应用日志规范
目录
简介
为什么会有这篇文章?
日志无论在什么时候,都是一个重要的工具。而一个好的日志规范,可以避免/解决很多问题:
- 低成本。一次配置,一次学习即可
- 适用性强。解决对接各个开源组件,云厂商
- 好用/便捷。
设计
日志存放的目录/文件
日志文件存放在 /data/logs/
,如果 linux 系统如果不存在这个路径,创建出来这个路径。
路径下最多会有 2 个日志文件。
App1-20240115.log
此文件为当天日志写入的文件。app 名称不允许重复,可以使用 git 仓库名group1-app1
来确保唯一。App1-20240114.log
此文件为前 1 天的备份文件,在轮转日志的时候,保证日志完整采集
例如 golang 的 lumberjack,当前写入的文件名为
App1.log
,没有日期后缀也是可以正常处理的。参考下面的日志处理部分
日志内容
字段含义:
time
记录时间:2024-01-08T15:30:45.123+08:00
标准的 iso 8601 时间戳,方便阅读level
日志等级:Information
,Debug
枚举有限的值source
调用源/异常点: csharp 里Properties.SourceContext
和 golang 的caller
这样的值msg
具体信息:xxx登录成功了
控制台输出格式
- logfmt 格式。方便明白每个字段的含义
- 因兼容性问题,关闭色彩
time=2024-01-08T15:30:45.123+08:00 level=info source=main.go:112 msg="xxx登录成功了" xx=oo
文件输出格式
- json 格式。方便解析
- 单行方便分割
{"time":"2024-01-08T15:30:45.123+08:00","level":"info","source":"main.go:112","message":"xxx登录成功了","xx":"oo"}
配置项表格
配置项 | 值 |
---|---|
日志目录 | /data/logs/ |
日志文件名 | 服务名.log |
日志记录等级 | info |
轮转规则 | 1 |
日志格式 - 控制台 stdout | logfmt |
日志格式 - 文件 file | json |
字段 | time/level/source/msg + 自定义字段 |
日志处理
日志采集/分析程序现状:
- 几乎都支持
/path/*.log
采集- 我们采集
/data/logs/*.log
日志。
- 我们采集
- 不是都支持轮转
- 我们程序必须自己轮转
日志轮转通常分 2 种。
- copy,truncate。现拷贝一份文件,然后 truncate 清理源文件。
- 我本来认为这一种会更好。因为文件不动,应用不收到影响。而其他的文件随时可删。可是我们在 copy 和 truncate 的短暂间隙,可能日志还没来得及采集,会丢失数据!
- rename,create。重命名现有的文件,然后创建一个新的文件。、
- 这个方法没有上面的缺点。但需要应用程序主动写入新的文件。需要采集程序监听这种文件的变化,避免不释放文件描述符和采集不到的情况。
- 现实情况是,我们的程序可以自己控制。而采集程序都支持通过
inotify
来监听这种变化,消除了第二种方式的缺点。
很多工具, 比如 grafana-Promtail 对第二种方式都有良好的支持. 因此我们设计每天写入一个新 log 文件是好的实践。