转载

go-logging

日志库考虑因素:

  • 级别: 最好是 always, err, warn, notice, info, debug, verbos 几个级别.

  • 性能: 如果设置级别低, 应该对程序性能没有任何影响.(不要先format)

  • 易用性:
    • 不需要显示初始化.

    • 打印代码行.

    • 可以动态设置日志级别

    • 如果支持rolling, rolling 需要提供小时级()
      • 不过自动rolling切日志都会降低性能.

因为标准库不支持日志级别, 所以造轮子的需求很强烈.

1   常见库

1.1   标准库

/usr/local/go/src/pkg/log/log.go

  • 没有级别:
  • 不需要初始化, 易用性ok

1.2   beego

~/go/src/github.com/astaxie/beego/logs http://beego.me/docs/module/logs.md

遵守 RFC5424 log message levels:

const (  LevelEmergency = iota  LevelAlert  LevelCritical  LevelError  LevelWarning  LevelNotice  LevelInformational  LevelDebug ) Numerical   Severity  Code   0    Emergency: system is unusable   1    Alert: action must be taken immediately   2    Critical: critical conditions   3    Error: error conditions   4    Warning: warning conditions   5    Notice: normal but significant condition   6    Informational: informational messages   7    Debug: debug-level messages 

问题:

  1. 必须初始化并持有一个句柄才能打印日志:

    log := NewLogger(10000) log.Trace("trace %s %s","param1","param2")
  2. 打日志先format再去判断级别, 性能差:

    // Log WARNING level message. func (bl *BeeLogger) Warning(format string, v ...interface{}) {  msg := fmt.Sprintf("[W] "+format, v...)  bl.writerMsg(LevelWarning, msg) } func (bl *BeeLogger) writerMsg(loglevel int, msg string) error {  if loglevel > bl.level {   return nil  } 
  3. 为了兼容老代码, 代码中冗余函数较多.

1.3   log4go

File logging with rotation (size, linecount, daily) and custom output formats Console logging Network logging via JSON and TCP/UDP

级别很奇怪:

const (  FINEST level = iota  FINE  DEBUG  TRACE  INFO  WARNING  ERROR  CRITICAL ) 

和常见的顺序是反的.. 没有NOTICE.

使用上也需要初始化一个实例再调用实例的方法.

1.4   codis logging库

级别差不多, 问题不大:

const (  LOG_FATAL   = LogType(0x1)  LOG_ERROR   = LogType(0x2)  LOG_WARNING = LogType(0x4)  LOG_INFO = LogType(0x8)  LOG_DEBUG   = LogType(0x10) ) 
  • 底层是基于Log.
  • 性能ok
  • 不需要初始化一个实例

2   性能

对几个库做了benchmark, (代码: https://github.com/idning/golog/blob/master/benchmark/log_benchmark.go )

结果如下:

go run benchmark/log_benchmark.go qps of     dummy1: 2727908735 qps of     dummy2:  552468326 qps of   variadic:    6151799 qps of    logging:    4003802 qps of      golog:    5986678 qps of     beelog:    1170780       <beego 性能确实较差>

测试发现, 使用变参形式就会导致性能很差:

Debug("hello %s", "world")        // 1. 100w/s Debug("hello world")              // 2. 1000w/s 性能好10倍.

对于变参写法, 通过profiling发现, 此时90%的时间都用于GC,

原因在于, 变参的这种写法, 每次要把参数转为 interface 构成的 slice, 产生了很多对象. 所以gc时间很重.

在benchmark里面我也加了 variadic测试, 对于一个空函数, 也只能达到600w/s 的性能.

3   小结

  1. beego性能较差.
  2. codis logging是目前所见较好的库(日志级别不习惯)
  3. 一旦使用了变参函数, 性能就很差.
正文到此结束
Loading...