I saw that there is log level in Uber Zap implementation:
const (
// DebugLevel logs are typically voluminous, and are usually disabled in
// production.
DebugLevel Level = iota - 1
// InfoLevel is the default logging priority.
InfoLevel
// WarnLevel logs are more important than Info, but don't need individual
// human review.
WarnLevel
// ErrorLevel logs are high-priority. If an application is running smoothly,
// it shouldn't generate any error-level logs.
ErrorLevel
// DPanicLevel logs are particularly important errors. In development the
// logger panics after writing the message.
DPanicLevel
// PanicLevel logs a message, then panics.
PanicLevel
// FatalLevel logs a message, then calls os.Exit(1).
FatalLevel
)
I use this when I set the level in a sigs.k8s.io/controller-runtime/pkg/log/zap
logger, which uses go-logr
under the hood:
func determineLogLevel(verbosityLevel string) zapcore.Level {
var zapLevel zapcore.Level
verbosityLevel = strings.ToLower(verbosityLevel)
switch verbosityLevel {
case ERROR:
zapLevel = zapcore.ErrorLevel
case WARNING:
zapLevel = zapcore.WarnLevel
case INFO:
zapLevel = zapcore.InfoLevel
case DEBUG:
zapLevel = zapcore.DebugLevel
default:
zapLevel = zapcore.InfoLevel
}
return zapLevel
}
// here zap is "sigs.k8s.io/controller-runtime/pkg/log/zap"
opts := zap.Options{
StacktraceLevel: ... ,
Level: determineLogLevel("ERROR"),
Encoder: ... ,
ZapOpts: ...,
}
But there is also the option of using logr.Logger.V
.
Is the level value here the same as in Uber Zap's constants? ( DebugLevel
, InfoLevel
, WarnLevel
, ....)
I also saw this:
flag --zap-log-level: Zap Level to configure the verbosity of logging. Can be one of ‘debug’, ‘info’, ‘error’, or any integer value > 0 which corresponds to custom debug levels of increasing verbosity”
Is this flag value the same as zapcore.Level
in the sigs.k8s.io
's zap.Options
?
The documentation for logr.Logger.V
// V returns an Logger value for a specific verbosity level, relative to
// this Logger. In other words, V values are additive. V higher verbosity
// level means a log message is less important. It's illegal to pass a log
// level less than zero.
V(level int) Logger
The correspondence between go-logr
and go.uber.org/zap
log levels is given by:
zapLevel = -1 * logrLevel
In other words, the go-logr
level is the inverse of zap
level. This information is available in go-logr/zapr
package docs:
Levels in logr correspond to custom debug levels in Zap. Any given level in logr is represents by its inverse in zap (
zapLevel = -1*logrLevel
). For example V(2) is equivalent to log level -2 in Zap, while V(1) is equivalent to Zap's DebugLevel.
You can also see a concrete example of how the level is initialized by looking at the implementation of logr.Logger.V
by zapr
package:
func (zl *zapLogger) V(level int) logr.Logger {
return &zapLogger{
lvl: zl.lvl - zapcore.Level(level),
l: zl.l,
}
}
The method zapr.NewLogger
constructs a zapr.zapLogger
with lvl
field set to zap.InfoLevel
(which you know is 0
), so each time you call V
on this implementation, it subtracts the given int value, thus obtaining its negative.
The flag --zap-log-level
is mapped from the string value passed on the command line (or k8s yaml config) to the Uber Zap's level as-is, based on this:
var levelStrings = map[string]zapcore.Level{
"debug": zap.DebugLevel,
"info": zap.InfoLevel,
"error": zap.ErrorLevel,
}
The numerical value is then multiplied by -1
and then set to the logr.Logger
implementation, as required by the documentation quoted above.