...

Source file src/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/server_interceptors.go

Documentation: github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus

     1  // Copyright (c) Improbable Worlds Ltd, All Rights Reserved
     2  
     3  package grpc_logrus
     4  
     5  import (
     6  	"context"
     7  	"path"
     8  	"time"
     9  
    10  	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
    11  	"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
    12  	"github.com/sirupsen/logrus"
    13  	"google.golang.org/grpc"
    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 field used to indicate whether this is a server or a client log statement.
    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, o.timestampFormat)
    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  		o.messageFunc(newCtx, "finished unary call with code "+code.String(), level, code, err, fields)
    48  		return resp, err
    49  	}
    50  }
    51  
    52  // StreamServerInterceptor returns a new streaming server interceptor that adds logrus.Entry to the context.
    53  func StreamServerInterceptor(entry *logrus.Entry, opts ...Option) grpc.StreamServerInterceptor {
    54  	o := evaluateServerOpt(opts)
    55  	return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
    56  		startTime := time.Now()
    57  		newCtx := newLoggerForCall(stream.Context(), entry, info.FullMethod, startTime, o.timestampFormat)
    58  		wrapped := grpc_middleware.WrapServerStream(stream)
    59  		wrapped.WrappedContext = newCtx
    60  
    61  		err := handler(srv, wrapped)
    62  
    63  		if !o.shouldLog(info.FullMethod, err) {
    64  			return err
    65  		}
    66  		code := o.codeFunc(err)
    67  		level := o.levelFunc(code)
    68  		durField, durVal := o.durationFunc(time.Since(startTime))
    69  		fields := logrus.Fields{
    70  			"grpc.code": code.String(),
    71  			durField:    durVal,
    72  		}
    73  
    74  		o.messageFunc(newCtx, "finished streaming call with code "+code.String(), level, code, err, fields)
    75  		return err
    76  	}
    77  }
    78  
    79  func newLoggerForCall(ctx context.Context, entry *logrus.Entry, fullMethodString string, start time.Time, timestampFormat string) context.Context {
    80  	service := path.Dir(fullMethodString)[1:]
    81  	method := path.Base(fullMethodString)
    82  	callLog := entry.WithFields(
    83  		logrus.Fields{
    84  			SystemField:       "grpc",
    85  			KindField:         "server",
    86  			"grpc.service":    service,
    87  			"grpc.method":     method,
    88  			"grpc.start_time": start.Format(timestampFormat),
    89  		})
    90  
    91  	if d, ok := ctx.Deadline(); ok {
    92  		callLog = callLog.WithFields(
    93  			logrus.Fields{
    94  				"grpc.request.deadline": d.Format(timestampFormat),
    95  			})
    96  	}
    97  
    98  	callLog = callLog.WithFields(ctxlogrus.Extract(ctx).Data)
    99  	return ctxlogrus.ToContext(ctx, callLog)
   100  }
   101  

View as plain text