I’d like to have spring auto configuration which adds LogstashTcpSocketAppender.
What I have done:
- The LogstashTcpSocketAppender was added in to the LoggerContext from the LogstashAutoConfiguration.java
@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;
}
}
- After a while, the Spring Boot trigger a event will make the app reconfig. (for example I use Consul so I just change property in key/value storage, then spring refresh my context)
- It call the initializeWithConventions in the AbstractLoggingSystem.java
- then it will call the loadConfiguration in the LogbackLoggingSystem.java
- then it will stopAndReset(loggerContext). here it will stop all the appenders, and it will resetAllListeners();, which will clear the all logback listeners. (so I cannot use logback listeners for addition appenders again)
Are there correct way add Appender through spring auto configuration? How can I prevent remove LogstashTcpSocketAppender from LoggerContext when spring makes the app reconfig?
In the above
Configuration
class, the intent is to add anappender
forLogstash
and that takes care of sending the logs.In case of an environment variable changes or the context gets refreshed, you can listen to the relevant events, then check if your Logstash appender is configured or not. Make sure you add the Logstash appender only if it is missing.
Here is the class that would do the same.