乐趣区

关于golang:聊聊golang的zap的level

本文次要钻研一下 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

  • zap
退出移动版