import "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
grpc_zap
is a gRPC logging middleware backed by ZAP loggers
It accepts a user-configured zap.Logger
that will be used for logging completed gRPC calls. The same zap.Logger
will
be used for logging completed gRPC calls, and be populated into the context.Context
passed into gRPC handler code.
You can use Extract
to log into a request-scoped zap.Logger
instance in your handler code. The fields set on the
logger correspond to the grpc_ctxtags.Tags attached to the context.
This package also implements request and response payload logging, both for server-side and client-side. These will be
logged as structured jsonbp
fields for every message received/sent (both unary and streaming). For that please use
Payload*Interceptor
functions for that. Please note that the user-provided function that determines whetether to log
the full request/response payload needs to be written with care, this can significantly slow down gRPC.
ZAP can also be made as a backend for gRPC library internals. For that use ReplaceGrpcLogger
.
Please see examples and tests for examples of use.
Click to expand code.
x := func(ctx context.Context, ping *pb_testproto.PingRequest) (*pb_testproto.PingResponse, error) {
// Add fields the ctxtags of the request which will be added to all extracted loggers.
grpc_ctxtags.Extract(ctx).Set("custom_tags.string", "something").Set("custom_tags.int", 1337)
// Extract a request-scoped zap.Logger and log a message.
grpc_zap.Extract(ctx).Info("some ping")
return &pb_testproto.PingResponse{Value: ping.Value}, nil
}
return x
Click to expand code.
// Shared options for the logger, with a custom gRPC code to log level function.
opts := []grpc_zap.Option{
grpc_zap.WithLevels(customFunc),
}
// Make sure that log statements internal to gRPC library are logged using the zapLogger as well.
grpc_zap.ReplaceGrpcLogger(zapLogger)
// Create a server, make sure we put the grpc_ctxtags context before everything else.
server := grpc.NewServer(
grpc_middleware.WithUnaryServerChain(
grpc_ctxtags.UnaryServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)),
grpc_zap.UnaryServerInterceptor(zapLogger, opts...),
),
grpc_middleware.WithStreamServerChain(
grpc_ctxtags.StreamServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)),
grpc_zap.StreamServerInterceptor(zapLogger, opts...),
),
)
return server
Click to expand code.
opts := []grpc_zap.Option{
grpc_zap.WithDurationField(func(duration time.Duration) zapcore.Field {
return zap.Int64("grpc.time_ns", duration.Nanoseconds())
}),
}
server := grpc.NewServer(
grpc_middleware.WithUnaryServerChain(
grpc_ctxtags.UnaryServerInterceptor(),
grpc_zap.UnaryServerInterceptor(zapLogger, opts...),
),
grpc_middleware.WithStreamServerChain(
grpc_ctxtags.StreamServerInterceptor(),
grpc_zap.StreamServerInterceptor(zapLogger, opts...),
),
)
return server
- github.com/golang/protobuf/jsonpb
- github.com/golang/protobuf/proto
- github.com/grpc-ecosystem/go-grpc-middleware
- github.com/grpc-ecosystem/go-grpc-middleware/logging
- github.com/grpc-ecosystem/go-grpc-middleware/tags
- go.uber.org/zap
- go.uber.org/zap/zapcore
- golang.org/x/net/context
- google.golang.org/grpc
- google.golang.org/grpc/codes
- google.golang.org/grpc/grpclog
- Variables
- func DefaultClientCodeToLevel(code codes.Code) zapcore.Level
- func DefaultCodeToLevel(code codes.Code) zapcore.Level
- func DurationToDurationField(duration time.Duration) zapcore.Field
- func DurationToTimeMillisField(duration time.Duration) zapcore.Field
- func Extract(ctx context.Context) *zap.Logger
- func PayloadStreamClientInterceptor(logger *zap.Logger, decider grpc_logging.ClientPayloadLoggingDecider) grpc.StreamClientInterceptor
- func PayloadStreamServerInterceptor(logger *zap.Logger, decider grpc_logging.ServerPayloadLoggingDecider) grpc.StreamServerInterceptor
- func PayloadUnaryClientInterceptor(logger *zap.Logger, decider grpc_logging.ClientPayloadLoggingDecider) grpc.UnaryClientInterceptor
- func PayloadUnaryServerInterceptor(logger *zap.Logger, decider grpc_logging.ServerPayloadLoggingDecider) grpc.UnaryServerInterceptor
- func ReplaceGrpcLogger(logger *zap.Logger)
- func StreamClientInterceptor(logger *zap.Logger, opts ...Option) grpc.StreamClientInterceptor
- func StreamServerInterceptor(logger *zap.Logger, opts ...Option) grpc.StreamServerInterceptor
- func UnaryClientInterceptor(logger *zap.Logger, opts ...Option) grpc.UnaryClientInterceptor
- func UnaryServerInterceptor(logger *zap.Logger, opts ...Option) grpc.UnaryServerInterceptor
- type CodeToLevel
- type DurationToField
- type Option
- Package (HandlerUsageUnaryPing)
- Package (Initialization)
- Package (InitializationWithDurationFieldOverride)
client_interceptors.go context.go doc.go grpclogger.go options.go payload_interceptors.go server_interceptors.go
var (
// SystemField is used in every log statement made through grpc_zap. Can be overwritten before any initialization code.
SystemField = zap.String("system", "grpc")
// ServerField is used in every server-side log statment made through grpc_zap.Can be overwritten before initialization.
ServerField = zap.String("span.kind", "server")
)
var (
// ClientField is used in every client-side log statement made through grpc_zap. Can be overwritten before initialization.
ClientField = zap.String("span.kind", "client")
)
var DefaultDurationToField = DurationToTimeMillisField
DefaultDurationToField is the default implementation of converting request duration to a Zap field.
var (
// JsonPBMarshaller is the marshaller used for serializing protobuf messages.
JsonPbMarshaller = &jsonpb.Marshaler{}
)
func DefaultClientCodeToLevel(code codes.Code) zapcore.Level
DefaultClientCodeToLevel is the default implementation of gRPC return codes to log levels for client side.
func DefaultCodeToLevel(code codes.Code) zapcore.Level
DefaultCodeToLevel is the default implementation of gRPC return codes and interceptor log level for server side.
func DurationToDurationField(duration time.Duration) zapcore.Field
DurationToDurationField uses a Duration field to log the request duration and leaves it up to Zap's encoder settings to determine how that is output.
func DurationToTimeMillisField(duration time.Duration) zapcore.Field
DurationToTimeMillisField converts the duration to milliseconds and uses the key grpc.time_ms
.
func Extract(ctx context.Context) *zap.Logger
Extract takes the call-scoped Logger from grpc_zap middleware.
It always returns a Logger that has all the grpc_ctxtags updated.
func PayloadStreamClientInterceptor(logger *zap.Logger, decider grpc_logging.ClientPayloadLoggingDecider) grpc.StreamClientInterceptor
PayloadStreamServerInterceptor returns a new streaming client interceptor that logs the paylods of requests and responses.
func PayloadStreamServerInterceptor(logger *zap.Logger, decider grpc_logging.ServerPayloadLoggingDecider) grpc.StreamServerInterceptor
PayloadUnaryServerInterceptor returns a new server server interceptors that logs the payloads of requests.
This only works when placed after the grpc_logrus.StreamServerInterceptor
. However, the logging can be done to a
separate instance of the logger.
func PayloadUnaryClientInterceptor(logger *zap.Logger, decider grpc_logging.ClientPayloadLoggingDecider) grpc.UnaryClientInterceptor
PayloadUnaryClientInterceptor returns a new unary client interceptor that logs the paylods of requests and responses.
func PayloadUnaryServerInterceptor(logger *zap.Logger, decider grpc_logging.ServerPayloadLoggingDecider) grpc.UnaryServerInterceptor
PayloadUnaryServerInterceptor returns a new unary server interceptors that logs the payloads of requests.
This only works when placed after the grpc_logrus.UnaryServerInterceptor
. However, the logging can be done to a
separate instance of the logger.
func ReplaceGrpcLogger(logger *zap.Logger)
ReplaceGrpcLogger sets the given zap.Logger as a gRPC-level logger. This should be called before any other initialization, preferably from init() functions.
func StreamClientInterceptor(logger *zap.Logger, opts ...Option) grpc.StreamClientInterceptor
StreamServerInterceptor returns a new streaming client interceptor that optionally logs the execution of external gRPC calls.
func StreamServerInterceptor(logger *zap.Logger, opts ...Option) grpc.StreamServerInterceptor
StreamServerInterceptor returns a new streaming server interceptor that adds zap.Logger to the context.
func UnaryClientInterceptor(logger *zap.Logger, opts ...Option) grpc.UnaryClientInterceptor
UnaryClientInterceptor returns a new unary client interceptor that optionally logs the execution of external gRPC calls.
func UnaryServerInterceptor(logger *zap.Logger, opts ...Option) grpc.UnaryServerInterceptor
UnaryServerInterceptor returns a new unary server interceptors that adds zap.Logger to the context.
type CodeToLevel func(code codes.Code) zapcore.Level
CodeToLevel function defines the mapping between gRPC return codes and interceptor log level.
type DurationToField func(duration time.Duration) zapcore.Field
DurationToField function defines how to produce duration fields for logging
type Option func(*options)
func WithCodes(f grpc_logging.ErrorToCode) Option
WithCodes customizes the function for mapping errors to error codes.
func WithDurationField(f DurationToField) Option
WithDurationField customizes the function for mapping request durations to Zap fields.
func WithLevels(f CodeToLevel) Option
WithLevels customizes the function for mapping gRPC return codes and interceptor log level statements.
Generated by godoc2ghmd