gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/go-grpc-middleware/logging/logrus/server_interceptors.go (about) 1 // Copyright (c) Improbable Worlds Ltd, All Rights Reserved 2 3 package grpc_logrus 4 5 import ( 6 "path" 7 "time" 8 9 grpcmiddleware "gitee.com/ks-custle/core-gm/go-grpc-middleware" 10 "gitee.com/ks-custle/core-gm/go-grpc-middleware/logging/logrus/ctxlogrus" 11 "gitee.com/ks-custle/core-gm/grpc" 12 "gitee.com/ks-custle/core-gm/net/context" 13 "github.com/sirupsen/logrus" 14 ) 15 16 var ( 17 // SystemField is used in every log statement made through grpc_logrus. Can be overwritten before any initialization code. 18 SystemField = "system" 19 20 // KindField describes the log gield used to incicate whether this is a server or a client log statment. 21 KindField = "span.kind" 22 ) 23 24 // UnaryServerInterceptor returns a new unary server interceptors that adds logrus.Entry to the context. 25 func UnaryServerInterceptor(entry *logrus.Entry, opts ...Option) grpc.UnaryServerInterceptor { 26 o := evaluateServerOpt(opts) 27 return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { 28 startTime := time.Now() 29 newCtx := newLoggerForCall(ctx, entry, info.FullMethod, startTime) 30 31 resp, err := handler(newCtx, req) 32 33 if !o.shouldLog(info.FullMethod, err) { 34 return resp, err 35 } 36 code := o.codeFunc(err) 37 level := o.levelFunc(code) 38 durField, durVal := o.durationFunc(time.Since(startTime)) 39 fields := logrus.Fields{ 40 "grpc.code": code.String(), 41 durField: durVal, 42 } 43 if err != nil { 44 fields[logrus.ErrorKey] = err 45 } 46 47 levelLogf( 48 // re-extract logger from newCtx, as it may have extra fields that changed in the holder. 49 // ctx_logrus.Extract is deprecated, use ctxlogrus.Extract instead. 50 //ctx_logrus.Extract(newCtx).WithFields(fields), 51 ctxlogrus.Extract(newCtx).WithFields(fields), 52 level, 53 "finished unary call with code "+code.String()) 54 55 return resp, err 56 } 57 } 58 59 // StreamServerInterceptor returns a new streaming server interceptor that adds logrus.Entry to the context. 60 func StreamServerInterceptor(entry *logrus.Entry, opts ...Option) grpc.StreamServerInterceptor { 61 o := evaluateServerOpt(opts) 62 return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { 63 startTime := time.Now() 64 newCtx := newLoggerForCall(stream.Context(), entry, info.FullMethod, startTime) 65 wrapped := grpcmiddleware.WrapServerStream(stream) 66 wrapped.WrappedContext = newCtx 67 68 err := handler(srv, wrapped) 69 70 if !o.shouldLog(info.FullMethod, err) { 71 return err 72 } 73 code := o.codeFunc(err) 74 level := o.levelFunc(code) 75 durField, durVal := o.durationFunc(time.Since(startTime)) 76 fields := logrus.Fields{ 77 "grpc.code": code.String(), 78 durField: durVal, 79 } 80 if err != nil { 81 fields[logrus.ErrorKey] = err 82 } 83 84 levelLogf( 85 // re-extract logger from newCtx, as it may have extra fields that changed in the holder. 86 // ctx_logrus.Extract is deprecated, use ctxlogrus.Extract instead. 87 //ctx_logrus.Extract(newCtx).WithFields(fields), 88 ctxlogrus.Extract(newCtx).WithFields(fields), 89 level, 90 "finished streaming call with code "+code.String()) 91 92 return err 93 } 94 } 95 96 func levelLogf(entry *logrus.Entry, level logrus.Level, format string, args ...interface{}) { 97 switch level { 98 case logrus.DebugLevel: 99 entry.Debugf(format, args...) 100 case logrus.InfoLevel: 101 entry.Infof(format, args...) 102 case logrus.WarnLevel: 103 entry.Warningf(format, args...) 104 case logrus.ErrorLevel: 105 entry.Errorf(format, args...) 106 case logrus.FatalLevel: 107 entry.Fatalf(format, args...) 108 case logrus.PanicLevel: 109 entry.Panicf(format, args...) 110 } 111 } 112 113 func newLoggerForCall(ctx context.Context, entry *logrus.Entry, fullMethodString string, start time.Time) context.Context { 114 service := path.Dir(fullMethodString)[1:] 115 method := path.Base(fullMethodString) 116 callLog := entry.WithFields( 117 logrus.Fields{ 118 SystemField: "grpc", 119 KindField: "server", 120 "grpc.service": service, 121 "grpc.method": method, 122 "grpc.start_time": start.Format(time.RFC3339), 123 }) 124 125 if d, ok := ctx.Deadline(); ok { 126 callLog = callLog.WithFields( 127 logrus.Fields{ 128 "grpc.request.deadline": d.Format(time.RFC3339), 129 }) 130 } 131 132 // ctx_logrus.Extract is deprecated, use ctxlogrus.Extract instead. 133 //callLog = callLog.WithFields(ctx_logrus.Extract(ctx).Data) 134 callLog = callLog.WithFields(ctxlogrus.Extract(ctx).Data) 135 return ctxlogrus.ToContext(ctx, callLog) 136 }