zoukankan      html  css  js  c++  java
  • java中日志打印规范

    1.选择恰当的日志级别

    日常开发中常见日志级别有:trace、debug、info、warn、error(级别依次增大):
    1.trace:最详细的日志信息,一般记录到日志文件中
    2.debug:一般用于开发中DEBUG的关键逻辑的运行时数据
    3.info:记录排查问题的关键信息,如出参,入参等
    4.warn:警告日志,一般的错误,对正常业务影响不大,需要开发者关注
    5.error:错误日志,对正常业务有影响,需要运维配置日志监控

    2.日志要打印方法的入参和出参

    例如在Controller层,请求入参、响应出参和响应异常,一般需要打印日志,出问题时,方便追踪代码逻辑运行的路线。建议这里使用日志切面进行统一日志打印;

    其他层级的方法入参和出参,如有必要,可以打印整个出参和入参的数据,反之可以打印有效的关键日志,方便问题定位即可;

    3.日志格式

    一般日志中包含:时间、日志级别、线程名称、日志具体内容等

    %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger:%line - %msg%n

    4.在多个if-else等条件时,每个分支首行尽量打印日志

    可以在进入分支前打印日志,后续可以快速定位到进入了哪个分支,方便排查问题

    String requestNo = "RN7195458555001";
    String channel = "weixin";
    log.info("请求流水号[{}]支付处理,渠道为:{}", requestNo, channel);
    if (Objects.equals("zhifubao", channel)) {
        // TODO
    } else if (Objects.equals("yinlian", channel)) {
        // TODO
    } else if (Objects.equals("weixin", channel)) {
        // TODO
    } else {
        // TODO
    }

    5.日志级别比较低时,进行日志开关判断

    对于trace、debug级别的日志打印,需要进行开关判断

    if (log.isTraceEnabled()) {
        log.trace("trace log detail......");
    }
    if (log.isDebugEnabled()) {
        log.debug("debug log detail......");            
    }

    比如需要打印如下日志

    log.debug("Payment processing,requestNo=" + requestNo + ",channel=" + channel);

    当前配置的日志级别为info,则上面日志不会打印,但会进行字符串拼接;如果是对象,还会执行toString()方法,浪费了系统资源

    6.不要直接使用日志系统(Log4j、Logback)中的 API,而是使用日志框架SLF4J中的API

    SLF4J是门面模式的日志框架,需要更换日志框架实现时,在不改动代码的情况下,可以方便切换到不同的日志实现框架

    import org.slf4j.Logger; 
    import org.slf4j.LoggerFactory;
    
    private static final Logger logger = LoggerFactory.getLogger(Demo.class);

    // 或者使用Lombok @Slf4j

    7.建议使用参数占位{},而不是用+拼接

    反例:

    log.debug("Payment processing,requestNo=" + requestNo + ",channel=" + channel);

    字符串使用"+"进行拼接操作,会有一定的性能损耗,虽然高版本的jdk对字符串拼接进行了性能优化,但不建议使用

    正例:

    log.info("Payment processing,requestNo={},channel={}", requestNo, channel);

    使用大括号{}进行占位符的替换,相比字符串拼接,性能上更高,日志代码也更加优雅

    8.不要使用e.printStackTrace() 和 System.out.println();

    反例:

    try{
      // TODO 业务代码处理
    }catch(Exception e){
     //System.out.println("xxx业务处理异常,异常信息:" + e); e.printStackTrace(); }

    正例:

    try {
        // TODO 业务代码处理
    } catch (Exception e) {
        log.error("xxx业务处理异常 requestNo={}", requestNo, e);
    }
    e.printStackTrace()打印在堆栈信息中,如果异常过多,会导致堆栈内存不足,出现卡(运行极慢)的现象,最后出现OOM,这是一种非常糟糕的现象;
    使用log来打印日志会记录到日志文件中,占用的是磁盘内存,一般不会经常出现卡(运行极慢)的现象,但如果磁盘内存占用比较高时,需要对日志进行备份处理,然后清理日志;

    9.异常日志不要只打一半,要输出全部错误信息

    反例:

    log.error("xxx业务处理异常");
    log.error("xxx业务处理异常", e.getMessage());

    e.getMessage()不会记录详细的堆栈异常信息,只会记录错误基本描述信息,不利于排查问题。

    正例:

    log.error("xxx业务处理异常 requestNo={}", requestNo, e);

    10.禁止在线上环境开启 debug

    一般业务系统的debug日志较多,引入的第三方框架debug日志也较多,随着业务交易的增多,容易占用磁盘内存空间,最后可能会影响正常业务系统的运行

    ,所以生产环境禁止开启debug

    11.不要既打印了异常日志,又抛出异常

    try {
        // TODO 业务代码处理
    } catch (Exception e) {
        log.error("xxx业务处理异常", e);
        // BusinessException:自定义业务处理异常类
        throw new BusinessException("xxx业务处理异常", e);
    }

    此处会打印两次异常日志:

    第一次是log.error("xxx业务处理异常", e)会打印一次;
    第二次是throw new BusinessException("xxx业务处理异常", e)会打印一次;

    可以根据具体情况来选择,例如此处就应该抛异常处理,那么可以仅使用throw new BusinessException("xxx业务处理异常", e)即可

    12.避免重复打印日志

    如果一行日志可以表达清楚,则使用一行打印即可,避免日志信息冗余

    反例:

    log.info("创建用户信息 userId={}", userId);
    log.info("创建用户信息 userName={}", userName);

    正例:

    log.info("创建用户信息 userId={},userName={}", userId, userName);

    13.日志文件分离

    根据不同的日志级别,打印在不同的日志文件中,例如debug、info、warn、error日志级别的日志分别创建一个日志文件debug.log、info.log、warn.log、error.log进行日志打印;

    将不同类型的日志进行日志分类,例如access.log、error.log等

    14.核心功能模块,建议打印较完整的日志

    业务系统中,核心功能的代码,尽可能打印日志完整,核心代码执行频率极高,出问题时,根据日志信息能快速定位。

  • 相关阅读:
    CSS浮动(float、clear)通俗讲解
    JAVA 类的加载
    数据库操作 delete和truncate的区别
    正则表达式 匹配相同数字
    Oracle EBS OM 取消订单
    Oracle EBS OM 取消订单行
    Oracle EBS OM 已存在的OM订单增加物料
    Oracle EBS OM 创建订单
    Oracle EBS INV 创建物料搬运单头
    Oracle EBS INV 创建物料搬运单
  • 原文地址:https://www.cnblogs.com/lwcode6/p/15527912.html
Copyright © 2011-2022 走看看