Alibaba开发规范_异常日志之日志规约:最佳实践与常见陷阱
文章目录
- 引言
- 1. 使用SLF4J日志门面
- 规则
- 解释
- 代码示例
- 正例
- 反例
- 2. 日志文件的保存时间
- 规则
- 解释
- 3. 日志文件的命名规范
- 规则
- 解释
- 代码示例
- 正例
- 反例
- 4. 使用占位符进行日志拼接
- 规则
- 解释
- 代码示例
- 正例
- 反例
- 5. 日志级别的开关判断
- 规则
- 解释
- 代码示例
- 正例
- 反例
- 6. 避免重复打印日志
- 规则
- 解释
- 代码示例
- 正例
- 反例
- 7. 记录异常信息
- 规则
- 解释
- 代码示例
- 正例
- 反例
- 8. 谨慎记录日志
- 规则
- 解释
- 9. 使用`warn`记录用户输入错误
- 规则
- 解释
- 代码示例
- 正例
- 反例
- 10. 使用英文描述日志错误信息
- 规则
- 解释
- 代码示例
- 正例
- 反例
- 总结

引言
日志是软件开发中不可或缺的一部分,合理的日志记录可以帮助开发者快速定位问题、监控系统运行状态。本文将深入探讨Java日志规约的最佳实践,并通过反例和正例代码来更好地理解和应用这些规则。
1. 使用SLF4J日志门面
规则
- 应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架SLF4J中的API。
解释
SLF4J(Simple Logging Facade for Java)是一个日志门面框架,它提供了统一的API,允许应用程序在不修改代码的情况下切换底层日志实现(如Log4j、Logback)。使用SLF4J可以提高代码的可维护性和灵活性。
代码示例
正例
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class Test {private static final Logger logger = LoggerFactory.getLogger(Test.class);public void doSomething() {logger.info("This is an info message.");}
}
反例
import org.apache.log4j.Logger;public class Test {private static final Logger logger = Logger.getLogger(Test.class);public void doSomething() {logger.info("This is an info message.");}
}
在反例中,直接使用Log4j的API,导致代码与具体日志实现耦合,难以切换日志框架。
2. 日志文件的保存时间
规则
- 所有日志文件至少保存15天,因为有些异常具备以“周”为频次发生的特点。网络运行状态、安全相关信息、系统监测、管理后台操作、用户敏感操作需要留存相关的网络日志不少于6个月。
解释
日志文件的保存时间应根据业务需求和法律要求来确定。通常,日志文件至少保存15天,而涉及安全和敏感操作的日志需要保存更长时间(如6个月)。
3. 日志文件的命名规范
规则
- 应用中的扩展日志(如打点、临时监控、访问日志等)命名方式:
appName_logType_logName.log。
解释
通过规范的日志文件名,可以快速识别日志的来源、类型和用途,便于日志的管理和查找。
代码示例
正例
force_web_timeZoneConvert.log
反例
log.txt
在反例中,日志文件名过于简单,无法快速识别日志的来源和用途。
4. 使用占位符进行日志拼接
规则
- 在日志输出时,字符串变量之间的拼接使用占位符的方式。
解释
使用占位符(如{})进行日志拼接可以避免不必要的字符串拼接操作,提高性能。
代码示例
正例
logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);
反例
logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);
在反例中,使用字符串拼接会导致性能损耗,尤其是在日志级别较高时(如INFO、WARN)。
5. 日志级别的开关判断
规则
- 对于
trace/debug/info级别的日志输出,必须进行日志级别的开关判断。
解释
在输出日志之前进行级别判断,可以避免不必要的字符串拼接和方法调用,提高性能。
代码示例
正例
if (logger.isDebugEnabled()) {logger.debug("Current ID is: {} and name is: {}", id, getName());
}
反例
logger.debug("Current ID is: " + id + " and name is: " + getName());
在反例中,即使日志级别高于DEBUG,仍然会执行字符串拼接和方法调用,造成性能浪费。
6. 避免重复打印日志
规则
- 避免重复打印日志,浪费磁盘空间,务必在
log4j.xml中设置additivity=false。
解释
additivity属性控制子Logger是否继承父Logger的输出源。设置为false可以避免日志重复输出。
代码示例
正例
<logger name="com.taobao.dubbo.config" additivity="false"><appender-ref ref="FILE"/>
</logger>
反例
<logger name="com.taobao.dubbo.config"><appender-ref ref="FILE"/>
</logger>
在反例中,未设置additivity=false,可能导致日志重复输出。
7. 记录异常信息
规则
- 异常信息应该包括两类信息:案发现场信息和异常堆栈信息。
解释
记录异常时,应包含案发现场信息(如参数值、状态等)和异常堆栈信息,以便快速定位问题。
代码示例
正例
try {// 业务逻辑
} catch (Exception e) {logger.error("Error processing trade with id: " + tradeId, e);
}
反例
try {// 业务逻辑
} catch (Exception e) {logger.error("Error occurred");
}
在反例中,未记录异常堆栈信息,难以定位问题。
8. 谨慎记录日志
规则
- 生产环境禁止输出
debug日志;有选择地输出info日志;使用warn记录业务行为信息时,注意日志输出量。
解释
过多的日志输出会影响系统性能,并增加日志管理的难度。应根据实际需求谨慎记录日志。
9. 使用warn记录用户输入错误
规则
- 可以使用
warn日志级别来记录用户输入参数错误的情况,避免用户投诉时无所适从。
解释
使用warn级别记录用户输入错误,可以在不频繁报警的情况下,提供足够的信息用于问题排查。
代码示例
正例
if (userInput == null) {logger.warn("User input is null");
}
反例
if (userInput == null) {logger.error("User input is null");
}
在反例中,使用error级别记录用户输入错误,可能导致频繁报警。
10. 使用英文描述日志错误信息
规则
- 尽量用英文来描述日志错误信息,如果日志中的错误信息用英文描述不清楚的话使用中文描述即可。
解释
使用英文描述日志错误信息可以提高日志的通用性,特别是在国际化团队或海外部署的场景中。
代码示例
正例
logger.error("Failed to process trade: tradeId={}", tradeId);
反例
logger.error("处理交易失败:tradeId={}", tradeId);
在反例中,使用中文描述日志错误信息,可能导致国际化团队难以理解。
总结
通过遵循日志规约的最佳实践,开发者可以编写出高效、易维护的日志代码。

相关文章:
Alibaba开发规范_异常日志之日志规约:最佳实践与常见陷阱
文章目录 引言1. 使用SLF4J日志门面规则解释代码示例正例反例 2. 日志文件的保存时间规则解释 3. 日志文件的命名规范规则解释代码示例正例反例 4. 使用占位符进行日志拼接规则解释代码示例正例反例 5. 日志级别的开关判断规则解释代码示例正例反例 6. 避免重复打印日志规则解释…...
使用istio实现权重路由
istio概述 **概述:**Istio 是一个开源的 服务网格(Service Mesh)解决方案,主要用于管理、保护和监控微服务架构中的服务通信。它为微服务提供了基础设施层的控制功能,不需要更改应用程序的代码,从而解决服…...
M. Triangle Construction
题目链接:Problem - 1906M - Codeforces 题目大意:给一个 n 边形, 每一个边上有a[ i ] 个点, 在此多边形上求可以连的三角形有多少个, 每个点只能用一次。 输入: 第一行是一个整数 N ( 3 ≤ N ≤ 200000…...
每天学点小知识之设计模式的艺术-策略模式
行为型模式的名称、定义、学习难度和使用频率如下表所示: 1.如何理解模板方法模式 模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基…...
机试题——到邻国目标城市的最短距离
题目描述 A国与B国是相邻的两个国家,每个国家都有很多城市。国家内部有很多连接城市的公路,国家之间也有很多跨国公路,连接两个国家的边界城市。两个国家一共有N个城市,编号从1到N,一共有M条公路,包括国内…...
Python + Tkinter + pyttsx3实现的桌面版英语学习工具
Python Tkinter pyttsx3实现的桌面版英语学习工具 在多行文本框输入英文句子,双击其中的英文单词,给出英文读音和中文含义和音标。 本程序查询本地词典数据。通过菜单栏"文件"->"打开词典编辑器"进入编辑界面。 词典数据存储…...
【Vite + Vue + Ts 项目三个 tsconfig 文件】
Vite Vue Ts 项目三个 tsconfig 文件 为什么 Vite Vue Ts 项目会有三个 tsconfig 文件?首先我们先了解什么是 tsconfig.json ? 为什么 Vite Vue Ts 项目会有三个 tsconfig 文件? 在使用 Vite 创建 vue-ts 模板的项目时,会发现除了 ts…...
AI时代IT行业职业方向规划大纲
一、引言 AI时代的颠覆性影响 ChatGPT、Midjourney等生成式AI对传统工作模式的冲击 案例:AI编程助手(GitHub Copilot)改变开发者工作流程 核心问题:IT从业者如何避免被AI替代,并找到新机遇? 二、AI时代…...
Mac M1 Comfyui 使用MMAudio遇到的问题解决?
问题1: AssertionError: Torch not compiled with CUDA enabled? 解决办法:修改代码以 CPU 运行 第一步:找到 /ComfyUI/custom_nodes/ComfyUI-MMAudio/mmaudio/ext/autoencoder/vae.py文件中的下面这两行代码 self.data_mean nn.Buffer(t…...
大语言模型深度研究功能:人类认知与创新的新范式
在人工智能迅猛发展的今天,大语言模型(LLM)的深度研究功能正在成为重塑人类认知方式的关键力量。这一突破性技术不仅带来了工具层面的革新,更深刻地触及了人类认知能力的本质。本文将从认知科学的角度出发,探讨LLM如何…...
[SAP ABAP] 性能优化
1.数据库编程OPEN SQL方面优化 1.避免使用SELECT *,只查询需要的字段即可 尽量使用SELECT f1 f2 ... (具体字段) 来代替 SELECT * 写法 2. 如果确定只查询一条数据时,使用 SELECT SINGLE... 或者是 SELECT ...UP TO 1 ROWS ... 使用语法 UP TO n ROWS 来…...
并行计算、分布式计算与云计算:概念剖析与对比研究(表格对比)
什么是并行计算?什么是分布计算?什么是云计算?我们如何更好理解这3个概念,我们采用概念之间的区别和联系的方式来理解,做到切实理解,深刻体会。 1、并行计算与分布式计算 并行计算、分布式计算都属于高性…...
ASP.NET Core Filter
目录 什么是Filter? Exception Filter 实现 注意 ActionFilter 注意 案例:自动启用事务的筛选器 事务的使用 TransactionScopeFilter的使用 什么是Filter? 切面编程机制,在ASP.NET Core特定的位置执行我们自定义的代码。…...
doris:删除操作概述
在 Apache Doris 中,删除操作(Delete)是一项关键功能,用于管理和清理数据,以满足用户在大规模数据分析场景中的灵活性需求。 Doris 提供了丰富多样的删除功能支持,包括:DELETE 语句、删除标记&…...
【思维导图】redis
学习计划:将目前已经学的知识点串成一个思维导图。在往后的学习过程中,不断往思维导图里补充,形成自己整个知识体系。对于思维导图里的每个技术知识,自己用简洁的话概括出来, 训练自己的表达能力。...
申博经验贴
1. 所谓申博,最重要的就是定制的海投 分成两个部分 1. 定制 要根据每个教授去写不同的,一定不要泛泛的去写,一定要非常非常的具体,要引起教授的兴趣。每个教授每天都会收到几十封邮件,所以要足够的引起教授的注意&a…...
.Net Core笔记知识点(跨域、缓存)
设置前端跨域配置示例: builder.Services.AddCors(option > {option.AddDefaultPolicy(policy > {policy.WithOrigins(originUrls).AllowAnyMethod().AllowAnyHeader().AllowCredentials();});});var app builder.Build();app.UseCors(); 【客户端缓存】接…...
YOLOV11-1:YoloV11-安装和CLI方式训练模型
YoloV11-安装和CLI方式训练模型 1.安装和运行1.1安装的基础环境1.2安装yolo相关组件1.3命令行方式使用1.3.1 训练1.3.2 预测 本文介绍yoloV11的安装和命令行接口 1.安装和运行 1.1安装的基础环境 GPU环境,其中CUDA是12.4版本 1.2安装yolo相关组件 # 克隆github…...
自学习记录-编程语言的特点(持续记录)
我学习的顺序是C -> python -> C -> Java。在讲到某项语言的特点是,可能会时不时穿插其他语言的特点。 Java 1 注解Annotation Python中也有类似的Decorators。以下为AI学习了解到的: Java的Annotation是一种元数据(metadata)&a…...
TypeScript (TS) 和 JavaScript (JS)
TypeScript (TS) 和 JavaScript (JS) 的区别主要在于 TypeScript 是 JavaScript 的一个超集,它在 JavaScript 基础上增加了类型系统和一些高级功能。让我们详细看看两者的区别和关系: 类型系统: TypeScript 最大的特点是 静态类型。在 TypeSc…...
Zotero插件生态:从翻译到效率提升的进阶配置指南
1. Zotero插件生态全景:从翻译到全流程优化 第一次接触Zotero时,我和大多数人一样,只是把它当作一个简单的文献管理工具。直到某天深夜赶论文,连续手动整理了47篇参考文献后,手指酸痛的我突然意识到:这绝对…...
嵌入式软件三大代码架构设计方法详解
嵌入式软件常用的几种代码架构设计方法1. 项目概述在嵌入式软件开发领域,合理的代码架构设计对系统稳定性、可维护性和实时性至关重要。本文系统介绍三种典型的嵌入式软件架构设计方案,分析其适用场景与实现要点。2. 时间片轮询法2.1 架构特点时间片轮询…...
从一条SQL到HDFS文件:手把手拆解Hive在YARN上的完整‘跑路’流程
从一条SQL到HDFS文件:手把手拆解Hive在YARN上的完整执行链路 当你在Beeline客户端输入一条看似简单的HiveQL查询时,背后究竟发生了什么?这条SQL如何穿越层层组件,最终变成分布式文件系统上的数据块操作?本文将带你以系…...
影刀RPA神用法:自动监控竞品价格的实操步骤
监控竞品价格的实操步骤数据采集模块配置 打开影刀RPA,创建一个新流程。使用网页抓取功能,定位竞品网站的价格元素。通过XPath或CSS选择器精准获取价格数据,确保动态加载内容也能被捕获。价格异常触发机制 设置价格波动阈值,当竞品…...
告别指标混乱:衡石科技指标管理平台的AI自治之路
指标混乱的根源在数字化时代,企业决策依赖的指标体系正面临前所未有的混乱:63%的企业存在指标定义不统一问题,58%的团队因数据口径差异导致决策冲突。这种"指标地狱"不仅消耗大量人力进行数据对齐,更直接导致战略执行偏移。某制造企业的案例极具代表性:其生产部门与财…...
Netgear路由器Telnet功能启用工具:技术解析与实践指南
Netgear路由器Telnet功能启用工具:技术解析与实践指南 【免费下载链接】netgear_telnet Netgear Enable Telnet (New Crypto) 项目地址: https://gitcode.com/gh_mirrors/ne/netgear_telnet 一、功能价值:技术突破点与应用场景 1.1 核心功能概述…...
ONNX Runtime C++部署踩坑记:GetInputName已弃用,手把手教你改用GetInputNameAllocated
ONNX Runtime C部署实战:从GetInputName到GetInputNameAllocated的平滑迁移指南 在深度学习模型部署的生态系统中,ONNX Runtime凭借其跨平台特性和高性能推理能力,已成为工业界广泛采用的推理引擎。然而,随着其C API的迭代升级&a…...
DICOM RT Structure深度解析——从文件结构到靶区可视化
1. DICOM RT Structure文件基础认知 第一次接触DICOM RT Structure文件时,我完全被那些密密麻麻的标签和序列搞晕了。这就像拿到一份没有目录的医学百科全书,所有内容都堆在一起。但经过几个项目的实战,我发现只要抓住三个核心序列࿰…...
Vue+DataV+Echarts实战:从零搭建企业级数据可视化大屏(附完整代码)
1. 环境准备与项目初始化 数据可视化大屏开发的第一步是搭建基础开发环境。这里我推荐使用Vue CLI作为项目脚手架,它能帮我们快速初始化一个规范的Vue项目结构。先确保你的系统已安装Node.js(建议LTS版本),然后在终端执行以下命令…...
永磁同步电机矢量控制进阶:电流环前馈补偿的5个关键点与避坑指南
永磁同步电机矢量控制进阶:电流环前馈补偿的5个关键点与避坑指南 在工业伺服系统与新能源驱动领域,永磁同步电机(PMSM)凭借其高功率密度和动态响应特性占据主导地位。而电流环作为矢量控制的内环,其性能直接影响整个系…...
