分享
  1. 首页
  2. 文章

golang echo 代码详解之 log 篇

Laily · · 7253 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一、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


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
7253 次点击
被以下专栏收入,发现更多相似内容
1 回复 | 直到 2025年05月13日 22:28:56
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏