| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 | package loggingimport (	"context"	"encoding/json"	"fmt"	"time"	"git.ikuban.com/server/kratos-utils/v2/codes"	"github.com/go-kratos/kratos/v2/errors"	"github.com/go-kratos/kratos/v2/log"	"github.com/go-kratos/kratos/v2/middleware"	"github.com/go-kratos/kratos/v2/transport")// Server is an server logging middleware.func Server(logger log.Logger) middleware.Middleware {	return func(handler middleware.Handler) middleware.Handler {		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {			var (				code      int32				reason    string				kind      string				operation string			)			startTime := time.Now()			if info, ok := transport.FromServerContext(ctx); ok {				kind = info.Kind().String()				operation = info.Operation()			}			reply, err = handler(ctx, req)			if se := errors.FromError(err); se != nil {				code = se.Code				reason = se.Reason			}			if code == 0 {				return			}			level, stack := extractError(err)			log.WithContext(ctx, logger).Log(level,				"kind", "server",				"component", kind,				"operation", operation,				"args", extractArgs(req),				"code", code,				"reason", reason,				"stack", stack,				"latency", time.Since(startTime).Seconds(),			)			return		}	}}// Client is an client logging middleware.func Client(logger log.Logger) middleware.Middleware {	return func(handler middleware.Handler) middleware.Handler {		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {			var (				code      int32				reason    string				kind      string				operation string			)			startTime := time.Now()			if info, ok := transport.FromClientContext(ctx); ok {				kind = info.Kind().String()				operation = info.Operation()			}			reply, err = handler(ctx, req)			if se := errors.FromError(err); se != nil {				code = se.Code				reason = se.Reason			}			if code == 0 {				return			}			level, stack := extractError(err)			log.WithContext(ctx, logger).Log(level,				"component", kind,				"operation", operation,				"args", extractArgs(req),				"code", code,				"reason", reason,				"stack", stack,				"latency", time.Since(startTime).Seconds(),			)			return		}	}}// extractArgs returns the string of the reqfunc extractArgs(req interface{}) string {	if stringer, ok := req.(fmt.Stringer); ok {		return stringer.String()	}	j, err := json.Marshal(req)	if err != nil {		return fmt.Sprintf("%+v", req)	}	return string(j)}// extractError returns the string of the errorfunc extractError(err error) (log.Level, string) {	if err != nil {		return log.LevelError, fmt.Sprintf("%+v", codes.ParseErrorMsg(err))	}	return log.LevelInfo, ""}
 |