关于错误日志规范
日志级别
不同标准对日志级别有不同的划分。apache log4j对日志级别的定义如下:
-
FATAL
A fatal event that will prevent the application from continuing.
-
ERROR
An error in the application, possibly recoverable.
-
WARN
An event that might possible lead to an error.
-
INFO
An event that might possible lead to an error.
-
DEBUG
A general debugging event.
-
TRACE
A fine-grained debug message, typically capturing the flow through the application.
slf4j在此基础上给出了更详细的定义(机翻):
- TRACE – 此级别的日志事件是最细粒度的,通常不需要,除非您需要全面了解您的应用程序和您使用的第三方库中发生的事情。您可以期望 TRACE 日志记录级别非常详细。
- DEBUG - 与 TRACE 级别相比,粒度较小,但仍超出您日常使用的需要。DEBUG 日志级别应该用于更深入的诊断和故障排除可能需要的信息。
- INFO – 标准日志级别,指示发生了某事、应用程序处理了请求等。使用 INFO 日志级别记录的信息应该是纯粹的信息,不定期查看它们不应导致丢失任何重要信息。
- WARN – 指示应用程序中发生意外情况的日志级别。例如,一个问题或可能会干扰其中一个进程的情况,但整个应用程序仍在运行。
- ERROR – 当应用程序遇到阻止一个或多个功能正常运行的问题时应该使用的日志级别。当其中一个支付系统不可用时,可以使用 ERROR 日志级别,但仍然可以选择在电子商务应用程序中检查购物篮,或者当您的社交媒体日志选项由于某种原因无法正常工作时。您还可以查看与异常关联的 ERROR 日志级别。
由于定义比较抽象(笼统),可以参考以下图片:
-
特别的,error和warning的区别:warning是潜在的error,将会导致其产生;而error造成了实际上的失败。
-
生产系统一般只打印INFO 级别以上的日志,对于 DEBUG 级别的日志,只在测试环境中打印。打印错误日志时,需要区分是业务异常还是系统异常,业务异常使用 warn 级别记录,系统异常使用 error 记录。
在RFC5424,对syslog级别进行了更细粒度的划分,可供参考。
0 Emergency: system is unusable 1 Alert: action must be taken immediately 2 Critical: critical conditions 3 Error: error conditions 4 Warning: warning conditions 5 Notice: normal but significant condition 6 Informational: informational messages 7 Debug: debug-level messages
维基百科对以上八种情况进行了进一步说明:
Value | Severity | Keyword | Condition |
---|---|---|---|
0 | Emergency | emerg |
A panic condition. |
1 | Alert | alert |
A condition that should be corrected immediately, such as a corrupted system database. |
2 | Critical | crit |
Hard device errors. |
3 | Error | err |
|
4 | Warning | warning |
|
5 | Notice | notice |
Conditions that are not error conditions, but that may require special handling. |
6 | Informational | info |
Confirmation that the program is working as expected. |
7 | Debug | debug |
Messages that contain information normally of use only when debugging a program. |
可见RFC5424主要对error根据其成因和紧急程度进行了进一步的划分。
Emergency:导致系统不可用的事故。
Alert:必须马上处理的问题,如DB损坏。
Critical:硬件错误。
Notice:并非错误,但可能需要特殊处理。
但也有开发者提出对日志级别的细分同时增加了日志IMO(Input, Manipulation, Output)的复杂度,提倡从简划分。
日志格式
[类名{必填}] [方法名{必填}] [错误现象{必填}] [条件{必填}] [可能原因{选填}] [需要怎么做{选填}][栈信息]
- 类名:类名。
- 方法名:方法名。
- 错误现象:描述错误现象,比如"接口超时"或者"接口返回异常"。
- 条件:接口参数或者类 DTO 入参序列化结果。
- 可能原因:描述错误可能原因,比如"缓存满了"或者"某某权限无法获取",错误码,非必选。
- 需要怎么做:描述建议操作, 比如"更新某键值缓存","修改某某权限",非必选。
小结
-
日志的描述需要具体且完整,以便确定错误。
-
在日记等级划分中需要找到一个平衡点,兼顾日志复杂度和开发人员和运维人员的便利性,划分等级太详细,会给日志增加复杂度;太粗略,会给运维人员造成不便。
-
良好规范的日志书写会为开发和运维提供便利,日志并非越多越好,无效日志的输出不仅不利于系统性能且不利于问题排查。
由于网上关于错误日志规范的权威文档较少,多是开发者个人的经验总结,笔者开发经验甚少,只能拾人牙慧。