简介

loglogruszapzerologzapzerolog

快速使用

先安装:

$ go get github.com/rs/zerolog/log

后使用:

package main

import "github.com/rs/zerolog/log"

func main() {
  log.Print("hello world")
}
log
{"level":"debug","time":"2020-04-25T13:43:08+08:00","message":"hello world"}

字段

zapzerologzerolog
func main() {
  log.Debug().
    Str("Scale", "833 cents").
    Float64("Interval", 833.09).
    Msg("Fibonacci is everywhere")

  log.Debug().
    Str("Name", "Tom").
    Send()
}
Msg()Send()
{"level":"debug","Scale":"833 cents","Interval":833.09,"time":"2020-04-25T13:55:44+08:00","message":"Fibonacci is everywhere"}
{"level":"debug","Name":"Tom","time":"2020-04-25T13:55:44+08:00"}

嵌套

Dict()
func main() {
  log.Info().
    Dict("dict", zerolog.Dict().
      Str("bar", "baz").
      Int("n", 1),
    ).Msg("hello world")
}
dict
{"level":"info","dict":{"bar":"baz","n":1},"time":"2020-04-25T14:34:51+08:00","message":"hello world"}
Logger
log.Debug()log.Info()LoggerLogger

设置日志级别

zerologpanic/fatal/error/warn/info/debug/traceSetGlobalLevel()Logger
func main() {
  debug := flag.Bool("debug", false, "sets log level to debug")
  flag.Parse()

  if *debug {
    zerolog.SetGlobalLevel(zerolog.DebugLevel)
  } else {
    zerolog.SetGlobalLevel(zerolog.InfoLevel)
  }

  log.Debug().Msg("This message appears only when log level set to debug")
  log.Info().Msg("This message appears when log level set to debug or info")

  if e := log.Debug(); e.Enabled() {
    e.Str("foo", "bar").Msg("some debug message")
  }
}
DebugInfoInfoDebugEnabled()
if e := log.Debug(); e.Enabled() {
  e.Str("foo", "bar").Msg("some debug message")
}
InfoDebug
$ go run main.go
{"level":"info","time":"2020-04-25T14:13:34+08:00","message":"This message appears when log level set to debug or info"}
-debugDebugInfo
$ go run main.go -debug
{"level":"debug","time":"2020-04-25T14:18:19+08:00","message":"This message appears only when log level set to debug"}
{"level":"info","time":"2020-04-25T14:18:19+08:00","message":"This message appears when log level set to debug or info"}
{"level":"debug","foo":"bar","time":"2020-04-25T14:18:19+08:00","message":"some debug 
message"}

不输出级别和信息

levellog.Log()Msg()
func main() {
  log.Log().
    Str("foo", "bar").
    Msg("")
}

运行:

{"foo":"bar","time":"2020-04-25T14:19:48+08:00"}
Logger
LoggerLogger
func main() {
  logger := zerolog.New(os.Stderr)
  logger.Info().Str("foo", "bar").Msg("hello world")
}
zerlog.New()io.Writer
Logger
LoggerLoggerLoggerLoggerlogger.With()Logger()Logger
func main() {
  logger := zerolog.New(os.Stderr)
  sublogger := logger.With().
    Str("foo", "bar").
    Logger()
  sublogger.Info().Msg("hello world")
}
sublogger"foo": "bar"

设置

zerolog

美化输出

zerologConsoleWriterzerolog.Output()ConsoleWriter
func main() {
  logger := log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
  logger.Info().Str("foo", "bar").Msg("hello world")
}

输出:

ConsoleWriter
func main() {
  output := zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}
  output.FormatLevel = func(i interface{}) string {
    return strings.ToUpper(fmt.Sprintf("| %-6s|", i))
  }
  output.FormatMessage = func(i interface{}) string {
    return fmt.Sprintf("***%s****", i)
  }
  output.FormatFieldName = func(i interface{}) string {
    return fmt.Sprintf("%s:", i)
  }
  output.FormatFieldValue = func(i interface{}) string {
    return strings.ToUpper(fmt.Sprintf("%s", i))
  }

  logger := log.Output(output).With().Timestamp().Logger()
  logger.Info().Str("foo", "bar").Msg("hello world")
}

实际上就是对级别、信息、字段名和字段值设置钩子,输出前经过钩子函数转换一次:

ConsoleWriter

设置自动添加的字段名

levelmessagetimezerologLevelFieldName/MessageFieldName/TimestampFieldName
func main() {
  zerolog.TimestampFieldName = "t"
  zerolog.LevelFieldName = "l"
  zerolog.MessageFieldName = "m"

  logger := zerolog.New(os.Stderr).With().Timestamp().Logger()
  logger.Info().Msg("hello world")
}

输出:

{"l":"info","t":"2020-04-25T14:53:08+08:00","m":"hello world"}

注意,这个设置是全局的!!!

输出文件名和行号

LoggerCaller()
func main() {
  logger := zerolog.New(os.Stderr).With().Caller().Logger()
  logger.Info().Msg("hello world")
}

输出:

{"level":"info","caller":"d:/code/golang/src/github.com/darjun/go-daily-lib/zerolog/setting/file-line/main.go:11","message":"hello world"}

日志采样

zerolog
func main() {
  sampled := log.Sample(&zerolog.BasicSampler{N: 10})

  for i := 0; i < 20; i++ {
    sampled.Info().Msg("will be logged every 10 message")
  }
}

结果只输出两条:

{"level":"info","time":"2020-04-25T15:01:02+08:00","message":"will be logged every 10 message"}
{"level":"info","time":"2020-04-25T15:01:02+08:00","message":"will be logged every 10 message"}

还有更高级的设置:

func main() {
  sampled := log.Sample(&zerolog.LevelSampler{
    DebugSampler: &zerolog.BurstSampler{
      Burst:       5,
      Period:      time.Second,
      NextSampler: &zerolog.BasicSampler{N: 100},
    },
  })

  sampled.Debug().Msg("hello world")
}
Debug

钩子

zerolog
type AddFieldHook struct {
}

func (AddFieldHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
  if level == zerolog.DebugLevel {
    e.Str("name", "dj")
  }
}

func main() {
  hooked := log.Hook(AddFieldHook{})
  hooked.Debug().Msg("")
}
Debug"name":"dj"
{"level":"debug","time":"2020-04-25T15:09:04+08:00","name":"dj"}

性能

logrus/zapzerologzap

总结

正是因为有很多人不满足于现状,才带来了技术的进步和丰富多彩的开源世界!

大家如果发现好玩、好用的 Go 语言库,欢迎到 Go 每日一库 GitHub 上提交 issue?

参考

  1. zerolog GitHub:https://github.com/rs/zerolog
  2. Go 每日一库 GitHub:https://github.com/darjun/go-daily-lib