log日志输出规范

4 篇文章 0 订阅
2 篇文章 0 订阅

目录

 

1、Log的用途

2、记录Log日志的基础原则

2.1、日志级别划分

2.2、日志对性能的影响

2.3、什么时候输出日志

2.3.1、系统启动参数、环境变量

2.3.2、异常捕获

2.3.3、函数获得期望之外的结果时

2.3.4、关键操作

2.4 日志输出的内容

3 日志API规范

3.1 Log对象的声明和初始化

3.2 不得使用System.out, System.err进行日志记录,请改使用logger.debug、logger.error

3.3 正确的记录异常信息

3.4 重要方法入口,业务流程前后及处理的结果等,推荐记录log,并使用debug级别

3.5 不允许记录日志后又抛出异常,因为这样会多次记录日志,只允许记录一次日志。

3.6 Log的内容一定要确保不会因为Log语句的问题而抛出异常造成中断


1、Log的用途

不管是使用何种编程语言,日志输出几乎无处不在。总结起来,日志大致有以下几种用途:

  • 问题跟踪:通过日志不仅仅包括我们程序的一些bug,也可以在安装配置时,通过日志可以发现问题。
  • 状态监控:通过实时分析日志,可以监控系统的运行状态,做到早发现问题,早处理问题。
  • 安全审计:审计主要体现在安全方面上,通过日志进行分析,可以发现是否存在非授权的操作。

2、记录Log日志的基础原则

2.1、日志级别划分

Java日志通常可以分为:error、warn、info、debug、trace五个级别。

  • error:问题已经影响到软件的正常运行,并且软件不能自行恢复到正常的运行状态,此时需要输出该级别的错误日志。
  • warn:与业务处理相关的失败,此次失败不影响下次业务的正常执行,通常的结果为外部的输入不能获得期望的结果。
  • info:系统运行期间的系统运行状态变化,或者关键业务处理记录等,用户或者管理员在系统操作运行期间关注的一些信息。
  • debug:软件调试信息,开发人员使用该级别的日志发现程序运行中的一些问题,排查故障。
  • trace:基本同上,但是显示的信息更详尽。

2.2、日志对性能的影响

不管多么优秀的日志工具,在日志输出时总会对性能产生或多或少的影响,为了将影响降到对低,有以下几个准则需要遵守:

  • 如何创建Logger实例:创建Logger实例有是否static区别,在log4j的早期版本中,一般会要求使用static,而在高版本以及后来的slf4j中,该问题已经得到优化,获取(创建)logger实例的成本已经很低。所以我们要求:对于可以预见的多数情况下单例运行的class,可以不添加static前缀;对于可能是多例居多,尤其是需要频繁创建的class,要求添加static前缀
  • 判断日志级别:对于可以预见的会频繁产生的日志输出,比如for、while循环,定期执行的job等,建议先使用if对日志级别进行判断后再输出。对于日志输出内容需要复杂的序列化,或输出的某些信息获取成本较高时,需要对日志级别进行判断。比如日志中需要输出用户名,而用户名需要在日志输出时从数据库获取,此时就需要先判断一下日志级别,看看是否有必要获取这些信息。
  • 优先使用参数,减少字符串拼接:使用参数的方式输出日志信息,有助于在性能和代码简洁之间取得平衡。当日志级别限制输出该日志时,参数内容将不会融合到最终输出中,减少了字符串的拼接,从而提升执行效率。

2.3、什么时候输出日志

日志并不是越多越详细就越好。在分析运行日志,查找问题时,我们经常遇到该出现的日志没有,无用的日志一大堆,或者有效的日志被大量无意义的日志信息淹没,查找起来非常困难。那么什么时候输出日志呢?以下列出了一些常见的需要输出日志的情况,而且日志的级别基本都是>=INFO,至于Debug级别日志的使用场景,需要具体情况具体分析,但也是要追求“恰如其分”,不是越多越好。

2.3.1、系统启动参数、环境变量

系统启动的参数、配置、环境变量、System.Properties等信息对于软件的正常运行至关重要,这些信息的输出有助于安装配置人员通过日志快速定位问题,所以程序有必要在启动过程中把使用到的关键参数、变量在日志中输出出来。在输出时需要注意,不是一股脑的全部输出,而是将软件运行涉及到的配置信息输出出来。比如,如果软件对jvm的内存参数比较敏感,对最低配置有要求,那么就需要在日志中将-Xms -Xmx -XX:PermSize这几个参数的值输出出来。

2.3.2、异常捕获

在捕获异常处输出日志,大家在基本都能做到,唯一需要注意的是怎么输出一个简单明了的日志信息。这在后面的问题问题中有进一步说明。

2.3.3、函数获得期望之外的结果时

一个函数,尤其是供外部系统或远程调用的函数,通常都会有一个期望的结果,但如果内部系统或输出参数发生错误时,函数将无法返回期望的正确结果,此时就需要记录日志,日志的基本通常是warn。需要特别说明的是,这里的期望之外的结果不是说没有返回就不需要记录日志了,也不是说返回false就需要记录日志。比如函数:isXXXXX(),无论返回true、false记录日志都不是必须的,但是如果系统内部无法判断应该返回true还是false时,就需要记录日志,并且日志的级别应该至少是warn。

2.3.4、关键操作

关键操作的日志一般是INFO级别,如果数量、频度很高,可以考虑使用DEBUG级别。以下是一些关键操作的举例,实际的关键操作肯定不止这么多。

n 删除:删除一个文件、删除一组重要数据库记录……

n 添加:和外系统交互时,收到了一个文件、收到了一个任务……

n 处理:开始、结束一条任务……

n ……

2.4 日志输出的内容

  •  ERROR:错误的简短描述,和该错误相关的关键参数,如果有异常,要有该异常的StackTrace。
  •  WARN:告警的简短描述,和该错误相关的关键参数,如果有异常,要有该异常的StackTrace。
  •  INFO:言简意赅地信息描述,如果有相关动态关键数据,要一并输出,比如相关ID、名称等。
  •  DEBUG:简单描述,相关数据,如果有异常,要有该异常的StackTrace。

在日志相关数据输出的时要特别注意对敏感信息的保护,比如修改密码时,不能将密码输出到日志中。 

 

3 日志API规范

3.1 Log对象的声明和初始化

// (推荐)

private static final Logger logger = LoggerFactory.getLogger(Xxx.class);

 

private final Logger logger = LoggerFactory.getLogger(getClass());

 

private  static  final Logger logger =  LoggerFactory.getLogger("loggerName");

 

private static Logger logger = LoggerFactory.getLogger(Xxx.class);

 

protected final Logger logger = LoggerFactory.getLogger(getClass());

 

private Logger logger = LoggerFactory.getLogger(getClass());

 

protected Logger logger = LoggerFactory.getLogger(getClass());

3.2 不得使用System.out, System.err进行日志记录,请改使用logger.debug、logger.error

3.3 正确的记录异常信息

输出Exceptions的全部Throwable信息,因为logger.error(msg)和logger.error(msg,e.getMessage())这样的日志输出方法会丢失掉最重要的StackTrace信息。

try {   

    Integer x = null;

    ++x;

} catch (Exception e) {

    //错误

    log.error(e);       

 

    //错误

    log.error(e, e);       

 

    //错误

    log.error(""+ e);       

 

    //错误

    log.error(e.toString());       

 

    //错误

    log.error(e.getMessage());       

 

    //错误

    log.error(null, e);       

 

    //不推荐

    log.error("", e);       

 

    //错误

    log.error("{}", e);       

 

    //错误

    log.error("{}", e.getMessage());     

   

     //错误

     log.error("Error reading configuration file: " + e);       

 

    //错误

    log.error("Error reading configuration file: "+ e.getMessage());       

 

    //推荐

    log.error("Error reading configuration file", e);

}

3.4 重要方法入口,业务流程前后及处理的结果等,推荐记录log,并使用debug级别

3.5 不允许记录日志后又抛出异常,因为这样会多次记录日志,只允许记录一次日志。

void foo() throws LogException{

    try{

        // do something

    }catch (Exception e){

        log.error("bad things",e);//错误

        throws new LogException("bad things",e);

    }

}

3.6 Log的内容一定要确保不会因为Log语句的问题而抛出异常造成中断

 

在使用MyBatis-Plus时,可以通过配置来控制日志输出。有两种方式可以实现这一点。第一种方式是在mybatis-plus的配置文件中设置日志实现类为org.apache.ibatis.logging.stdout.StdOutImpl。这样就会将日志输出到控制台上。\[1\]第二种方式是在application.yml文件中增加配置,指定mapper文件所在的包,并设置日志级别为debug。这样就可以控制mybatis-plus的日志输出级别。\[2\]另外,还可以使用yml规范的写法来配置日志输出。例如,可以将日志输出logs/sys.log文件中,并设置cn.shangze.boot.modules.oa.mapper包下的日志级别为debug。\[3\] #### 引用[.reference_title] - *1* *2* [mybatis-plus配置log4j2进行日志输出](https://blog.csdn.net/evalsys/article/details/106060257)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [springboot+mybatis-plus在log控制台输出sql语句的方法](https://blog.csdn.net/FengRenYuanDeFZ/article/details/101060423)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值