Dropwizard 0.9.1:在自定义AppenderFactory实现中使用应用程序配置值

时间:2015-12-15 20:43:12

标签: java logging configuration guice dropwizard

我正在构建一个基于Dropwizard v0.9.1的Web堆栈。堆栈中的所有日志都通过Loggly接口的自定义实现发送到AppenderFactory

@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) {
        ...
    }
}

此类未在我的Application类中的Environment中注册。相反,它似乎是由Dropwizard基于@JsonTypeName注释自动装配的。尽管如此,tokentag字段由我的配置yaml文件中显示的值填充:

logging:
    level: INFO
    appenders:
        # send logs to loggly
        - type: loggly
          threshold: INFO
          token: "my-secret-loggly-token"
          tag: "webservice-ci"

问题是,这些配置值没有出现在我的应用程序的Configuration类中,这意味着在构建其他资源或HealthChecks时我无法重用它们。

理想情况下,我想像这样手动注册LogglyAppenderFactory

 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);
    }
}

这样LogglyAppenderFactory和LogglyHealthCheck都可以使用相同的配置值来指示它们如何与外部服务通信。

我怀疑如果我引入像Google Guice这样的依赖注入框架并使用它将应用程序配置注入到两个对象中,这可能是可能的,但另一方面,因为logback appender通常在应用程序生命周期的早期创建,我不知道在创建AppenderFactory时Guice是否准备好了。

有人知道怎么做吗?如果没有,我是否坚持将令牌放入配置文件两次?一旦进入logging.appenders部分,再一次进入LogglyHealthCheck可以访问的其他部分?

2 个答案:

答案 0 :(得分:2)

我认为你正在寻找

configuration.getLoggingFactory();

此API为您提供配置文件中的所有日志配置。

例如

configuration.getLoggingFactory().getLevel();

configuration.getLoggingFactory().getAppenders()

((ConsoleAppenderFactory)configuration.getLoggingFactory().getAppenders().get(0)).getLogFormat();

不是最漂亮的API,但应该可行

答案 1 :(得分:1)

原来,Configuration类公开了一个包含日志记录配置的LoggingFactory。我将这个帮助器方法添加到我的Configuration类中,该类从我的自定义AppenderFactory中提取我关心的字段:

/**
 * Extracts the Loggly token from the logging.appenders section of the configuration file.
 * If a {@link LogglyAppenderFactory} is not specified as one of the log appenders, this method returns null.
 * @return the Loggly token or null if no token is specified
 */
public String getLogglyToken() {
    final DefaultLoggingFactory loggingFactory = (DefaultLoggingFactory) getLoggingFactory();
    for (final AppenderFactory appenderFactory : loggingFactory.getAppenders()) {
        if (appenderFactory instanceof LogglyAppenderFactory) {
            final LogglyAppenderFactory logglyAppenderFactory = (LogglyAppenderFactory) appenderFactory;
            return logglyAppenderFactory.getToken();
        }
    }
    return null;
}

它不漂亮,但它有效!