设计一个 Golang Go语言的日志库

发布于 1周前 作者 ionicwang 来自 Go语言

日志库是最基础和最重要的库,go 官方的日志库功能太简陋,项目中经常使用的功能:日志级别,json 格式,按日期旋转文件等都不支持。

而使用最多的 logrus 库也不支持按时间旋转文件,还要依赖另外三方包去实现。

所以我决定重新设计一个简单易用的日志库 ylog.

ylog 日志库特点:

  • 支持日志级别
  • 支持按日期旋转文件
  • 支持 json 格式
  • 支持自定义格式和输出
  • 代码测试覆盖率 100%
  • 线程安全的
  • 超越 sirupsen/logrus 日志库的性能

项目: https://github.com/lyuangg/ylog

设计思想: http://yuancoder.com/ylog/


设计一个 Golang Go语言的日志库

更多关于设计一个 Golang Go语言的日志库的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

20 回复

其实大多时候打到 syslog 去让 rsyslogd 和 logrotate 去处理日志运维的杂事(比如切分)就够用了。

哦,用 Windows 的请直接无视我。

更多关于设计一个 Golang Go语言的日志库的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


另,以上不针对功能性的轮子。只针对日志切分、旋转这种运维性质的杂活。

感觉维基百科译作日志轮替比日志旋转好理解很多

logrus 的作者也是这么想的,可现实不是这样的

额,标准库马上要加日志库了…

标准库不是要有了吗

那有什么必须的理由把 rotation 做成 application 的一部分而不是外部功能呢?

作为一个运维人员,我想到用外部功能来做的主要理由是,logging 虽然不属于业务功能,但毕竟还是应用系统的一部分,属于业务发出的动作,而 rotation 则完全和业务无关,是“带外”操作,其逻辑本身就是外部化的。rotation 跟业务逻辑没有什么必然关系,生产环境所要维护的 rotation 操作,外部化之后,可以用专门做 rotation 的组件来配置足够复杂和灵活的处理规则,这些没必要让做开发的角色来操心。这种解耦有利于业务程序员和基建运维发挥各自的长处,各司其职,而不是业务程序员操心基建开发,在“进程内”造轮子,运维又要学习一堆繁杂但又不见得比现有成熟基建更强大的专用配置来吐槽。

#7 完全同意,这样增加了运维的复杂度

另外,不是说日志库完全不需要考虑 rotation 。只要留个操作,可以 reopen 当前的日志文件就行了。外部 rotation 工具在移动日志文件后往进程传一个 rotation 指示(比如 kill -HUP ),进程收到后 reopen 日志文件,就写到新的文件里去了。而不需要在日志库里对日志文件的更替做定时管理。日志库里要再加上这个功能,那又要牵扯到定时任务管理,更加复杂了。

我觉得 logrus 适合用在脚本或者小工具上,大点的项目我用 zap 更多点

再比如,用 logrotate ,我可以配置 pre 和 post 脚本,在 rotate 动作的前后做一些处理。

而 rotate 功能做在 application 内部了,怎么办呢?让写 application 的业务开发团队加这个功能,然后业务开发再去推写 log 库的人加这个功能?就算实现了,谁能保证专注于写业务的开发团队顺手做的能比人家 logrotate 一心一意做了这么多年积累下来的经验更可靠?那我当然是希望业务开发团队不要操心这些事情。

下一个功能,是不是得在轮转之后加上压缩功能,再后面,是不是得加上搬运到冷存功能,再后面…

golang 标准库准备在近期版本加入一个结构化日志库 slog ,可以关注下

OP 输入的 Markdown 语法的链接没有加 scheme

markdown 写反了 [哭了]

研究研究

这就复杂了 [二哈]

你说的有道理,我遇到的情况是,小公司的运维根本就不管这个。

真的吗。那可以不用第三方了。目前用的 zerolog

欢迎使用 https://github.com/gookit/slog

一个易于使用的,轻量级、可配置、可扩展的日志库。支持多个级别,输出到多文件;内置文件日志处理、自动切割、清理、压缩等增强功能

设计一个 Golang 日志库时,需要考虑以下几个关键点以确保其功能全面且高效:

  1. 日志级别:支持不同的日志级别(如 DEBUG、INFO、WARN、ERROR、FATAL),允许开发者根据需求调整日志的详细程度。

  2. 输出格式:提供灵活的日志格式配置,如 JSON、文本格式,以及时间戳、日志级别、文件名、行号等信息的显示。

  3. 日志目标:支持多种日志输出目标,如文件、控制台、远程服务器(如 Logstash),并允许同时向多个目标输出日志。

  4. 异步处理:为了提高性能,可以引入异步日志处理机制,避免阻塞主线程。

  5. 上下文支持:支持在日志中添加上下文信息,如请求ID、用户ID等,便于追踪和调试。

  6. 可扩展性:设计良好的接口和钩子,允许开发者自定义日志处理器、格式化器等,以满足特定需求。

  7. 性能:优化代码,减少内存分配和CPU开销,特别是在高并发场景下。

  8. 安全性:处理日志时要避免敏感信息泄露,特别是在日志输出到不安全环境时。

实现时,可以参考现有的成熟日志库(如 zap、logrus)的设计,结合项目需求进行定制化开发。同时,良好的文档和测试用例也是确保日志库易用性和稳定性的关键。总之,设计一个 Golang 日志库需要综合考虑功能性、性能、安全性和易用性等多个方面。

回到顶部