Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gRPC Zap ReplaceGrpcLoggerV2 #221

Merged
2 changes: 1 addition & 1 deletion logging/zap/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ logged as structured `jsonpb` fields for every message received/sent (both unary
`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`.
ZAP can also be made as a backend for gRPC library internals. For that use `ReplaceGrpcLoggerV2`.


*Server Interceptor*
Expand Down
10 changes: 5 additions & 5 deletions logging/zap/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"context"
"time"

"github.com/grpc-ecosystem/go-grpc-middleware"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
"github.com/grpc-ecosystem/go-grpc-middleware/tags"
"github.com/grpc-ecosystem/go-grpc-middleware/tags/zap"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags"
ctx_zap "github.com/grpc-ecosystem/go-grpc-middleware/tags/zap"
devnev marked this conversation as resolved.
Show resolved Hide resolved
pb_testproto "github.com/grpc-ecosystem/go-grpc-middleware/testing/testproto"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
Expand All @@ -26,7 +26,7 @@ func Example_initialization() {
grpc_zap.WithLevels(customFunc),
}
// Make sure that log statements internal to gRPC library are logged using the zapLogger as well.
grpc_zap.ReplaceGrpcLogger(zapLogger)
grpc_zap.ReplaceGrpcLoggerV2(zapLogger)
// Create a server, make sure we put the grpc_ctxtags context before everything else.
_ = grpc.NewServer(
grpc_middleware.WithUnaryServerChain(
Expand Down
103 changes: 103 additions & 0 deletions logging/zap/grpclogger.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ package grpc_zap

import (
"fmt"
"os"
"strconv"

"go.uber.org/zap"
"google.golang.org/grpc/grpclog"
)

// ReplaceGrpcLogger sets the given zap.Logger as a gRPC-level logger.
// This should be called *before* any other initialization, preferably from init() functions.
// Deprecated: use ReplaceGrpcLoggerV2
func ReplaceGrpcLogger(logger *zap.Logger) {
zgl := &zapGrpcLogger{logger.With(SystemField, zap.Bool("grpc_log", true))}
grpclog.SetLogger(zgl)
Expand Down Expand Up @@ -44,3 +47,103 @@ func (l *zapGrpcLogger) Printf(format string, args ...interface{}) {
func (l *zapGrpcLogger) Println(args ...interface{}) {
l.logger.Info(fmt.Sprint(args...))
}

// ReplaceGrpcLoggerV2 replaces the grpc_log.LoggerV2 with the input zap.Logger
// This logger adheres to the grpc go environment variables GRPC_GO_LOG_VERBOSITY_LEVEL and GRPC_GO_LOG_SEVERITY_LEVEL.
kush-patel-hs marked this conversation as resolved.
Show resolved Hide resolved
func ReplaceGrpcLoggerV2(logger *zap.Logger) {
zgl := &zapGrpcLoggerV2{Logger: logger.With(SystemField, zap.Bool("grpc_log", true))}
kush-patel-hs marked this conversation as resolved.
Show resolved Hide resolved

verbosity := os.Getenv("GRPC_GO_LOG_VERBOSITY_LEVEL")
if v, err := strconv.Atoi(verbosity); err == nil {
zgl.verbosity = v
}

// We don't want to change the zap core of the input logger so we won't set logger level of input zap.Logger
logLevel := os.Getenv("GRPC_GO_LOG_SEVERITY_LEVEL")
switch logLevel {
case "", "ERROR", "error": // If env is unset, set level to ERROR.
zgl.severity = errorLevel
case "WARNING", "warning":
zgl.severity = warnLevel
case "INFO", "info":
zgl.severity = infoLevel
}

grpclog.SetLoggerV2(zgl)
}

const (
errorLevel = iota
warnLevel
infoLevel
)

type zapGrpcLoggerV2 struct {
*zap.Logger
verbosity int
severity int
}

func (l *zapGrpcLoggerV2) Info(args ...interface{}) {
if l.severity >= infoLevel {
l.Logger.Info(fmt.Sprint(args...))
}
}

func (l *zapGrpcLoggerV2) Infoln(args ...interface{}) {
if l.severity >= infoLevel {
l.Logger.Info(fmt.Sprint(args...))
}
}

func (l *zapGrpcLoggerV2) Infof(format string, args ...interface{}) {
if l.severity >= infoLevel {
l.Logger.Info(fmt.Sprintf(format, args...))
}
}

func (l *zapGrpcLoggerV2) Warning(args ...interface{}) {
if l.severity >= warnLevel {
l.Logger.Warn(fmt.Sprint(args...))
}
}

func (l *zapGrpcLoggerV2) Warningln(args ...interface{}) {
if l.severity >= warnLevel {
l.Logger.Warn(fmt.Sprint(args...))
}
}

func (l *zapGrpcLoggerV2) Warningf(format string, args ...interface{}) {
if l.severity >= warnLevel {
l.Logger.Warn(fmt.Sprintf(format, args...))
}
}

func (l *zapGrpcLoggerV2) Error(args ...interface{}) {
l.Logger.Error(fmt.Sprint(args...))
}

func (l *zapGrpcLoggerV2) Errorln(args ...interface{}) {
l.Logger.Error(fmt.Sprint(args...))
}

func (l *zapGrpcLoggerV2) Errorf(format string, args ...interface{}) {
l.Logger.Error(fmt.Sprintf(format, args...))
}

func (l *zapGrpcLoggerV2) Fatal(args ...interface{}) {
l.Logger.Fatal(fmt.Sprint(args...))
}

func (l *zapGrpcLoggerV2) Fatalln(args ...interface{}) {
l.Logger.Fatal(fmt.Sprint(args...))
}

func (l *zapGrpcLoggerV2) Fatalf(format string, args ...interface{}) {
l.Logger.Fatal(fmt.Sprintf(format, args...))
}

func (l *zapGrpcLoggerV2) V(level int) bool {
return level <= l.verbosity
}