grpc.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package logger
  2. import (
  3. "context"
  4. "log/slog"
  5. "time"
  6. )
  7. import (
  8. "google.golang.org/grpc"
  9. "google.golang.org/grpc/codes"
  10. "google.golang.org/grpc/status"
  11. )
  12. func GRPCLoggerClientInterceptor(logger *slog.Logger) grpc.UnaryClientInterceptor {
  13. return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
  14. start := time.Now()
  15. logger.Info("request",
  16. slog.String("method", method),
  17. slog.Any("payload", req),
  18. )
  19. err := invoker(ctx, method, req, reply, cc, opts...)
  20. duration := time.Since(start)
  21. if err != nil {
  22. logger.Error("response",
  23. slog.String("method", method),
  24. slog.Duration("duration", duration),
  25. slog.String("error", err.Error()),
  26. )
  27. } else {
  28. logger.Info("response",
  29. slog.String("method", method),
  30. slog.Duration("duration", duration),
  31. slog.Any("reply", reply),
  32. )
  33. }
  34. return err
  35. }
  36. }
  37. func GRPCLoggerServerInterceptor(logger *slog.Logger) grpc.UnaryServerInterceptor {
  38. return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
  39. start := time.Now()
  40. method := info.FullMethod
  41. // 在请求处理前记录
  42. logger.Info("request",
  43. slog.String("method", method),
  44. slog.Any("payload", req),
  45. )
  46. // 调用实际的服务方法
  47. resp, err = handler(ctx, req)
  48. // 在请求处理后记录
  49. duration := time.Since(start)
  50. statusCode := codes.OK // 默认成功
  51. if err != nil {
  52. s, ok := status.FromError(err)
  53. if ok {
  54. statusCode = s.Code() // 从 gRPC 错误中获取状态码
  55. } else {
  56. statusCode = codes.Unknown // 非 gRPC 错误则视为未知
  57. }
  58. }
  59. if err != nil {
  60. logger.Error("response",
  61. slog.String("method", method),
  62. slog.Duration("duration", duration),
  63. slog.String("status_code", statusCode.String()),
  64. slog.String("error", err.Error()),
  65. )
  66. } else {
  67. logger.Info("response",
  68. slog.String("method", method),
  69. slog.Duration("duration", duration),
  70. slog.Any("reply", resp),
  71. )
  72. }
  73. return resp, err
  74. }
  75. }