// Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0. package logutil import ( "context" "github.com/pingcap/log" "go.uber.org/zap" ) // We cannot directly set global logger as log.L(), // or when the global logger updated, we cannot get the latest logger. var globalLogger *zap.Logger = nil // ResetGlobalLogger resets the global logger. // Contexts have already made by `ContextWithField` would keep untouched, // subsequent wrapping over those contexts would keep using the old global logger, // only brand new contexts (i.e. context without logger) would be wrapped with the new global logger. // This method is mainly for testing. func ResetGlobalLogger(l *zap.Logger) { globalLogger = l } type loggingContextKey struct{} var keyLogger loggingContextKey = loggingContextKey{} // ContextWithField wrap a context with a logger with some fields. func ContextWithField(c context.Context, fields ...zap.Field) context.Context { logger := LoggerFromContext(c).With(fields...) return context.WithValue(c, keyLogger, logger) } // LoggerFromContext returns the contextual logger via the context. // If there isn't a logger in the context, returns the global logger. func LoggerFromContext(c context.Context) *zap.Logger { logger, ok := c.Value(keyLogger).(*zap.Logger) if !ok { if globalLogger != nil { return globalLogger } return log.L() } return logger } // CL is the shorthand for LoggerFromContext. func CL(c context.Context) *zap.Logger { return LoggerFromContext(c) }