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…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
