...

Source file src/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/client_interceptors.go

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

     1  // Copyright 2017 Michal Witkowski. All Rights Reserved.
     2  // See LICENSE for licensing terms.
     3  
     4  package grpc_zap
     5  
     6  import (
     7  	"context"
     8  	"path"
     9  	"time"
    10  
    11  	"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
    12  	"go.uber.org/zap"
    13  	"go.uber.org/zap/zapcore"
    14  	"google.golang.org/grpc"
    15  )
    16  
    17  var (
    18  	// ClientField is used in every client-side log statement made through grpc_zap. Can be overwritten before initialization.
    19  	ClientField = zap.String("span.kind", "client")
    20  )
    21  
    22  // UnaryClientInterceptor returns a new unary client interceptor that optionally logs the execution of external gRPC calls.
    23  func UnaryClientInterceptor(logger *zap.Logger, opts ...Option) grpc.UnaryClientInterceptor {
    24  	o := evaluateClientOpt(opts)
    25  	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
    26  		fields := newClientLoggerFields(ctx, method)
    27  		startTime := time.Now()
    28  		err := invoker(ctx, method, req, reply, cc, opts...)
    29  		newCtx := ctxzap.ToContext(ctx, logger.With(fields...))
    30  		logFinalClientLine(newCtx, o, startTime, err, "finished client unary call")
    31  		return err
    32  	}
    33  }
    34  
    35  // StreamClientInterceptor returns a new streaming client interceptor that optionally logs the execution of external gRPC calls.
    36  func StreamClientInterceptor(logger *zap.Logger, opts ...Option) grpc.StreamClientInterceptor {
    37  	o := evaluateClientOpt(opts)
    38  	return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
    39  		fields := newClientLoggerFields(ctx, method)
    40  		startTime := time.Now()
    41  		clientStream, err := streamer(ctx, desc, cc, method, opts...)
    42  		newCtx := ctxzap.ToContext(ctx, logger.With(fields...))
    43  		logFinalClientLine(newCtx, o, startTime, err, "finished client streaming call")
    44  		return clientStream, err
    45  	}
    46  }
    47  
    48  func logFinalClientLine(ctx context.Context, o *options, startTime time.Time, err error, msg string) {
    49  	code := o.codeFunc(err)
    50  	level := o.levelFunc(code)
    51  	duration := o.durationFunc(time.Now().Sub(startTime))
    52  	o.messageFunc(ctx, msg, level, code, err, duration)
    53  }
    54  
    55  func newClientLoggerFields(ctx context.Context, fullMethodString string) []zapcore.Field {
    56  	service := path.Dir(fullMethodString)[1:]
    57  	method := path.Base(fullMethodString)
    58  	return []zapcore.Field{
    59  		SystemField,
    60  		ClientField,
    61  		zap.String("grpc.service", service),
    62  		zap.String("grpc.method", method),
    63  	}
    64  }
    65  

View as plain text