package server import ( "context" "fmt" "time" "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/peer" "google.golang.org/grpc/status" ) func LogInterceptor(logger *zap.Logger) grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { start := time.Now() // Call the handler to execute the gRPC request response, err := handler(ctx, req) duration := time.Since(start).Milliseconds() fields := []zap.Field{ zap.Int64("duration_ms", duration), zap.String("method", info.FullMethod), zap.Any("request", req), } // Get the remote address from the context peer, ok := peer.FromContext(ctx) if ok { fields = append(fields, zap.String("remote_addr", peer.Addr.String())) } if err != nil { fields = append(fields, zap.Int32("status_code", int32(status.Code(err)))) } message := "request completed" if err != nil { message = fmt.Sprintf("request failed. %s", err.Error()) } logRequest(logger, fields, int(status.Code(err)), message) return response, err } } func logRequest(logger *zap.Logger, fields []zap.Field, statusCode int, message string) { if statusCode >= 400 { logger.Error(message, fields...) } else { logger.Info(message, fields...) } }