# 后端开发日志规范

后端开发日志规范

日志的作用

故障排查和调试

  • 日志记录了系统运行过程中的各种事件、操作和错误信息,有助于开发人员快速定位和解决问题,提高系统的稳定性和可靠性。

性能监控和优化

  • 通过分析日志信息,可以了解系统的性能表现,包括请求响应时间、资源利用情况等,有助于发现性能瓶颈并进行优化。

安全审计和监控

  • 日志记录了系统的操作轨迹和访问记录,可以用于安全审计和监控,及时发现异常行为和安全漏洞。

用户行为分析

  • 通过分析用户的操作行为和访问记录,可以了解用户的偏好和行为习惯,为产品改进和优化提供参考。

什么时候记录日志

代码初始化时或进入逻辑入口时

  • 系统或者服务的启动参数。核心模块或者组件初始化过程中往往依赖一些关键配置,根据参数不同会提供不一样的服务。务必在这里记录INFO日志,打印出参数以及启动完成态服务表述。

编程语言提示异常

  • 这类捕获的异常是系统告知开发人员需要加以关注的,是质量非常高的报错。应当适当记录日志,根据实际结合业务的情况使用WARN或者ERROR级别。

业务流程预期不符

  • 项目代码中结果与期望不符时也是日志场景之一,简单来说所有流程分支都可以加入考虑。取决于开发人员判断能否容忍情形发生。常见的合适场景包括外部参数不正确,数据处理问题导致返回码不在合理范围内等等。

系统/业务核心逻辑的关键动作

  • 系统中核心角色触发的业务动作是需要多加关注的,是衡量系统正常运行的重要指标,建议记录INFO级别日志。

第三方服务远程调用

  • 微服务架构体系中有一个重要的点就是第三方永远不可信,对于第三方服务远程调用建议打印请求和响应的参数,方便在和各个终端定位问题,不会因为第三方服务日志的缺失变得手足无措。

日志记录原则

清晰性和一致性

  • 日志消息应该清晰、简洁,并且在格式上保持一致,以便开发人员更容易阅读和理解。

相关性

  • 只记录与故障排查、监控或审计相关的信息。避免记录敏感信息,如密码或个人数据。

日志级别

  • 适当使用不同的日志级别(如 DEBUGINFO、WARN、ERROR)来指示日志消息的严重程度。这有助于过滤和优先处理日志消息。

时间戳

  • 在日志消息中包含时间戳,以提供事件的时间顺序记录。这有助于理解操作的顺序和诊断问题。

上下文信息

  • 在日志消息中包含相关的上下文信息,如请求参数、用户ID和错误详情,以提供更多的调试上下文。

错误处理

  • 当发生异常时,记录详细的错误消息,包括堆栈跟踪。这些信息对于识别错误的根本原因至关重要。

性能影响

  • 注意日志记录对性能的影响。避免过度记录可能降低系统性能的日志信息。

日志轮换和保留

  • 实施日志轮换和保留策略,有效管理日志文件,并防止占用过多的磁盘空间。

日志等级设置规范

DEBUG(调试)

  • DEUBG级别的主要输出调试性质的内容,该级别日志主要用于在开发、测试阶段输出。该级别的日志应尽可能地详尽,开发人员可以将各类详细信息记录到DEBUG里,起到调试的作用,包括参数信息,调试细节信息,返回值信息等等,便于在开发、测试阶段出现问题或者异常时,对其进行分析。

INFO(信息)

  • INFO级别的主要记录系统关键信息,旨在保留系统正常工作期间关键运行指标,开发人员可以将初始化系统配置、业务状态变化信息,或者用户业务流程中的核心处理记录到INFO日志中,方便日常运维工作以及错误回溯时上下文场景复现。
  • 建议在项目完成后,在测试环境将日志级别调成INFO,然后通过INFO级别的信息看看是否能了解这个应用的运用情况,如果出现问题后是否这些日志能否提供有用的排查问题的信息。

WARN(警告)

  • WARN级别的主要输出警告性质的内容,这些内容是可以预知且是有规划的,比如,某个方法入参为空或者该参数的值不满足运行该方法的条件时。
  • WARN级别的时应输出较为详尽的信息,以便于事后对日志进行分析。

ERROR(错误)

  • ERROR级别主要针对于一些不可预知的信息,诸如:错误、异常等,比如,在catch块中抓获的网络通信、数据库连接等异常,若异常对系统的整个流程影响不大,可以使用WARN级别日志输出。
  • 在输出ERROR级别的日志时,尽量多地输出方法入参数、方法执行过程中产生的对象等数据,在带有错误、异常对象的数据时,需要将该对象一并输出。

TRACE(跟踪)

  • 用于记录非常详细的信息,有助于跟踪请求或操作在应用程序中的流程。跟踪消息比调试消息更为细致。

OFF(关闭)

  • 关闭所有日志记录。通常情况下不使用此级别,但可以在某些场景下设置为完全禁用日志记录。

日志使用实践

打印日志的代码不允许失败,阻断流程

  • 一定要确保不会因为日志打印语句抛出异常造成业务流程中断,如下图所示,shopnull的会导致抛出NPE
public void doSth(){
   
    log.info("do sth and print log: {}", shop.getId());
    // 业务逻辑
    ...
}

禁止使用System.out.println()输出日志

反例:

public void doSth(){
   
    System.out.println("doSth...");
    // 业务逻辑
    ...
}

分析:

  • 通过分析System.out.println源码可知,System.out.println是一个同步方法,在高并发的情况下,大量执行println方法会严重影响性能。
public void println(String x) {
   
    synchronized (this) {
   
        print(x);
        newLine();
    }
}
  • 不能实现日志按等级输出。具体来说就是不能和日志框架一样,有 debuginfoerror等级别的控制。
  • System.out、System.error打印的日志都并没有打印在日志文件中,而是直接打印在终端,无法对日志进行收集。

正例:

在日常开发或者调试的过程中,尽量使用标准日志记录系统log4j2或者logback(但不要直接使用其中的API),异步的进行日志统一收集。

public void doSth(){
   
    log.info("doSth...");
    // 业务逻辑
    ...
}

禁止直接使用日志系统(Log4j、Logback)中的API

  • 应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架 (SLF4J、JCL--Jakarta Commons Logging)中的API。

分析:

直接使用Log4j或者Logback中的API会导致系统代码实现强耦合日志系统,后续需要切换日志实现时会产生比较大的改造成本,统一使用SLF4J或者JCL等日志框架的API,其是使用门面模式的日志框架,可以做到解耦具体日志实现的作用,有利于后续维护和保证各个类的日志处理方式统一。

正例:

// 使用 SLF4J:
 import org.slf4j.Logger;
 import org.slf4j.<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值