美文网首页
logback不传throwable参数也会打印堆栈

logback不传throwable参数也会打印堆栈

作者: 望穿天堂 | 来源:发表于2019-12-13 15:11 被阅读0次
    private static final Logger LOG = LoggerFactory.getLogger(Test.class);
    
    LOG.error("exec error,msg={}", msg, e);
    

    我们可以看到以上语句调用的是slf4j的这个方法:

    void error(String var1, Object var2, Object var3);
    

    参数里面并没有Throwable类型的,但是在实际运行的时候是会打印堆栈的,那么为什么会打印堆栈呢?我们来看logback的源码:

    public void error(String format, Object arg1, Object arg2) {
            this.filterAndLog_2(FQCN, (Marker)null, Level.ERROR, format, arg1, arg2, (Throwable)null);
    }
    
    private void filterAndLog_2(String localFQCN, Marker marker, Level level, String msg, Object param1, Object param2, Throwable t) {
            FilterReply decision = this.loggerContext.getTurboFilterChainDecision_2(marker, this, level, msg, param1, param2, t);
            if (decision == FilterReply.NEUTRAL) {
                if (this.effectiveLevelInt > level.levelInt) {
                    return;
                }
            } else if (decision == FilterReply.DENY) {
                return;
            }
    
            this.buildLoggingEventAndAppend(localFQCN, marker, level, msg, new Object[]{param1, param2}, t);
    }
    
    private void buildLoggingEventAndAppend(String localFQCN, Marker marker, Level level, String msg, Object[] params, Throwable t) {
            LoggingEvent le = new LoggingEvent(localFQCN, this, level, msg, t, params);
            le.setMarker(marker);
            this.callAppenders(le);
    }
    
    public LoggingEvent(String fqcn, Logger logger, Level level, String message, Throwable throwable, Object[] argArray) {
            this.fqnOfLoggerClass = fqcn;
            this.loggerName = logger.getName();
            this.loggerContext = logger.getLoggerContext();
            this.loggerContextVO = this.loggerContext.getLoggerContextRemoteView();
            this.level = level;
            this.message = message;
            this.argumentArray = argArray;
            if (throwable == null) {
                throwable = this.extractThrowableAnRearrangeArguments(argArray);
            }
    
            if (throwable != null) {
                this.throwableProxy = new ThrowableProxy(throwable);
                LoggerContext lc = logger.getLoggerContext();
                if (lc.isPackagingDataEnabled()) {
                    this.throwableProxy.calculatePackagingData();
                }
            }
    
            this.timeStamp = System.currentTimeMillis();
    }
    

    追到这里,我们看到这样一段代码

    if (throwable == null) {
                throwable = this.extractThrowableAnRearrangeArguments(argArray);
            }
    

    当throwable为null时,extractThrowableAnRearrangeArguments这个方法的名字已经写得很清楚了,我们继续往下看

    private Throwable extractThrowableAnRearrangeArguments(Object[] argArray) {
            Throwable extractedThrowable = EventArgUtil.extractThrowable(argArray);
            if (EventArgUtil.successfulExtraction(extractedThrowable)) {
                this.argumentArray = EventArgUtil.trimmedCopy(argArray);
            }
    
            return extractedThrowable;
    }
    
    public static final Throwable extractThrowable(Object[] argArray) {
            if (argArray != null && argArray.length != 0) {
                Object lastEntry = argArray[argArray.length - 1];
                return lastEntry instanceof Throwable ? (Throwable)lastEntry : null;
            } else {
                return null;
            }
    }
    

    好了,关键就在这一句

    return lastEntry instanceof Throwable ? (Throwable)lastEntry : null;
    

    个人非常反对这种写法emmm...大家不要学

    相关文章

      网友评论

          本文标题:logback不传throwable参数也会打印堆栈

          本文链接:https://www.haomeiwen.com/subject/qkvfnctx.html