Table of Contents
日志库考虑因素:
级别: 最好是 always, err, warn, notice, info, debug, verbos 几个级别.
性能: 如果设置级别低, 应该对程序性能没有任何影响.(不要先format)
不需要显示初始化.
打印代码行.
可以动态设置日志级别
因为标准库不支持日志级别, 所以造轮子的需求很强烈.
~/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
问题:
必须初始化并持有一个句柄才能打印日志:
log := NewLogger(10000)
log.Trace("trace %s %s","param1","param2")
打日志先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
}
为了兼容老代码, 代码中冗余函数较多.
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.
使用上也需要初始化一个实例再调用实例的方法.
级别差不多, 问题不大:
const (
LOG_FATAL = LogType(0x1)
LOG_ERROR = LogType(0x2)
LOG_WARNING = LogType(0x4)
LOG_INFO = LogType(0x8)
LOG_DEBUG = LogType(0x10)
)
对几个库做了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 的性能.