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

Dropwizard 0.9.1: Use Application Configuration Values in Custom AppenderFactory Implementation

我正在构建一个基于 Dropwizard v0.9.1 的网络堆栈。堆栈中的所有日志都发送到 Loggly via a custom implementation of the 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) {
        ...
    }
}

此 class 未在我的应用程序 class 中的环境中注册。相反,它似乎是由 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 class 中,这意味着我无法在构建其他资源或健康检查时重新使用它们。

理想情况下,我想像这样手动注册 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 可以访问的其他部分?

我想你在找

configuration.getLoggingFactory();

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

例如

configuration.getLoggingFactory().getLevel();

configuration.getLoggingFactory().getAppenders()

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

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

原来配置 class 公开了一个包含日志记录配置的 LoggingFactory。我将这个辅助方法添加到我的配置 class 中,它从我的自定义 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;
}

虽然不漂亮,但很管用!