在计算机领域,日志文件是一个记录了发生在运行中的操作系统或其他软件中的事件的文件,或者记录了在网络聊天软件的用户之间发送的消息。几乎所有软件都能从日志记录中获得很多好处。
但是何时打印日志、如何打印日志、日志如何分级对于很多程序员来说,并不是很明确的。本文将从日志的作用、日志的使用场景、日志的要求、日志按等级分类对日志进行介绍。并在文末提供一些日志记录相关建议。
本文仅针对常规日志,对于MySQL中的binlog、redolog这类特殊日志不在考虑范围内。
日志作用
- 明确代码行为
- 用户行为记录(操作记录)
- 系统状态记录
- 异常现场记录
。。。
使用日志
什么是后使用日志:
- 系统状态发生变换
- 业务流程预期不符
- 代码逻辑进入多分支(打印判断依据、分支结果等)
- 系统核心角色,组件关键动作
- 作为服务提供方(打印入参、出参)
- 作为服务提供方(打印入参,出参可根据情况决定是否打印)
- 定时任务运行相关记录
- 编程语言提示异常
。。。
日志基本要求
- 对程序运行情况充分、正确的记录
- 需要满足一定的格式规范,方便日志的分析
- 对系统的性能影响尽量小
。。。
日志按级别分类
FATAL
指出每个严重的错误事件将会导致应用程序的退出。出现这种日志,服务已经出现了某种程度的不可用,系统管理员需要立即介入。通常情况下,一个进程生命周期中应该最多只有一次FATAL记录。频繁使用该日志,会使得警示功能失去意义。日志信息中需要尽可能多的包含信息,包括但不限于输入、堆栈信息、代码位置、进程ID等等。
ERROR
指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息。该级别的错误日志也需要马上被处理,但是紧急程度要低于FATAL级别。从某种程度上说,ERROR和FATAL日志出现时,对用户的体验影响是相当的。包括:
- 打开配置文件失败
- 对接第三方异常
- 数据写入失败
。。。
需要注意的是ERROR和FATAL日志都属于服务器自身异常,而非用户操作不当。不应该使用ERROR或FATAL日志记录如参数不合法等异常行为。
WARN
表明会出现潜在错误的情形,如网络波动,磁盘写入达到阈值等。有些信息不是错误信息,但是也要给程序员的一些提示。对于WARN级别的日志,虽然不需要系统管理员马上处理,也是需要即时查看并处理的。
- 触发容错机制,如配置文件获取失败,使用默认配置
- 触发阈值警报,如磁盘阈值、CPU阈值等
- 系统状态变化,如进入熔断、服务降级等
。。。
INFO
消息在粗粒度级别上突出强调应用程序的运行过程。该种日志记录系统正常运行状态,打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息。如:系统加载过程,系统状态变换,某个请求执行成功等等。通过查看INFO级别的日志,可以很快地对系统中出现的WARN,ERROR,FATAL错误进行定位。
- 调用第三方时的调用参数和调用结果(入参和出参)
- 作为服务提供方,至少记录入参
- 定时任务的开始执行与结束执行
- 系统初始化阶段记录
。。。
DEBUG
主要用于开发过程中打印一些运行信息,给软件开发人员提供故障检测和定位问题的帮助。该级别日志的主要作用是对系统每一步的运行状态进行精确的记录。
TRACE
比DEBUG更加细粒度的日志,除非有特殊用意,否则请使用DEBUG级别替代
注意: DEBUG和TRACE日志规范一般由项目组自行决定。但是也需要规范的日志格式,应该保证除了记录日志的开发人员自己外,其他的如运维,测试人员等也可以通过DEBUG或TRACE日志来定位问题。
以上分类方式参考Log4j,从上到小,日志级别依次降低,加上日志全开和全关,就构成了八种日志级别。
补充
除了上面的分类方法,还有很多其他的分类方式。此处介绍一些常见的差别点。
- 合并
DEBUG和TRACE日志 - 增加
PANIC作为对系统整体严重错误的记录,而原FATAL则作为进程级别的严重错误记录。 - 按照日志作用进行分类,如
mysql的binlog、redolog等
。。。
具体的分类方案,大家可以更具项目规模,使用场景等具体情况,自行判断。只要能充分满足对日志的使用需求即可。
一些建议
- 使用启动参数控制日志打印级别,方便开发、测试、上线日志级别切换
- 增删改操作需要打印参数日志(以便定位一些异常业务问题)
- 业务逻辑中的条件分支需要打印日志:包括条件值以及重要参数;
- 异常信息应该包括两类信息:现场信息和异常堆栈。
-
明确日志打印级别与包含的信息
- 提供服务,建议以 INFO 级别记录入参,出参可选
- 调用服务,建议以 INFO 级别记录入参和出参
- 消费队列消息,务必打印消息内容
- 运行环境问题,如网络错误,建议以 WARN 级别记录错误堆栈
- 定时任务,务必打印任务开始时间、结束时间。涉及扫描数据的任务,务必打印扫描范围
-
谨慎地记录日志
- 生产环境禁止输出 debug 日志
- 有选择地输出 info 日志
- 注意日志输出量的问题,避免把服务器磁盘撑爆,并记得及时删除这些观察日志
- 不要肆无忌惮的在终端上打印
- 尽量减少日志拼接开销,如:使用明确类型的序列化方法,先判断是否需要记录。。。
- 大型系统中分类存储日志,可对不同日志采用不同的写入方法、落盘策略
- 底层核心代码(调用频繁),严格控制日志记录
- 避免重复记录日志
-
添加日志自动拆分功能,避免单个日志文件过于庞大
-
注意日志输出的级别,如非有必要,避免升级或降级日志
- 可以使用 warn 日志级别来记录用户输入参数错误的情况,避免用户投诉时,无所适从
- 有条件的话,尽可能长期保存日志,可以帮助分析周期性异常。
。。。
\