阿里Java开发者规范之日志打印强制规约及思考

背景

偶尔翻翻代码,看到项目中的日志打印都心有感慨,日志打印风格各异,也没什么好说的,毕竟没有领导专门约束过这些,只能凭个人了。

Java 编码中到底应该怎么打日志呢?一起回顾一下阿里巴巴Java开发者规范中的日志打印强制规约,不多,就 十条,落实到日常开发中需要开发者关注的就八条,掌握区区八条,对靠脑力劳动的开发者应该是不在话下的。

日志强制规约10条

1.应用中不可直接使用三方日志组件(Log4j、Logback)中的API,而应依赖使用统一日志框架(SLF4J、JCL---Jakarta Commons Logging)中的 API。【日常开发关注

2.普通日志保存天数与命名需要遵循规范。【项目初期需要关注】

3.应用中的扩展日志(如打点、临时监控、访问日志等)命名方式:

bash 复制代码
appName_logType_logName.log。
logType:日志类型,如 stats / monitor / access 等;
logName:日志描述。

原理:这种命名的好处是,通过文件名就可知道日志文件属于什么应用,什么类型,什么目的,也有利于归类查找。【项目初期需要关注】

4.避免重复打印日志,浪费磁盘空间,必须在日志配置中设置 additivity=false。【项目初期需要关注】

5.根据国家法律,网络运行状态、网络安全事件、个人敏感信息操作等相关记录,留存的日志不少于六个月,并且要多机备份。【运维关注】

6.在日志输出时,字符串变量之间的拼接使用占位符;有存在用 + 拼接的情况,应该杜绝。【日常开发关注

原理:字符串拼接使用 StringBuilder.append() ,有性能损耗;使用占位符仅是替换动作,可以有效提升性能。

正例:

bash 复制代码
logger.debug("Processing trade with id : {} and symbol : {}", id, symbol);

反例:

bash 复制代码
logger.info("文件路径为:"+classPath+name+",文件大小:"+size+",文件原名称:"+fileName);

7.对于 trace/debug/info 级别的日志输出,必须进行日志级别的开关判断。【日常开发关注

原理:虽然在 Logger 类的 debug(参数) 方法体内第一行代码 isDisabled(Level.DEBUG_INT) 为真时就直接 return, 但是参数可能会进行字符串拼接运算,为了减少不必要的计算,应该遵守第 6 条。【日常开发关注

8.生产环境禁止使用 System.out 或 System.err 输出或使用 e.printStackTrace() 打印异常堆栈。【日常开发关注

原理:首先,System.out 是单例,可能造成死锁「PS:本人亲自排过这个坑」。其次, 它打印到控制台了,一般生产环境Java 应用启动脚本会通过 >/dev/null 2>&1 & 命令忽略控制台日志的,日志信息被淹没了,对问题排查无任何帮助,徒耗资源而已。

9.异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过关键字 throws 往上抛出。同时 logger.error 应该打印堆栈信息方便排错。【开发关注】

10.日志打印时禁止直接用JSON工具将对象转换成 String。【开发关注】

原理:如果对象里某些get方法被覆写,存在抛出异常的情况,则可能会因为打印日志而影响正常业务流程的执行。

启示录

思考:项目代码中很多地方都有在日志中打印 JSON 序列化对象的代码,日志中序列化有两个问题:

  • 1)它耗时。
  • 2)重写 get 方法异常的情况下序列化异常时会影响正常的业务流程。

怎么权衡呢?从我个人的经验来说,虽然直接打印 JSON 确实很方便,但不免有偷懒的嫌疑,总不能一个 JSON 中所有信息都重要吧。心中有这个规约意识,打重要信息,别总想着简单打 JSON,尤其是在开发测试阶段想打又不想影响生产环境而打印 DEBUG 日志时,更要谨慎第 6、7 条。

相关推荐
MZ_ZXD0012 分钟前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
PP东4 分钟前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable
ManThink Technology9 分钟前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
invicinble14 分钟前
springboot的核心实现机制原理
java·spring boot·后端
人道领域22 分钟前
SSM框架从入门到入土(AOP面向切面编程)
java·开发语言
大模型玩家七七42 分钟前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
CodeToGym1 小时前
【Java 办公自动化】Apache POI 入门:手把手教你实现 Excel 导入与导出
java·apache·excel
凡人叶枫1 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发
JMchen1232 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
阔皮大师2 小时前
INote轻量文本编辑器
java·javascript·python·c#