阿里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 条。

相关推荐
杀死那个蝈坦2 小时前
Docker
java·docker·eclipse·tomcat·hibernate
a3158238062 小时前
Android13隐藏某个App需要关注的源码文件
android·java·framework·launcher3·隐藏app
悟空码字3 小时前
SpringBoot实现消息推送:让服务器学会“主动搭讪”
java·spring boot·后端
蒟蒻小袁3 小时前
Hot100--找到字符串中所有字母异位词
java·算法·leetcode·面试
+VX:Fegn08953 小时前
人力资源管理|基于springboot + vue人力资源管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
即随本心0.o3 小时前
SSE服务搭建
java·spring boot
MarkHD3 小时前
车辆TBOX科普 第56次 从模块拼接到可靠交付的实战指南
java·开发语言
灰什么鱼3 小时前
OkHttp + Retrofit2 调用第三方接口完整教程(以nomad为例)
java·spring boot·okhttp·retrofit
掘金-我是哪吒3 小时前
第378集设备服务接入系统Java微服务后端架构实战
java·开发语言·spring·微服务·架构