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);

在反例中,使用字符串拼接会导致性能损耗,尤其是在日志级别较高时(如INFOWARN)。


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);

在反例中,使用中文描述日志错误信息,可能导致国际化团队难以理解。


总结

通过遵循日志规约的最佳实践,开发者可以编写出高效、易维护的日志代码。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/68959.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动化软件测试的基本流程

一、自动化测试的准备 1.1 了解测试系统 首先对于需要测试的系统我们需要按照软件需求说明书明确软件功能。这里以智慧养老系统作为案例进行测试&#xff0c;先让我们看看该系统的登录界面和用户管理界面。 登录界面&#xff1a; 登录成功默认界面&#xff1a; 用户管理界面…

Windows电脑本地部署运行DeepSeek R1大模型(基于Ollama和Chatbox)

文章目录 一、环境准备二、安装Ollama2.1 访问Ollama官方网站2.2 下载适用于Windows的安装包2.3 安装Ollama安装包2.4 指定Ollama安装目录2.5 指定Ollama的大模型的存储目录 三、选择DeepSeek R1模型四、下载并运行DeepSeek R1模型五、常见问题解答六、使用Chatbox进行交互6.1 …

计算机网络中常见高危端口有哪些?如何封禁高危端口?

保障网络安全&#xff0c;从封禁高危端口开始&#xff01; 在计算机网络中&#xff0c;端口是设备与外界通信的“大门”&#xff0c;但某些端口因常被黑客利用而成为高危入口。封禁这些端口是防御网络攻击的关键一步。本文将详解 10个常见高危端口&#xff0c;并提供多平台封禁…

CommonJS

CommonJS 是由 JavaScript 社区于 2oo9 年提出的包含模块、文件、IO、控制台在内的一系列标准。Node.js 的实现中采用了 CommonJS 标准的一部分&#xff0c;并在其基础上进行了一些调整。我们所说的 CommonJS 模块和 Node.js 中的实现并不完全一样&#xff0c;现在一般谈到 Com…

[SAP ABAP] ABAP SQL跟踪工具

事务码ST05 操作步骤 步骤1&#xff1a;使用事务码ST05之前&#xff0c;将要检测的程序生成的页面先呈现出来&#xff0c;这里我们想看下面程序的取数操作&#xff0c;所以停留在选择界面 步骤2&#xff1a; 新建一个GUI窗口&#xff0c;输入事务码ST05&#xff0c;点击 Acti…

蓝桥杯备考:高精度算法之除法

我们除法的高精度其实也不完全是高精度&#xff0c;而是一个高精度作被除数除以一个低精度 模拟我们的小学除法 由于题目中我们的除数最大是1e9&#xff0c;当它真正是1e9的时候&#xff0c;t是有可能超过1e9的&#xff0c;所以要用long long

算法竞赛(Python)-堆栈

文章目录 一 基础知识二 题目有效的括号字符串解码 一 基础知识 堆栈&#xff08;Stack&#xff09;&#xff1a;简称为栈。一种线性表数据结构&#xff0c;是一种只允许在表的一端进行插入和删除操作的线性表。   我们把栈中允许插入和删除的一端称为 「栈顶&#xff08;top…

SpringBoot 中的测试jar包knife4j(实现效果非常简单)

1、效果图 非常快的可以看见你实现的接口 路径http://localhost:8080/doc.html#/home 端口必须是自己的 2、实现效果 2.1、导入jar包 <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-jakarta-spring-boot-star…

16.1.STM32F407ZGT6-CAN基础概念

参考&#xff1a; https://blog.csdn.net/sunlight_vip/article/details/128639144 前言&#xff1a; 学习总结CAN的知识点&#xff1a; 1.can是什么&#xff0c;历史由来和背景 2.can的物理层&#xff0c;链路层 3.初始化的流程和关键点 4.波特率怎么设置 5.can id怎么过滤 6…

Linux环境下的Java项目部署技巧:Nginx 详解

Nginx 的启动 Nginx 启动会生成 2 个进程&#xff1a;主进程与守护进程 主进程&#xff1a;常用于提供反向代理服务。特点&#xff1a;占内存大守护进程&#xff1a;防止主进程以外关闭。特点&#xff1a;占内存小 Nginx 启动需要占用 80 端口: 当 Ngnix 启动失败时&#xff0…

【Pytorch和Keras】使用transformer库进行图像分类

目录 一、环境准备二、基于Pytorch的预训练模型1、准备数据集2、加载预训练模型3、 使用pytorch进行模型构建 三、基于keras的预训练模型四、模型测试五、参考 现在大多数的模型都会上传到huggface平台进行统一的管理&#xff0c;transformer库能关联到huggface中对应的模型&am…

relational DB与NoSQL DB有什么区别?该如何选型?

Relational Database(关系型数据库,简称RDB)与NoSQL Database(非关系型数据库)是两类常见的数据库类型。它们在设计理念、数据存储方式、性能优化、扩展性等方面有许多差异。下面我们将会详细分析它们的区别,以及如何根据应用场景进行选型。 一、数据模型的区别 关系型…

Flutter常用Widget小部件

小部件Widget是一个类&#xff0c;按照继承方式&#xff0c;分为无状态的StatelessWidget和有状态的StatefulWidget。 这里先创建一个简单的无状态的Text小部件。 Text文本Widget 文件&#xff1a;lib/app/app.dart。 import package:flutter/material.dart;class App exte…

智能小区物业管理系统推动数字化转型与提升用户居住体验

内容概要 在当今快速发展的社会中&#xff0c;智能小区物业管理系统的出现正在改变传统的物业管理方式。这种系统不仅仅是一种工具&#xff0c;更是一种推动数字化转型的重要力量。它通过高效的技术手段&#xff0c;将物业管理与用户居住体验紧密结合&#xff0c;无疑为社区带…

给AI加知识库

1、加载 Document Loader文档加载器 在 langchain_community. document_loaders 里有很多种文档加载器 from langchain_community. document_loaders import *** 1、纯文本加载器&#xff1a;TextLoader&#xff0c;纯文本&#xff08;不包含任何粗体、下划线、字号格式&am…

游戏引擎 Unity - Unity 设置为简体中文、Unity 创建项目

Unity Unity 首次发布于 2005 年&#xff0c;属于 Unity Technologies Unity 使用的开发技术有&#xff1a;C# Unity 的适用平台&#xff1a;PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域&#xff1a;开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…

小红的小球染色期望

B-小红的小球染色_牛客周赛 Round 79 题目描述 本题与《F.R小红的小球染色期望》共享题目背景&#xff0c;但是所求内容与范围均不同&#xff0c;我们建议您重新阅读题面。 有 n 个白色小球排成一排。小红每次将随机选择两个相邻的白色小球&#xff0c;将它们染成红色。小红…

ASP.NET Core与配置系统的集成

目录 配置系统 默认添加的配置提供者 加载命令行中的配置。 运行环境 读取方法 User Secrets 注意事项 Zack.AnyDBConfigProvider 案例 配置系统 默认添加的配置提供者 加载现有的IConfiguration。加载项目根目录下的appsettings.json。加载项目根目录下的appsettin…

Redis集群理解以及Tendis的优化

主从模式 主从同步 同步过程&#xff1a; 全量同步&#xff08;第一次连接&#xff09;&#xff1a;RDB文件加缓冲区&#xff0c;主节点fork子进程&#xff0c;保存RDB&#xff0c;发送RDB到从节点磁盘&#xff0c;从节点清空数据&#xff0c;从节点加载RDB到内存增量同步&am…

沙皮狗为什么禁养?

各位铲屎官们&#xff0c;今天咱们来聊聊一个比较敏感的话题&#xff1a;沙皮狗为什么会被禁养&#xff1f;很多人对沙皮狗情有独钟&#xff0c;但有些地方却明确禁止饲养这种犬种&#xff0c;这背后到底是什么原因呢&#xff1f;别急&#xff0c;今天就来给大家好好揭秘&#…