xxl-job异步不打印日志解决方案

文章目录

  • xxl-job存在的问题
  • 源码
    • InheritableThreadLocal为何物?
  • 解决方案

xxl-job存在的问题

  • 在定时器使用异步或者使用线程池来实现异步处理(比如有时远程调用会超时,像网关会设置超时的时间等等)在代码中打印日志不输出的问题。

接下来我们看下导致的原因

源码

XxlJobLogger.log

xxl-job异步不打印日志解决方案_第1张图片

xxl-job异步不打印日志解决方案_第2张图片
XxlJobFileAppender.contextHolder

xxl-job异步不打印日志解决方案_第3张图片

InheritableThreadLocal为何物?

我在之前的博客已经有相应的讲解

  • 初识TransmittableThreadLocal

InheritableThreadLocal为父子线程传递,就是如果你在当前线程下创建新的线程,它在创建线程的过程会把当前线程的变量copy到子线程里面。这种情况是可以打印出日志的。

另一种情况是你使用了自己定义的线程池,进行异步处理事务。

解决方案

1.在创建线程的时候,XxlJobFileAppender.contextHolder.set()一下日志文件名称。

2.重写一下打印日志的代码,避免同事失误打印不出来日志,下面大概写下思路,具体还没去验证,凑合着看下,嘻嘻~

public class XxlJobLoggerChild extends XxlJobLogger {

    public static final TransmittableThreadLocal<String> contextHolder = new TransmittableThreadLocal<>();

    private static Logger logger = LoggerFactory.getLogger("xxl-job logger");

    public static void log(String appendLogPattern, Object... appendLogArguments) {
        FormattingTuple ft = MessageFormatter.arrayFormat(appendLogPattern, appendLogArguments);
        String appendLog = ft.getMessage();
        StackTraceElement callInfo = (new Throwable()).getStackTrace()[1];
        logDetail(callInfo, appendLog);
    }

    @PostConstruct
    public void someMethod() {
        contextHolder.set(XxlJobFileAppender.contextHolder.get());
    }

    private static void logDetail(StackTraceElement callInfo, String appendLog) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(DateUtil.formatDateTime(new Date())).append(" ").append("[" + callInfo.getClassName() + "#" + callInfo.getMethodName() + "]").append("-").append("[" + callInfo.getLineNumber() + "]").append("-").append("[" + Thread.currentThread().getName() + "]").append(" ").append(appendLog != null ? appendLog : "");
        String formatAppendLog = stringBuffer.toString();
        String logFileName = contextHolder.get();
        if (logFileName != null && logFileName.trim().length() > 0) {
            XxlJobFileAppender.appendLog(logFileName, formatAppendLog);
        } else {
            logger.info(">>>>>>>>>>> {}", formatAppendLog);
        }

    }

}

你可能感兴趣的:(xxl-job异步不打印日志解决方案)