xxl-job存在的问题
- 在定时器使用异步或者使用线程池来实现异步处理(比如有时远程调用会超时,像网关会设置超时的时间等等)在代码中打印日志不输出的问题。
接下来我们看下导致的原因
源码
XxlJobLogger.log
XxlJobFileAppender.contextHolder
InheritableThreadLocal为何物?
我在之前的博客已经有相应的讲解
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);
}
}
}