Spring Boot中如何编程式为现有Log4j2配置添加JDBC Appender
Spring Boot中编程式扩展Log4j2配置并触发更新
首先吐个槽:
我翻了无数次Log4j2的文档,根本找不到解决方案。文档过时,示例代码脱离上下文还没解释,说明也不充分。框架本来是给开发者减负的,结果只有Log4j2自己的开发者才能用好,这太离谱了。不多说了。
实际问题
我有个Spring Boot应用,主要用YAML配置,但DataSource是编程式创建的,方便获取Bean实例。初始的Log4j2配置也是YAML:
Configuration: name: Default status: warn Appenders: Console: name: Console target: SYSTEM_OUT PatternLayout: pattern: "%d{yyyy-MM-dd HH:mm:ss} %-5level [%t] %c: %msg%n" Loggers: Root: level: warn AppenderRef: - ref: Console Logger: - name: com.example level: debug additivity: false AppenderRef: - ref: Console
现在我想编程式扩展初始配置,用已有的连接池添加一个JDBC Appender。根据Log4j2文档推荐,要扩展标准Configuration类,重写setup方法添加自定义组件。
我写了继承YamlConfiguration的自定义Log4j2Configuration类:
public class Log4j2Configuration extends YamlConfiguration { /* private final Log4j2ConnectionSource connectionSource; */ // <-- 需要注入 public Log4j2Configuration(LoggerContext loggerContext, ConfigurationSource configSource) { super(loggerContext, configSource); } @Override public void setup() { super.setup(); } @Override protected void doConfigure() { super.doConfigure(); LoggerContext context = (LoggerContext) LogManager.getContext(false); Configuration config = context.getConfiguration(); ColumnConfig[] columns = new ColumnConfig[]{ //... }; Appender jdbcAppender = JdbcAppender.newBuilder() .setName("DataBase") .setTableName("application_log") // .setConnectionSource(connectionSource) .setColumnConfigs(columns) .build(); jdbcAppender.start(); config.addAppender(jdbcAppender); AppenderRef ref = AppenderRef.createAppenderRef("DataBase", null, null); AppenderRef[] refs = new AppenderRef[]{ref}; /* 已过时,但Log4j2文档里还在用 */ LoggerConfig loggerConfig = LoggerConfig.createLogger( false, Level.TRACE, "com.example", "true", refs, null, config, null); loggerConfig.addAppender(jdbcAppender, null, null); config.addLogger("com.example", loggerConfig); context.updateLoggers(); } }
Spring上下文里有个继承AbstractConnectionSource的Log4j2ConnectionSource实现,需要注入到Log4j2Configuration类中:
@Configuration public class Log4j2ConnectionSource extends AbstractConnectionSource { private final DataSource dataSource; public Log4j2ConnectionSource(@Autowired @NotNull DataSource dataSource) { this.dataSource = dataSource; } @Override public Connection getConnection() throws SQLException { return dataSource.getConnection(); } }
还有按文档写的ConfigurationFactory:
@Order(50) @Plugin(name = "Log4j2ConfigurationFactory", category = ConfigurationFactory.CATEGORY) public class Log4j2ConfigurationFactory extends YamlConfigurationFactory { @Override public Configuration getConfiguration(LoggerContext context, ConfigurationSource configSource) { return new Log4j2Configuration(context, configSource); } @Override public String[] getSupportedTypes() { return new String[]{".yml", "*"}; } }
现在代码基本写完了,但不知道怎么触发Log4j2更新配置——也就是调用Log4j2Configuration里的doConfigure()方法,Log4j2和Spring Boot都没自动执行。
求问:怎么触发Log4j2更新配置?感谢任何帮助。
内容的提问来源于stack exchange,提问作者Slevin
相关产品推荐
相关产品推荐

