1

本文主要研究一下golang的zap的level

Level

zap@v1.16.0/zapcore/level.go

// A Level is a logging priority. Higher levels are more important.
type Level int8

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

    _minLevel = DebugLevel
    _maxLevel = FatalLevel
)

func (l Level) String() string {
    switch l {
    case DebugLevel:
        return "debug"
    case InfoLevel:
        return "info"
    case WarnLevel:
        return "warn"
    case ErrorLevel:
        return "error"
    case DPanicLevel:
        return "dpanic"
    case PanicLevel:
        return "panic"
    case FatalLevel:
        return "fatal"
    default:
        return fmt.Sprintf("Level(%d)", l)
    }
}
Level为int8类型,其中DebugLevel值最小,FatalLevel值最大

LevelEnabler

zap@v1.16.0/zapcore/level.go

type LevelEnabler interface {
    Enabled(Level) bool
}

func (l Level) Enabled(lvl Level) bool {
    return lvl >= l
}
LevelEnabler接口定义了Enabled方法,Level的Enabled方法判断lvl是否大于等于l

levelToColor

zap@v1.16.0/zapcore/level_strings.go

import "go.uber.org/zap/internal/color"

var (
    _levelToColor = map[Level]color.Color{
        DebugLevel:  color.Magenta,
        InfoLevel:   color.Blue,
        WarnLevel:   color.Yellow,
        ErrorLevel:  color.Red,
        DPanicLevel: color.Red,
        PanicLevel:  color.Red,
        FatalLevel:  color.Red,
    }
    _unknownLevelColor = color.Red

    _levelToLowercaseColorString = make(map[Level]string, len(_levelToColor))
    _levelToCapitalColorString   = make(map[Level]string, len(_levelToColor))
)

func init() {
    for level, color := range _levelToColor {
        _levelToLowercaseColorString[level] = color.Add(level.String())
        _levelToCapitalColorString[level] = color.Add(level.CapitalString())
    }
}
level_strings定义了_levelToColor的映射,其中DebugLevel为color.Magenta,InfoLevel为color.Blue,WarnLevel为color.Yellow,其余的为color.Red

levelFilterCore

zap@v1.16.0/zapcore/increase_level.go

type levelFilterCore struct {
    core  Core
    level LevelEnabler
}

// NewIncreaseLevelCore creates a core that can be used to increase the level of
// an existing Core. It cannot be used to decrease the logging level, as it acts
// as a filter before calling the underlying core. If level decreases the log level,
// an error is returned.
func NewIncreaseLevelCore(core Core, level LevelEnabler) (Core, error) {
    for l := _maxLevel; l >= _minLevel; l-- {
        if !core.Enabled(l) && level.Enabled(l) {
            return nil, fmt.Errorf("invalid increase level, as level %q is allowed by increased level, but not by existing core", l)
        }
    }

    return &levelFilterCore{core, level}, nil
}

func (c *levelFilterCore) Enabled(lvl Level) bool {
    return c.level.Enabled(lvl)
}

func (c *levelFilterCore) With(fields []Field) Core {
    return &levelFilterCore{c.core.With(fields), c.level}
}

func (c *levelFilterCore) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
    if !c.Enabled(ent.Level) {
        return ce
    }

    return c.core.Check(ent, ce)
}

func (c *levelFilterCore) Write(ent Entry, fields []Field) error {
    return c.core.Write(ent, fields)
}

func (c *levelFilterCore) Sync() error {
    return c.core.Sync()
}
levelFilterCore定义了Core、LevelEnabler属性;其Check方法首先通过c.Enabled(ent.Level)判断entry的level是否大于等于core的level,如果满足条件才执行c.core.Check(ent, ce),否则直接返回

IncreaseLevel

zap@v1.16.0/options.go

func IncreaseLevel(lvl zapcore.LevelEnabler) Option {
    return optionFunc(func(log *Logger) {
        core, err := zapcore.NewIncreaseLevelCore(log.core, lvl)
        if err != nil {
            fmt.Fprintf(log.errorOutput, "failed to IncreaseLevel: %v\n", err)
        } else {
            log.core = core
        }
    })
}
IncreaseLevel会通过zapcore.NewIncreaseLevelCore创建一个新的core,它包装了原来的core,并设置了zapcore.LevelEnabler

实例

func levelDemo() {
    logger, err := zap.NewDevelopment()
    defer logger.Sync()
    if err != nil {
        panic(err)
    }

    infoLog := logger.WithOptions(zap.IncreaseLevel(zapcore.InfoLevel))
    logger.Debug("this is debug log")
    infoLog.Debug("this will be dropped")
}

输出

2020-12-21T22:44:12.385+0800    DEBUG   zap/zap_demo.go:29      this is debug log

小结

Level为int8类型,其中DebugLevel值最小,FatalLevel值最大;LevelEnabler接口定义了Enabled方法,Level的Enabled方法判断lvl是否大于等于l;levelFilterCore定义了Core、LevelEnabler属性;其Check方法首先通过c.Enabled(ent.Level)判断entry的level是否大于等于core的level,如果满足条件才执行c.core.Check(ent, ce),否则直接返回。

doc


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...