I'm building a web stack based on Dropwizard v0.9.1. All logs from the stack are sent to Loggly via a custom implementation of the AppenderFactory interface:
@JsonTypeName("loggly")
public class LogglyAppenderFactory extends AbstractAppenderFactory {
@JsonProperty
private String token;
@JsonProperty
private final Optional<String> tag = Optional.absent();
@Override
public Appender<ILoggingEvent> build(LoggerContext context, String applicationName, Layout<ILoggingEvent> layout) {
...
}
protected Layout<ILoggingEvent> buildLayout(LoggerContext context) {
...
}
}
This class isn't registered with the Environment in my Application class. Instead, it seems to be autowired by Dropwizard based on the @JsonTypeName annotation. Despite this, the token and tag fields are populated by values that appear in my configuration yaml file:
logging:
level: INFO
appenders:
# send logs to loggly
- type: loggly
threshold: INFO
token: "my-secret-loggly-token"
tag: "webservice-ci"
The thing is, these configuration values don't appear in my application's Configuration class, which means that I can't re-use them when building other Resources or HealthChecks.
Ideally, I'd like to manually register the LogglyAppenderFactory like this:
public class WebServiceApplication extends Application<WebServiceAppConfiguration> {
@Override
public void run(WebServiceAppConfiguration configuration, Environment environment) throws Exception {
final HttpClient httpClient = new HttpClientBuilder(environment).using(configuration.getHttpClientConfiguration()).build("httpClient");
// to be clear, environment.logAppenders() doesn't exist, and this doesn't work
final LogglyAppenderFactory logglyAppenderFactory = new LogglyAppenderFactoryBuilder(configuration).build();
environment.logAppenders().register(logglyAppenderFactory)
// when we make this HealthCheck, it would be cool to reference the same config values that the AppenderFactory used
final LogglyHealthCheck logglyHealthCheck = new LogglyHealthCheck(httpClient, configuration);
environment.healthChecks().register("Loggly", logglyHealthCheck);
}
}
so that both the LogglyAppenderFactory and the LogglyHealthCheck can use the same configuration values that dictate how they talk to the external service.
I suspect that this might be possible if I introduce a Dependency Injection framework like Google Guice and use it to inject the application configuration into both objects, but on the other hand, since logback appenders are typically created very early in the application lifecycle, I don't know if Guice will be ready to go when the AppenderFactory is being created.
Does anybody know how to do this? If not, am I stuck with putting the token into my config file twice? Once in the logging.appenders section, and again in some other section that the LogglyHealthCheck can access?