千分尺过滤器被CompositeMeterRegistry

时间:2019-02-14 15:47:03

标签: spring-boot elasticsearch micrometer spring-micrometer

我使用Spring Boot 2.1.2.RELEASE,并尝试将Micrometer与CompositeMeterRegistry一起使用。我的目标是将一些选定的计量表发布到ElasticSearch。下面的代码显示了我的示例配置。问题是,尽管我在日志中可以看到过滤器已被处理(“过滤器对计量表的答复...”行),但该过滤器被完全忽略了(因此所有度量标准都发送到了ElasticSearch)。

奇怪的是,如果我将MeterFilter定义为Spring Bean,那么它将应用于所有注册表(但是,我希望仅将其应用于“ elasticMeterRegistry”)。

这是一个示例配置类:

@Configuration
public class AppConfiguration {

    @Bean
    public ElasticConfig elasticConfig() {
        return new ElasticConfig() {
            @Override
            @Nullable
            public String get(final String k) {
                return null;
            }
        };
    }

    @Bean
    public MeterRegistry meterRegistry(final ElasticConfig elasticConfig) {
        final CompositeMeterRegistry registry = new CompositeMeterRegistry();
        registry.add(new SimpleMeterRegistry());
        registry.add(new JmxMeterRegistry(new JmxConfig() {
            @Override
            public Duration step() {
                return Duration.ofSeconds(10);
            }

            @Override
            @Nullable
            public String get(String k) {
                return null;
            }
        }, Clock.SYSTEM));

        final ElasticMeterRegistry elasticMeterRegistry = new ElasticMeterRegistry(elasticConfig, Clock.SYSTEM);
        elasticMeterRegistry.config().meterFilter(new MeterFilter() {
            @Override
            public MeterFilterReply accept(Meter.Id id) {
                final MeterFilterReply reply =
                        id.getName().startsWith("logback")
                                ? MeterFilterReply.NEUTRAL
                                : MeterFilterReply.DENY;
                log.info("filter reply of meter {}: {}", id.getName(), reply);
                return reply;
            }
        });
        registry.add(elasticMeterRegistry);

        return registry;
    }
}

因此,我希望ElasticSearch仅接收“ logback”指标,而JMX将接收所有指标。

更新:

我玩过过滤器并找到了一个“解决方案”,但我真的不明白为什么上面的代码不起作用。

这有效:

elasticMeterRegistry.config().meterFilter(new MeterFilter() {
    @Override
    public MeterFilterReply accept(Meter.Id id) {
        final MeterFilterReply reply =
                id.getName().startsWith("logback")
                        ? MeterFilterReply.ACCEPT
                        : MeterFilterReply.DENY;
        log.info("filter reply of meter {}: {}", id.getName(), reply);
        return reply;
    }
});

区别是:我返回ACCEPT而不是NEUTRAL。

奇怪的是,以下代码不起作用(ES获取所有指标):

elasticMeterRegistry.config().meterFilter(
    MeterFilter.accept(id -> id.getName().startsWith("logback")));

但这可行:

elasticMeterRegistry.config().meterFilter(
    MeterFilter.accept(id -> id.getName().startsWith("logback")));
elasticMeterRegistry.config().meterFilter(
    MeterFilter.deny());

结论:

因此,过滤器似乎应该返回ACCEPT而不是NEUTRAL。但是对于不是以“ logback”开头的仪表,我的原始过滤器(带有NEUTRAL)返回DENY。那为什么这些指标会发布到ElasticSearch注册表中呢?

有人可以解释吗?

1 个答案:

答案 0 :(得分:0)

这实际上是问题的综合。我只想指出几点。

对于您定义的MeterRegistry bean,Spring Boot将自动配置ElasticMeterRegistry bean,因为没有ElasticMeterRegistry bean。与其定义自己的CompositeMeterRegistry bean,不如定义一个自定义的ElasticMeterRegistry bean,它将应用您想要的MeterFilter并让Spring Boot为它创建一个(CompositeMeterRegistry bean)你。

对于MeterFilterReplyACCEPT将立即接受计量表,DENY将立即拒绝计量表,并且NEUTRAL将决定推迟到下一个过滤器。除非有DENY,否则基本上都可以接受米。