需要解决的问题:
- 业务日志打太乱,没有位置和格式约束
- 什么情况打日志,如何避免滥用,提高日志作用
打日志最佳实践
Dropwizard 列出的打日志原则:
Be human readable.
Be machine parsable.
Be easy for sleepy ops folks to figure out why things are pear-shaped at 3:30AM using standard UNIXy tools like tail and grep.
eg.:
TRACE [2010-04-06 06:42:35,271] com.example.dw.Thing: Contemplating doing a thing.
DEBUG [2010-04-06 06:42:35,274] com.example.dw.Thing: About to do a thing.
INFO [2010-04-06 06:42:35,274] com.example.dw.Thing: Doing a thing
WARN [2010-04-06 06:42:35,275] com.example.dw.Thing: Doing a thing
ERROR [2010-04-06 06:42:35,275] com.example.dw.Thing: This may get ugly.
! java.lang.RuntimeException: oh noes!
! at com.example.dw.Thing.run(Thing.java:16)
!
splunk 的最佳实践:
- 使用清晰的键值对:
key1=val1, key2=val2
- 对开发者易读
- 全部添加时间戳
- 使用唯一标记,比如 user_id, transaction_id
- 使用文本
- 使用开发者易用格式,比如 JSON
- 尽可能多加一下数据
- 标记调用来源,比如方法名,类名
- 将多行事件拆分
除了一些浅显易懂的原则,还是 dropwizard 的三条原则和解决方案靠谱。 但是两篇文章都没有告诉如果在复杂系统里面记录有用的日志,打日志生命周期是怎样的。
既然找不到,我就就自行想想如何打有意义的日志。
日志不怕多,而是怕繁杂难搜索,产出的数据无意义难追踪问题。所以最关键是找到一个合理通用的方式组织起来即可:
- 按照模块名 com.duitang.service.module.aaa 打日志,比如
com.duitang.service.module.aaa.log
- 一个模块一个日志,模块复杂之后,可以拆分,
com.duitang.service.module.aaa.core.log
/com.duitang.service.module.aaa.query.log
,其实在这个时侯,这个模块本身由于复杂性也会面临拆分。 - 不分离 error / info 日志,放到一个文件,通过
grep
或者日志工具分离 - 日志文件一定要 rotate,磁盘存储固定时间 N 天,远程文件存储固定时间 M 天,TTL 删除。
补充一个日志常见使用场景:
- 外部资源调用
- 状态变化
- 系统入口和出口
- 业务异常
- 非预期执行
参考文档:
原文链接: 怎么打日志 | Log4D
3a1ff193cee606bd1e2ea554a16353ee
欢迎关注我的微信公众号:窥豹