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

相关推荐
Seoyoneh10 分钟前
Agentic Workflow编排架构:云客服从“被动响应”迈向“主动执行”的技术实现
java·开发语言·架构
海南java第二人15 分钟前
对外 API 如何保证幂等性?插入数据 / 上传表格场景全方案汇总
java·幂等性
tryxr35 分钟前
Chat2Excel 文件服务模块上传文件功能开发
java·项目·oss·easyexcel·文件服务
Tangyuewei37 分钟前
Java 写 Agent:模型只是组件
java·开发语言
彧azz2 小时前
Java学习语法篇:变量
java·学习
信誓旦旦的程序猿3 小时前
【量化系统从零构建 #04】存储设计:选型·建库·交易日历
java·人工智能·python·股票数据api·股票数据·股票数据api接口·股票api数据接口
yurenpai(27届找实习中)3 小时前
Java 10 的 var 为什么不能随便用?从订单汇总看懂类型推断与泛型陷阱
java·开发语言·java18
Flynt4 小时前
把公司项目迁到 Spring Boot 4.0:编译通过只是开始
java·spring boot·后端
Tangyuewei4 小时前
给老 Spring 项目装个 AI Agent
java·人工智能·spring
她的男孩4 小时前
多租户和数据权限怎么共存?扒完拦截器注册链路,我找到 4 个隐蔽的坑
java·后端·架构