是这样的,最近我在调研xxl-job
的使用,想把它整合到自己的项目工程中。
整合得很顺利,没什么问题,但在使用上出现了一个小小的繁琐,就是日志的输出
@Slf4j
@Component
public class SampleTask {
@XxlJob("demoJobHandler")
public void demoJobHandler() throws Exception {
XxlJobHelper.log("XXL-JOB, Hello World.");
for (int i = 0; i < 5; i++) {
XxlJobHelper.log("beat at:{}", i);
log.info("beat at:{}", i);
TimeUnit.SECONDS.sleep(2);
}
}
}
看到是什么问题了吗,没错就是日志的输出,我写了两次。
至于为什么写两次,纯属无奈之举,一个是logback
日志的打印,一个xxl-job
自己的日志
有没有什么办法,能只写一次就行的呢?
在logback
中,我们可以自己编写filter
来对日志等信息进行过滤。
所以,我们只需要在filter
中写上,一些逻辑判断,就可以实现日志往xxl-job
中打印了
package com.banmoon.filter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
import com.xxl.job.core.context.XxlJobContext;
import com.xxl.job.core.context.XxlJobHelper;
import java.util.Objects;
public class XxlJobLogFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
// 判断是否处于xxl-job上下文中
if (Objects.nonNull(XxlJobContext.getXxlJobContext())) {
XxlJobHelper.log(event.getFormattedMessage());
}
return FilterReply.NEUTRAL;
}
}
然后,再将这个过滤器指定放在我们的CONSOLE
输出中(片段代码)
<?xml version="1.0" encoding="UTF-8"?>
<included>
<!-- 输出到控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出编码格式化 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>${LOG_FORMAT_ONE}</Pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="com.banmoon.filter.XxlJobLogFilter"/>
</appender>
</included>
这样的话就可以实现,只需要一个log.info()
就能在xxl-job
的日志打印了
其实到上面一步,已经能实现了。
但由于我项目工程的设计,我的logback
配置文件,根本就不是同一个工程,我不能直接将filter
写入CONSOLE
。
这是我项目的结构,banmoon-common-core
包完全不知道项目有没有引用banmoon-xxl-job-client
,也就不知道里面有没有filter
了。
对于上面这种情况,我想了想,能不能从其他方面进行入手呢?
比如说AOP
,但我看到logback
中的Logger
是final
类,顿时就无语了。
没办法,只能想想其他办法了
后面我看到了一个新的解决思路,就是获取到CONSOLE
的ConsoleAppender
,直接往里面塞一个XxlJobLogFilter
不就可以了
package com.banmoon.config;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import com.banmoon.filter.XxlJobLogFilter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import static org.slf4j.Logger.ROOT_LOGGER_NAME;
@Slf4j
@Configuration
public class XxlJobConfig {
@PostConstruct
public void init() {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logger = context.getLogger(ROOT_LOGGER_NAME);
Appender<ILoggingEvent> console = logger.getAppender("CONSOLE");
XxlJobLogFilter filter = new XxlJobLogFilter();
console.addFilter(filter);
}
}
当项目启动的时候,就会去找ConsoleAppender
,这样后面打印的日志就会经过这个过滤器。