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…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
