go-logr 和 uber 的 zap 冗长级别之间的对应关系是什么?

What is the correspondence between go-logr and uber's zap verbosity levels?

我看到 Uber Zap 实现中有日志级别:

    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
        ) 

我在 sigs.k8s.io/controller-runtime/pkg/log/zap 记录器中设置级别时使用它,它在后台使用 go-logr

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:         ...,
}

但也有使用 logr.Logger.V 的选项。

这里的level值和Uber Zap的常量一样吗? ( DebugLevel, InfoLevel, WarnLevel, ....)

我也看到了这个:

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”

此标志值是否与 sigs.k8s.iozap.Options 中的 zapcore.Level 相同?

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

go-logrgo.uber.org/zap日志级别的对应关系为:

zapLevel = -1 * logrLevel

也就是说,go-logr层是zap层的。此信息可在 go-logr/zapr 包文档中找到:

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.

您还可以通过查看 zapr 包的 logr.Logger.V 的实现来查看关卡如何初始化的具体示例:

func (zl *zapLogger) V(level int) logr.Logger {
    return &zapLogger{
        lvl: zl.lvl - zapcore.Level(level),
        l:   zl.l,
    }
}

方法zapr.NewLogger构造了一个zapr.zapLoggerlvl字段设置为zap.InfoLevel(你知道是0),所以每次调用V 在这个实现中,它减去给定的 int 值,从而得到它的负值。


标志 --zap-log-level 从命令行(或 k8s yaml 配置)传递的字符串值映射到 Uber Zap 的级别,基于此:

var levelStrings = map[string]zapcore.Level{
    "debug": zap.DebugLevel,
    "info":  zap.InfoLevel,
    "error": zap.ErrorLevel,
}

然后将数值乘以 -1,然后设置为 logr.Logger 实现,如上面引用的文档所要求的那样。