Skip to content

03 日志规约

  1. 【强制】 应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架(SLF4J、JCL—Jakarta Commons Logging)中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

    说明

    日志框架(SLF4J、JCL--Jakarta Commons Logging)的使用方式(推荐使用 SLF4J)

    • 使用 SLF4J:

      java
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      private static final Logger logger = LoggerFactory.getLogger(Test.class);
    • 使用 JCL:

      java
      import org.apache.commons.logging.Log;
      import org.apache.commons.logging.LogFactory;
      private static final Log log = LogFactory.getLog(Test.class);
  2. 【强制】 日志文件至少保存 15 天,因为有些异常具备以“周”为频次发生的特点。当天日志保存为 {应用名}.log,存放在 {统一目录}/{应用名}/logs/ 目录下,过往日志格式为 {logname}.log.{保存日期},日期格式:yyyy-MM-dd

    正例

    以 mppserver 应用为例,日志保存为 /home/admin/mppserver/logs/mppserver.log,历史日志名称为 mppserver.log.2021-11-28

  3. 【强制】 根据国家法律,网络运行状态、网络安全事件、个人敏感信息操作等相关记录的日志应至少留存六个月,并进行网络多机备份。

  4. 【强制】 应用中的扩展日志(如打点、临时监控、访问日志等)的命名方式应为:appName_logType_logName.log

    • logType:日志类型,如 stats / monitor / access 等;
    • logName:日志描述。

    这种命名的好处:通过文件名就可知道日志文件属于什么应用,什么类型,什么目的,也有利于归类查找。

    说明

    推荐对日志进行分类,将错误日志和业务日志分开放,便于开发人员查看,也便于通过日志对系统进行及时监控。

    正例

    mppserver 应用中单独监控时区转换异常,日志命名为 mppserver_monitor_timeZoneConvert.log

  5. 【强制】 日志输出时,字符串变量之间的拼接应使用占位符的方式。

    说明

    字符串拼接会使用 StringBuilderappend() 方法,有一定的性能损耗。而占位符替换仅是替换动作,可以有效提升性能。

    正例

    java
    logger.debug("Processing trade with id : {} and symbol : {}", id, symbol);
  6. 【强制】 对于 tracedebuginfo 级别的日志输出,必须进行日志级别的开关判断。

    说明

    虽然在 debug(参数) 的方法体内第一行代码 isDisabled(Level.DEBUG_INT) 为真时(Slf4j 的常见实现 Log4j 和 Logback),就直接 return,但是参数可能会进行字符串拼接运算。此外,如果 debug(getName()) 这种参数内有 getName() 方法调用,无谓浪费方法调用的开销。

    正例

    java
    // 如果判断为真,那么可以输出 trace 和 debug 级别的日志
    if (logger.isDebugEnabled()) {
        logger.debug("Current ID is: {} and name is: {}", id, getName());
    }
  7. 【强制】 避免重复打印日志,浪费磁盘空间,务必在日志配置文件中设置 additivity=false

    正例

    xml
    <logger name="com.taobao.dubbo.config" additivity="false">
  8. 【强制】 生产环境禁止使用 System.outSystem.err 输出日志,或使用 e.printStackTrace() 打印异常堆栈。

    说明

    标准日志输出与标准错误输出文件仅在 JBoss 重启时滚动,如果大量输出至这两个文件,容易造成文件大小超过操作系统大小限制。

  9. 【强制】 异常信息应包括两类信息:案发现场信息和异常堆栈信息。如果不处理异常,应通过关键字 throws 往上抛出。

    正例

    java
    logger.error("inputParams: {} and errorMessage: {}", 各类参数或者对象 toString(), e.getMessage(), e);
  10. 【强制】 日志打印时禁止直接使用 JSON 工具将对象转换为 String

    说明

    如果对象里某些 get 方法被覆写,存在抛出异常的情况,则可能会因为打印日志而影响正常业务流程的执行。

    正例

    打印日志时仅打印业务相关属性值或调用对象的 toString() 方法。

  11. 【推荐】 谨慎记录日志。生产环境禁止输出 debug 日志;有选择地输出 info 日志;如使用 warn 记录刚上线时的业务行为信息,应注意日志输出量,避免服务器磁盘撑爆,并及时删除这些观察日志。

    说明

    大量输出无效日志不利于系统性能提升,也不利于快速定位错误。记录日志时请思考:这些日志是否有实际意义?看到这条日志能做什么?是否有助于问题排查?

  12. 【推荐】 可使用 warn 日志级别记录用户输入参数错误的情况,避免用户投诉时无所适从。如非必要,请勿在此场景下打出 error 级别日志,以避免频繁报警。

    说明

    注意日志输出的级别,error 级别仅记录系统逻辑出错、异常或重要错误信息。

  13. 【推荐】 尽量使用英文描述日志错误信息;如英文描述不清楚则使用中文,否则容易产生歧义。

    说明

    国际化团队或海外部署的服务器可能因字符集问题,建议使用英文注释和描述日志错误信息。

  14. 【推荐】 为保护用户隐私,日志文件中的用户敏感信息应进行脱敏处理。

    说明

    在日志排查问题时,推荐使用订单号、UUID 之类的唯一编号进行查询。