log4j不打印详细错误堆栈

记一次排查问题时发现日志不打印详细堆栈的情况

 

文章目录

  • 背景
  • 现象
  • 解决

 

背景

调用打印日志的代码:

LOGGER.error("actionDetailBiz max monitorTime upload data error, ",  ex);

注意如果如下调用方式是不会打印堆栈的:

LOGGER.error("actionDetailBiz max monitorTime upload data error, msg:{} ",  ex.getMessage());
  • 使用Logger.error(e)、Logger.error(e.getMessage())、Logger.error(“some msg” + e)、Logger.error(“some msg” + e.getMessage()) 都是调用的error(Object message),这个方法都会将入参当作Object输出,不会打印堆栈信息。
  • 在使用Logger.error("first param ",e)时会调用error(String message, Throwable t),此方法会完整的打印出错误堆栈信息。
  • 细节参考:Logger.error方法之打印错误异常的详细堆栈信息

现象

以下是从服务器上捞下来的部分日志:

2019-06-12 00:00:06 068 [action-etl-main-thread-75:108382040] - [ERROR] com.x.action.handler.SDKStatHandler - actionDetailBiz config data error, 
java.lang.NullPointerException
2019-06-12 00:00:06 362 [action-etl-main-thread-69:108382334] - [ERROR] com.x.action.handler.SDKStatHandler - actionDetailBiz config data error, 
java.lang.NullPointerException
2019-06-12 00:00:06 732 [action-etl-main-thread-73:108382704] - [ERROR] com.x.action.handler.SDKStatHandler - actionDetailBiz config data error, 
java.lang.NullPointerException

一开始还以为是grep 没有把堆栈获取到,所以加了个 -A 10 发现结果还是一样,就是没有堆栈。

查多方资料后发现,这是jvm自身的优化,JVM 为了性能,如频繁的抛出某个异常,会重新编译,不再打印异常堆栈。此时要找堆栈就得到最开头去找了。。。可是最开头可能在几天前,可能日志早就被清理了

解决

启动参数加上 -XX:-OmitStackTraceInFastThrow禁用该优化,强制打印异常堆栈
当然这会损耗性能且日志过大咯

本人加了这个参数之后就可以看到详细堆栈了

2019-06-13 11:14:33 097 [action-etl-main-thread-2:32713] - [ERROR] com.x.action.handler.SDKStatHandler - actionDetailBiz max monitorTime upload data error, 
java.lang.NullPointerException
        at com.x.action.handler.SDKStatHandler.lambda$builderResults$1(SDKStatHandler.java:221)
        at java.util.HashMap.forEach(HashMap.java:1288)
        at com.x.action.handler.SDKStatHandler.builderResults(SDKStatHandler.java:219)
        at com.x.action.handler.SDKStatHandler.run(SDKStatHandler.java:141)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

 

 

 原文地址:https://blog.csdn.net/maoyuanming0806/article/details/91823290

你可能感兴趣的:(运维,log4j不打印详细错误堆栈)