You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.4 KiB
100 lines
2.4 KiB
package logging |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"time" |
|
|
|
"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 |
|
} |
|
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 |
|
} |
|
level, stack := extractError(err) |
|
_ = log.WithContext(ctx, logger).Log(level, |
|
"kind", "client", |
|
"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 req |
|
func extractArgs(req interface{}) string { |
|
if stringer, ok := req.(fmt.Stringer); ok { |
|
return stringer.String() |
|
} |
|
return fmt.Sprintf("%+v", req) |
|
} |
|
|
|
// extractError returns the string of the error |
|
func extractError(err error) (log.Level, string) { |
|
if err != nil { |
|
return log.LevelError, fmt.Sprintf("%+v", err) |
|
} |
|
return log.LevelInfo, "" |
|
}
|
|
|