Go日志库Logrus拿下2.5万Star,结构化日志的开路先锋
Go日志库Logrus拿下2.5万Star,结构化日志的开路先锋
Go 语言标准库自带 log 包,但功能太基础了:没有日志级别、没有结构化字段、输出格式也单一。Logrus 就是来解决这些问题的,而且它做到了跟标准库 API 完全兼容。GitHub 上 25,728 个 Star,是 Go 生态里最知名的日志库之一。

一行 import 就能用
Logrus 的入门成本几乎为零。你只需要把 import 改一下:
import log "github.com/sirupsen/logrus"
原来代码里所有 log.Print、log.Fatal 照常工作,不需要改任何业务逻辑。然后你可以按自己的节奏逐步加上结构化字段:
log.WithFields(logrus.Fields{
"user_id": 12345,
"action": "login",
}).Info("用户登录成功")
这种写法的好处是在生产环境查日志时,可以按字段精确过滤,而不是用 grep 在字符串里大海捞针。Logrus 官方文档原话是:经历过无数次"加一个字段就能省下几小时排查"的场景之后,结构化日志的必要性就不需要再论证了。
七级日志加上双格式输出
Logrus 支持七个日志级别:Trace、Debug、Info、Warning、Error、Fatal、Panic。通过 log.SetLevel(log.InfoLevel) 可以控制最低输出级别,低于该级别的日志会被忽略。开发时开 Debug,生产环境只输出 Info 及以上,很实用。
输出格式提供了两种内置选择:TextFormatter 和 JSONFormatter。本地开发默认用 TextFormatter,终端里带颜色高亮,错误红色、警告黄色。切到 JSONFormatter 之后,每行一条 JSON,Logstash、Splunk、Elasticsearch 这些日志平台可以直接解析:
{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2014-03-10 19:57:38.562"}

Hook 机制让一条日志多路分发
Logrus 的 Hook 设计是把一个日志事件同时发给多个目标。你可以注册几个 Hook:Error 级别以上的发到 Sentry 做异常告警,Info 级别的按采样率发给 StatsD 做统计,全部日志写到本地文件。每个 Hook 各自处理,互不阻塞。
官方内置了 Syslog Hook,社区也有大量第三方 Hook,覆盖了 Airbrake、Bugsnag、Logstash、Fluentd 等服务。自定义 Hook 也很简单,实现一个接口就行。
进入维护模式不是说项目死了
2020 年前后,Logrus 作者宣布项目进入维护模式,只修 bug 和安全问题,不再加新功能。有人觉得这是维护者放弃了,实际正相反:Logrus 已经把 Go 结构化日志这件事定义清楚了。后来出现的 Zerolog、Zap 在性能上确实更强(Zap 的零内存分配设计在高并发场景下比 Logrus 快数倍),但它们的设计范式都来自 Logrus 打下的基础。
这是一个标准制定者的角色:定义了接口和交互方式之后,后来者在相同范式下去做极致优化。Logrus 的历史任务完成了。
现在还能用吗
如果你在写一个对日志吞吐要求不是每秒百万级别的 Go 项目,Logrus 依然是很好的选择。API 设计是它最大的优势:足够简单、足够直观、文档完善。从标准库迁移过来的学习成本几乎为零。
Docker、Prometheus、Grafana Loki 等项目都曾经或仍在大量使用 Logrus。25k Star 的数字本身就说明了社区认可度。
安装就是一条命令搞定。如果对延迟敏感的链路(比如高频交易的日志路径),可以考虑 Zerolog 或 Zap;其余场景,Logrus 的易用性已经足够覆盖。

浙公网安备 33010602011771号