一、echo 自带的 log 库
1. log 结构
echo 框架的 log 结构体是 echo.Echo 结构体的一个属性
type Echo struct {
...
Logger Logger
}
而 logger 是个这样的接口
type (
// Logger defines the logging interface.
Logger interface {
Output() io.Writer
SetOutput(w io.Writer)
Prefix() string
SetPrefix(p string)
Level() log.Lvl
SetLevel(v log.Lvl)
Print(i ...interface{})
Printf(format string, args ...interface{})
Printj(j log.JSON)
Debug(i ...interface{})
Debugf(format string, args ...interface{})
Debugj(j log.JSON)
Info(i ...interface{})
Infof(format string, args ...interface{})
Infoj(j log.JSON)
Warn(i ...interface{})
Warnf(format string, args ...interface{})
Warnj(j log.JSON)
Error(i ...interface{})
Errorf(format string, args ...interface{})
Errorj(j log.JSON)
Fatal(i ...interface{})
Fatalj(j log.JSON)
Fatalf(format string, args ...interface{})
Panic(i ...interface{})
Panicj(j log.JSON)
Panicf(format string, args ...interface{})
}
)
一般的 log 也都实现了这些方法,所以我们可以使用自己的 log 包替换这个。而作者是使用的 github.com/labstack/gommon/log
这个包。
到这里,自定义 log 级别,输出位置都一目了然了。
2. 默认的 log
在生成 echo.Echo 实例的时候,会初始化一个默认的 log。
// 初始化一个 Echo 实例
func New() (e *Echo) {
e = &Echo{
...
Logger: log.New("echo"),
}
...
e.Logger.SetLevel(log.ERROR) // 默认日志级别
...
return
}
// log.New() 方法是这样的
func New(prefix string) (l *Logger) {
l = &Logger{
level: INFO,
prefix: prefix,
template: l.newTemplate(defaultHeader),
color: color.New(), // 这个是让不同级别的日志在控制台显示不用颜色的。
bufferPool: sync.Pool{
New: func() interface{} {
return bytes.NewBuffer(make([]byte, 256))
},
},
}
l.initLevels() // 同样是处理颜色
l.SetOutput(output()) // 默认是 os.Stdout
return
}
这里的 template 是 github.com/valyala/fasttemplate
包的对象,是一个简单的模版引擎,用来控制 log 的输出样式。
默认的样式是这样的
defaultHeader = `{"time":"${time_rfc3339_nano}","level":"${level}","prefix":"${prefix}",` +
`"file":"${short_file}","line":"${line}"}`
这里的很多配置都和官方 log 的配置类似,也显示了文件名和行号。这里默认支持的时间格式只有两种
time_rfc3339 // "2006-01-02T15:04:05Z07:00"
time_rfc3339_nano // "2006-01-02T15:04:05.999999999Z07:00"
需要更深层次的定制的话就需要修改或者替换 log 包了。
二、 log 中间件
通过这样的方法来注册 log 中间件,这个中间件主要用来针对 http 请求打印日志。
// 使用默认的配置
e.Use(middleware.Logger())
// 自定义配置
// 自定义配置只支持 Format 和 Output 两个属性
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
Format: "method=${method}, uri=${uri}, status=${status}\n",
Output os.Stdout,
}))
默认的配置是这样的
DefaultLoggerConfig = LoggerConfig{
...
Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}","host":"${host}",` +
`"method":"${method}","uri":"${uri}","status":${status}, "latency":${latency},` +
`"latency_human":"${latency_human}","bytes_in":${bytes_in},` +
`"bytes_out":${bytes_out}}` + "\n",
Output: os.Stdout,
colorer: color.New(),
}
自定义配置支持下面这些字段
- time_unix
- time_unix_nano
- time_rfc3339
- time_rfc3339_nano
// 时间上多了两个 unix 时间戳类型
- id (Request ID)
- remote_ip
- uri
- host
- method
- path
- referer
- user_agent
- status
// 常规的 http 请求内容
- latency (In nanoseconds)
- latency_human (Human readable)
// 这个可以算作处理日志花的时间
- bytes_in (Bytes received)
- bytes_out (Bytes sent)
// request 请求和 response 响应的大小
- header:<NAME>
- query:<NAME>
- form:<NAME>
- cookie:<NAME>
// 这几个可以拿到具体内容,分别用下面的方法取得
// tag 就是上面的字段
// c.Request().Header.Get(tag[7:])
// c.QueryParam(tag[6:])
// c.FormValue(tag[5:])
// c.Cookie(tag[7:]
整个日志中间件在这里 https://github.com/labstack/echo/blob/master/middleware/logger.go
,不符合也可以根据需要重新实现一个。
三、后记
之前翻译了 echo 的中文文档 http://go-echo.org,发现文档有很多地方没有说清楚,就萌生了边看代码边补充使用文档的想法。拖了很久终于开工了,拿最简单的 log 开篇,后面会陆续更新关于 echo 其他模块的介绍。
原文地址:laily.net
有疑问加站长微信联系(非本文作者)