...

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

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

     1  package ctxzap
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/grpc-ecosystem/go-grpc-middleware/tags"
     7  	"go.uber.org/zap"
     8  	"go.uber.org/zap/zapcore"
     9  )
    10  
    11  type ctxMarker struct{}
    12  
    13  type ctxLogger struct {
    14  	logger *zap.Logger
    15  	fields []zapcore.Field
    16  }
    17  
    18  var (
    19  	ctxMarkerKey = &ctxMarker{}
    20  	nullLogger   = zap.NewNop()
    21  )
    22  
    23  // AddFields adds zap fields to the logger.
    24  func AddFields(ctx context.Context, fields ...zapcore.Field) {
    25  	l, ok := ctx.Value(ctxMarkerKey).(*ctxLogger)
    26  	if !ok || l == nil {
    27  		return
    28  	}
    29  	l.fields = append(l.fields, fields...)
    30  }
    31  
    32  // Extract takes the call-scoped Logger from grpc_zap middleware.
    33  //
    34  // It always returns a Logger that has all the grpc_ctxtags updated.
    35  func Extract(ctx context.Context) *zap.Logger {
    36  	l, ok := ctx.Value(ctxMarkerKey).(*ctxLogger)
    37  	if !ok || l == nil {
    38  		return nullLogger
    39  	}
    40  	// Add grpc_ctxtags tags metadata until now.
    41  	fields := TagsToFields(ctx)
    42  	// Add zap fields added until now.
    43  	fields = append(fields, l.fields...)
    44  	return l.logger.With(fields...)
    45  }
    46  
    47  // TagsToFields transforms the Tags on the supplied context into zap fields.
    48  func TagsToFields(ctx context.Context) []zapcore.Field {
    49  	fields := []zapcore.Field{}
    50  	tags := grpc_ctxtags.Extract(ctx)
    51  	for k, v := range tags.Values() {
    52  		fields = append(fields, zap.Any(k, v))
    53  	}
    54  	return fields
    55  }
    56  
    57  // ToContext adds the zap.Logger to the context for extraction later.
    58  // Returning the new context that has been created.
    59  func ToContext(ctx context.Context, logger *zap.Logger) context.Context {
    60  	l := &ctxLogger{
    61  		logger: logger,
    62  	}
    63  	return context.WithValue(ctx, ctxMarkerKey, l)
    64  }
    65  
    66  // Debug is equivalent to calling Debug on the zap.Logger in the context.
    67  // It is a no-op if the context does not contain a zap.Logger.
    68  func Debug(ctx context.Context, msg string, fields ...zap.Field) {
    69  	Extract(ctx).WithOptions(zap.AddCallerSkip(1)).Debug(msg, fields...)
    70  }
    71  
    72  // Info is equivalent to calling Info on the zap.Logger in the context.
    73  // It is a no-op if the context does not contain a zap.Logger.
    74  func Info(ctx context.Context, msg string, fields ...zap.Field) {
    75  	Extract(ctx).WithOptions(zap.AddCallerSkip(1)).Info(msg, fields...)
    76  }
    77  
    78  // Warn is equivalent to calling Warn on the zap.Logger in the context.
    79  // It is a no-op if the context does not contain a zap.Logger.
    80  func Warn(ctx context.Context, msg string, fields ...zap.Field) {
    81  	Extract(ctx).WithOptions(zap.AddCallerSkip(1)).Warn(msg, fields...)
    82  }
    83  
    84  // Error is equivalent to calling Error on the zap.Logger in the context.
    85  // It is a no-op if the context does not contain a zap.Logger.
    86  func Error(ctx context.Context, msg string, fields ...zap.Field) {
    87  	Extract(ctx).WithOptions(zap.AddCallerSkip(1)).Error(msg, fields...)
    88  }
    89  

View as plain text