问题描述
我想进行Spring自动配置,以添加LogstashTcpsocketAppender。
我所做的:
@Configuration
@ConditionalOnProperty(name = "logging.logstash.url")
@requiredArgsConstructor
public class LogstashAutoConfiguration {
@Value("${spring.application.name:null}")
private String applicationName;
@Value("${logging.logstash.url}")
private String logstashUrl;
@Bean
public LogstashTcpsocketAppender logstashAppender() {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
LogstashTcpsocketAppender logstashTcpsocketAppender = new LogstashTcpsocketAppender();
logstashTcpsocketAppender.setName("LOGSTASH");
logstashTcpsocketAppender.setContext(loggerContext);
logstashTcpsocketAppender.addDestination(logstashUrl);
LogstashEncoder encoder = new LogstashEncoder();
encoder.setIncludeMdc(true);
encoder.getFieldNames().setLevelValue(null);
encoder.setCustomFields(String.format("{\"app_name\":\"%s\"}",applicationName));
logstashTcpsocketAppender.setEncoder(encoder);
logstashTcpsocketAppender.start();
loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(logstashTcpsocketAppender);
return logstashTcpsocketAppender;
}
}
- 过一会儿,Spring Boot触发一个事件将重新配置应用程序。 (例如,我使用Consul,所以我只更改键/值存储中的属性,然后春季刷新我的上下文)
- 它在AbstractLoggingSystem.java中调用InitializeWithConventions
- 然后它将在LogbackLoggingSystem.java中调用loadConfiguration
- 然后它将停止stopAndReset(loggerContext)。在这里它将停止所有附加程序,并会重置resetAllListeners();,这将清除所有的Logback侦听器。 (所以我不能再将Logback侦听器用于添加附加程序)
是否有通过Spring自动配置添加Appender的正确方法? 春天使应用程序重新配置时,如何防止从LoggerContext中删除LogstashTcpsocketAppender?
解决方法
在上述Configuration
类中,目的是为appender
添加一个Logstash
,并负责发送日志。
如果环境变量发生更改或上下文得到刷新,则可以侦听相关事件,然后检查是否已配置Logstash附加程序。确保仅在缺少Logstash附加程序时添加它。
这里是可以做的事情。
@Configuration
@ConditionalOnProperty(name = "logging.logstash.url")
public class LogstashAppenderConfiguration {
@Value("${spring.application.name:null}")
private String applicationName;
@Value("${logging.logstash.url}")
private String logstashUrl;
@EventListener(ContextRefreshedEvent.class)
public void onContextRefreshedEvent(ContextRefreshedEvent event) {
this.addLogStashAppenderIfMissing();
}
@EventListener(RefreshScopeRefreshedEvent.class)
public void onRefreshScopeRefreshedEvent(RefreshScopeRefreshedEvent event) {
this.addLogStashAppenderIfMissing();
}
@EventListener(EnvironmentChangeEvent.class)
public void onEnvironmentChangeEvent(EnvironmentChangeEvent event) {
this.addLogStashAppenderIfMissing();
}
public void addLogStashAppenderIfMissing() {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
synchronized (this) {
if (Objects.isNull(loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).getAppender("LOGSTASH"))) {
LogstashTcpSocketAppender logstashTcpSocketAppender = new LogstashTcpSocketAppender();
logstashTcpSocketAppender.setName("LOGSTASH");
logstashTcpSocketAppender.setContext(loggerContext);
logstashTcpSocketAppender.addDestination(logstashUrl);
LogstashEncoder encoder = new LogstashEncoder();
encoder.setIncludeMdc(true);
encoder.getFieldNames().setLevelValue(null);
encoder.setCustomFields(String.format("{\"app_name\":\"%s\"}",applicationName));
logstashTcpSocketAppender.setEncoder(encoder);
logstashTcpSocketAppender.start();
loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(logstashTcpSocketAppender); ;
}
}
}
}