系统日志实践
日志是每个程序员,尤其是后台服务器程序员每天都要接触的东西,但是如何把实现一个好的日志,是有很多道道在里面的。
好的日志 vs 不好的日志
我们为什么要对日志这么一个看起来那么简单的事情专门进行总结呢?看看下面表格就知道了,一个系统,日志的好坏,基本上直接或间接地决定了我们这个系统的质量是什么鸟样。
好的日志 | 不好的日志 |
---|---|
可以帮助开发 了解线上系统的运行状态 快速准确定位线上问题 发现系统瓶颈 预警系统潜在风险 挖掘产品最大价值 |
让开发 对系统的运行状态一知半解,甚至一无所知 系统出现问题无法定位,或者需要花费巨大的时间和精力 无法发现系统瓶颈,不知优化从何做起 无法基于日志对系统运行过程中的错误和潜在风险进行监控和报警 对挖掘用户行为和提升产品价值毫无 |
日志分类
这里只写一下我自己工作中涉及到的日志分类
诊断日志
这个类型的日志,是我们大部分程序员同学接触最多的类型,通常我们日常口中说的日志都是指这个类型
- 请求入口和出口
- 外部服务调用和返回的结果
- 程序异常: DB无法连接
- 程序启动、关闭、配置加载
- 抛出异常时,记录异常的详细信息
- 其他程序运行过程中的信息
审计日志
这个在金融系统,以及一些其他受监管的行业中见的比较多,需要明确记录下一些监管机构要求的信息
- 谁、什么时候、做了什么事情、事情的一些必要细节。
日志内容记录建议
推荐在日志中记录的内容
- 在系统启动或初始化时记录重要的系统初始化参数
- 记录系统运行过程中的所有的警告、错误,要有详细的错误信息,不能只记录一个“出错了”
- 在持久化数据修改时记录修改前和修改后的值
- 记录系统各主要模块之间的请求和响应
- 重要的状态变化
- 系统中一些长期执行的任务的执行进度
不推荐在日志中记录的内容
- 函数入口信息 —— 除非该函数入口表示了一个重要事件的开始,或者将该信息记入DEBUG级别日志
- 文件内容或者一大段消息的内容 —— 如果实在需要记录,则可以截取其中一些重要的信息来记入日志
- “良性”错误 —— 有时候虽然出现了错误,然而错误处理的流程可以正确解决这种情况,例如插入数据库时有重复的记录,尽管是个错误,然而错误处理流程可以对这种情况进行处理
最佳实践
- 整个团队(包括运维人员)需要对日志级别有明确的规定,有明确的日志级别,每个级别的处理方式是怎样的。
- 绝不要打印没有用的日志,尤其是那种循环重复出现的, 防止无用日志淹没重要信息
- 日志信息要准确全面,并且要定期对日志内容优化更新,努力做到仅凭日志就可以定位问题
将一个请求的整个处理流程和唯一的requestID关联起来
TODO 如何制定? server在收到请求的时候生成, 但是如何在传递下去呢? - 日志的优化是一件需要持续不断投入精力的事,需要不断从错误中学习。好的日志就像好的文章一样,绝不是一遍就可以写好的,而需要在实际的运维过程中,结合线上问题的定位,不断地进行优化。
最关键的一点是,团队要重视日志优化这件事情,不要让日志的质量持续降低(当项目变大时,项目的代码也存在一样的问题,越写越乱)。以下是一些推荐的日志优化实践:- 在定位问题的过程中完善日志,如果定位问题花费了很长时间,那就说明系统日志还存在问题,需要进一步完善和优化;
- 需要思考是否可以通过优化日志,来提前预判该问题是否可能发生(如某种资源耗尽而导致的错误,可以对资源的使用情况进行记录)
- 定义好整个团队记录日志的规范,保证每个开发记录的日志格式统一;特别是DEBUG级别的日志,也不能由大家随意发挥
例如 a=0, a = 0, a:0, 这3种不同的表达a的值的格式,在日志检索的时候,就会带来一些额外的工作量
- 团队定期对记录的日志内容进行Review;
- 在查问题的过程来优化日志记录的方式;
- 新上线服务器后一定要对日志进行观察,特别地,开发人员可以通过观察日志来确认新功能是否工作正常
- 对日志进行监控报警,比客户先发现系统问题
- 日志格式要统一规范(通过封装函数实现)
- 要把日志的大小,如何切分,如何删除等作为规范建立起来
- 要有日志定时删除机制(历史日志收集起来集中管理)
- 日志的优化是一件持续不断需要投入精力的事,需要不断从错误中学习
- 要明确不同日志的用途,对日志内容进行分类
- 慢操作监控(某一步操作比正常情况超时过多), 可以对此情况提升日志级别.
这个是否可以做到根据服务状态动态变化?
- 通过日志中的关键字来确定系统的运行状态
- 要有一个web页面来对日志进行管理和展示,避免登录到服务器上查看日志。对一个大规模的分布式集群,如果没有一个统一的地方查看日志,那绝对是噩梦!!!
这个远端的web日志系统,一定要稳定可靠,日志不能丢失,导致开发同学定位问题浪费太多无谓的时间
日志级别的选择
级别 | 定义 |
---|---|
FATAL | 系统级错误, 导致服务某种程度不可用, 需要立即处理. 服务基本已挂 |
ERROR | 系统级错误(用户输入错误的不算), 影响用户访问, 需立即处理, 服务还活着, 但无法提供正常服务 |
WARN | 系统可能有问题, 也可能没有, 例如某些资源的使用超过阈值, 不需要立刻处理, 但是需要关注跟进 |
INFO | 记录系统的正常运行状态, 不宜过多 |
DEBUG | 精确记录系统的每一步运行状态, 通过该种日志, 可以查看某一个操作每一步的执行过程. 可以保证在不重现错误的情况下, 可以通过DEBUG级别的日志对问题进行诊断. 需要规范日志格式 |
引用
https://zhuanlan.zhihu.com/p/27363484
https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels