简版日志规范及常见问题

日志规范

1、日志级别

我们使用4个日志级别,分别为DEBUGINFOWARNERROR

DEBUG:可以将各类详细信息记录到DEBUG里,起到调试的作用,包括参数信息,调试细节信息,返回值信息等等。

INFO:记录系统关键信息,旨在保留系统正常工作期间关键运行指标,开发人员可以将初始化系统配置、业务状态变化信息,或者用户业务流程中的核心处理记录到INFO日志中,方便日常运维工作以及错误回溯时上下文场景复现。

WARN:系统在业务处理时触发了异常流程,但系统可恢复到正常态,下一次业务可以正常执行。

ERROR:打印ERROR日志意味着,程序(当前线程)不知道如何进行下去,提示需要人工检车和干预了,系统需要将错误或异常细节记录ERROR日志中,方便后续人工回溯解决。所有打印ERROR日志时,也业务数据信息打印越详细越好。

2、重要方法入口打印日志

建议记录方法调用、入参、返回值,对于排查问题会有很大帮助。

3、打印日志的代码任何情况下都不允许失败

一定要确保不会因为Log语句的问题而抛出异常造成中断。如下,如果request为null,就会抛空指针异常

`logger.info(``"execute fail id={}"``,request.getId());`

4、打印业务数据

日志打印时需要的两个重要的因素就是:数据,与事件, 所以在打印日志时,需要体现业务数据。

`logger.error(``"发送微信失败! message={} userId={}"``, message(), userId, e);`

补充说明:

1、推荐使用参数占位符{}。

2、异常 e 不能使用占位符。

如上面的例子,两个业务数据, message 与userId,使用了两个占位符。异常 e 则不需要使用占位符,并且作为最后一个参数。

5、有异常时,一定打印Exception异常堆栈信息

如下例子中,第一个条就将异常栈信息丢失了。 第二条 则能打印堆栈出异常信息。

logger.error("handle error "+e.getMessage()));
logger.error("handle error", e));

补充说明:

1 谁处理谁打印, 我们有时会遇到Exception, 我们catch exception 后又包装成一个新的Exception,然后再次抛出,这里其实不算处理,所以这是不需要打印日志。在真正处理异常时,打印这个异常信息。

2 在包装Exception时,不能将原始的Exception(cause)丢失。需要将原始的异常作为构建新Exception构造方法的参数。

常见日志问题

  1. 基本不打印日志。

  2. 日志不有打印业务数据,比如订单号。

  3. 出现异常时没有打印异常堆栈信息。

  4. 日志级别打印不对,该打印info时打成了error, 改打印error的打成了info。

  5. 日志打印太多, 日志也是有开销的,打印太多的日志影响性能,比如在for循环(循环很多次中)中打印日志。

  6. 打印日志导致空指针异常。

  7. 不同的地方日志信息一模一样,这个问题,会导致在定位问题时,不能尽快定位日志是哪里代码打印出来的。特别是同一个类中多个地方的日志信息一样。

你可能感兴趣的:(简版日志规范及常见问题)