代码日志打印规范

大彬大约 7 分钟

代码日志打印规范

日志文件提供精确的系统记录,根据日志可以定位到错误详情和根源,方便开发排查问题。

日志有什么作用呢

  • 打印调试:即用日志来记录变量或者某个逻辑。记录程序运行的流程,即程序运行了哪些代码,方便排查逻辑问题。
  • 问题定位:程序出异常或者出故障时快速的定位问题,方便后期解决问题。因为线上生产环境无法 debug,在测试环境去模拟一套生产环境,费时费力。所以依靠日志记录的信息定位问题,这点非常重要。还可以记录流量,后期可以通过 ELK(包括 EFK 进行流量统计)。
  • 用户行为日志:记录用户的操作行为,用于大数据分析,比如监控、风控、推荐等等。这种日志,一般是给其他团队分析使用,而且可能是多个团队,因此一般会有一定的格式要求,开发者应该按照这个格式来记录,便于其他团队的使用。当然,要记录哪些行为、操作,一般也是约定好的,因此,开发者主要是执行的角色。
  • 根因分析(甩锅必备):即在关键地方记录日志。方便在和各个终端定位问题时,别人说时你的程序问题,你可以理直气壮的拿出你的日志说,看,我这里运行了,状态也是对的。这样,对方就会乖乖去定位他的代码,而不是互相推脱。

什么时候记录日志?

上文说了日志的重要性,那么什么时候需要记录日志。

  • 系统初始化:系统或者服务的启动参数。核心模块或者组件初始化过程中往往依赖一些关键配置,根据参数不同会提供不一样的服务。务必在这里记录 INFO 日志,打印出参数以及启动完成态服务表述。
  • 编程语言提示异常:如今各类主流的编程语言都包括异常机制,业务相关的流行框架有完整的异常模块。这类捕获的异常是系统告知开发人员需要加以关注的,是质量非常高的报错。应当适当记录日志,根据实际结合业务的情况使用 WARN 或者 ERROR 级别。
  • 业务流程预期不符:除开平台以及编程语言异常之外,项目代码中结果与期望不符时也是日志场景之一,简单来说所有流程分支都可以加入考虑。取决于开发人员判断能否容忍情形发生。常见的合适场景包括外部参数不正确,数据处理问题导致返回码不在合理范围内等等。
  • 系统核心角色,组件关键动作:系统中核心角色触发的业务动作是需要多加关注的,是衡量系统正常运行的重要指标,建议记录 INFO 级别日志,比如电商系统用户从登录到下单的整个流程;微服务各服务节点交互;核心数据表增删改;核心组件运行等等,如果日志频度高或者打印量特别大,可以提炼关键点 INFO 记录,其余酌情考虑 DEBUG 级别。
  • 第三方服务远程调用:微服务架构体系中有一个重要的点就是第三方永远不可信,对于第三方服务远程调用建议打印请求和响应的参数,方便在和各个终端定位问题,不会因为第三方服务日志的缺失变得手足无措。

日志级别

常用的分为以下几种:

1、ERROR

影响到程序正常运行、当前请求正常运行的异常情况。如:

1)打开配置文件失败

2)所有第三方对接的异常(包括第三方返回错误码)

3)所有影响功能使用的异常,包括:SQLException 、空指针异常以及业务异常之外的所有异常

2、WARN

告警日志。不应该出现但是不影响程序、当前请求正常运行的异常情况。

但是一旦出现了也需要关注,因此一般该级别的日志达到一定的阈值之后,就得提示给用户或者需要关注的人了。如:

1)有容错机制的时候出现的错误情况

2)找不到配置文件,但是系统能自动创建配置文件

3、INFO

记录输入输出、程序关键节点等必要信息。平时无需关注,但出问题时可根据INFO日志诊断出问题

1)Service方法中对于系统/业务状态的变更

2)调用第三方时的调用参数和调用结果(入参和出参)

3)提供方,需要记录入参

4)定时任务的开始执行与结束执行

4、DEBUG

调试信息,对系统每一步的运行状态进行精确的记录。

5、TRACE

特别详细的服务调用流程各个节点信息。业务代码中,除非涉及到多级服务的调用,否则不要使用(除非有特殊用意,否则请使用DEBUG级别替代)

日志打印规范

1、增删改操作需要打印参数日志(以便定位一些异常业务问题);

2、条件分支需要打印日志:包括条件值以及重要参数;

3、明确日志打印级别与包含的信息

1)提供方服务,建议以 INFO 级别记录入参,出参可选

2)消费队列消息,务必打印消息内容

3)调用方服务,建议以 INFO 级别记录入参和出参

4)运行环境问题,如网络错误、建议以 WARN 级别记录错误堆栈

5)定时任务,务必打印任务开始时间、结束时间。涉及扫描数据的任务,务必打印扫描范围

4、异常信息应该包括两类信息案发现场信息异常堆栈信息。如果不处理,那么通过关键字throws/throw 往上抛出,由父级方法处理

5、谨慎地记录日志

1)生产环境禁止输出 debug 日志

2)有选择地输出 info 日志

3)如果使用 warn 来记录刚上线时的业务行为信息,一定要注意日志输出量的问题,避免把服务器磁盘撑爆,并记得及时删除这些观察日志

6、可以使用 warn 日志级别来记录用户输入参数错误的情况

7、对 trace/debug/info级别的日志输出,必须使用条件输出形式或者使用占位符的方式

8、不允许记录日志后又抛出异常,因为这样会多次记录日志,只允许记录一次日志

9、不允许出现System print(包括System.out.println和System.error.println)语句作为日志的打印

10、不允许出现 e.printStackTrace

11、日志性能的考虑。如果代码为核心代码,执行频率非常高,则输出日志建议增加判断,尤其是低级别的输出

12、【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一

13、【强制】避免重复打印日志,浪费磁盘空间。务必在 log4j.xml 中设置 additivity=false

参考链接:

https://cloud.tencent.com/developer/article/1559519open in new window

https://www.jianshu.com/p/d94cf3069568open in new window

Loading...