那么多组件对MQ、Redis、鉴权等的封装着,每个组件都需要打印日志,组件日志与业务日志混合在一起,干扰业务排查问题。组件日志主要是为了排查问题,组件打印的日志也没有必要被收集到SLS、ELK上等。
主要解决两个问题:
这里会有同学说,我在配置一个logj2文件,其实是不行的。Log4j2为应用程序提供了几种创建自己的编程配置的方法:
这里说一下第四种:有时你使用配置文件进行配置,但需要进行一些额外的编程配置。一个可能的用例可能是,您希望允许使用XML进行灵活的配置,但同时确保始终存在一些无法删除的业务配置元素。实现这一点的最简单方法是扩展其中一个标准配置类(XmlConfiguration、JSONConfiguration),然后为扩展类创建一个新的ConfigurationFactory。标准配置完成后,可以向其中添加自定义配置。
下面的示例显示了如何扩展XmlConfiguration以手动将Appender和LoggerConfig添加到配置中。
Plugin(name = "MyXmlConfigurationFactory", category = "ConfigurationFactory")
@Order(10)
public class MyXmlConfigurationFactory extends ConfigurationFactory {
/**
* Valid file extensions for XML files.
*/
public static final String[] SUFFIXES = new String[]{".xml", "*"};
/**
* Return the Configuration.
*
* @param source The InputSource.
* @return The Configuration.
*/
public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) {
return new MyXmlConfiguration(loggerContext, source);
}
/**
* Returns the file suffixes for XML files.
*
* @return An array of File extensions.
*/
public String[] getSupportedTypes() {
return SUFFIXES;
}
}
public class MyXmlConfiguration extends XmlConfiguration {
public MyXmlConfiguration(final LoggerContext loggerContext, final ConfigurationSource configSource) {
super(loggerContext, configSource);
}
@Override
protected void doConfigure() {
super.doConfigure();
final LoggerContext context = (LoggerContext) LogManager.getContext(false);
final Configuration config = context.getConfiguration();
final Layout layout = PatternLayout.createDefaultLayout(config);
final Appender fileAppender = FileAppender.newBuilder().setName("target/test.log").withFileName("File")
.withImmediateFlush(true).setIgnoreExceptions(false).withBufferedIo(false).withBufferSize(4000)
.setLayout(layout).withAdvertise(false).setConfiguration(config)
.build();
fileAppender.start();
addAppender(fileAppender);
AppenderRef[] refs = new AppenderRef[]{AppenderRef.createAppenderRef(fileAppender.getName(), null, null)};
LoggerConfig loggerConfig = LoggerConfig.createLogger(false, Level.INFO, "org.apache.logging.log4j",
"true", refs, null, config, null);
loggerConfig.addAppender(fileAppender, null, null);
addLogger("org.apache.logging.log4j", loggerConfig);
}
}
主要思路就是通过显示编码的方式在log4j2初始化配置的时候,加入自己的单独配置,兼容业务配置,而且对业务无感。本解决思路比较简单,但收益巨大,避免干扰业务日志,减少存储成本。
参考资料:
log4j2 Programmatic Configuration: https://logging.apache.org/log4j/2.x/manual/customconfig.html