2

我使用 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 注册表?

有人可以解释一下吗?

4

1 回答 1

1

这实际上是一个问题的组合。我只指出几点。

对于MeterRegistry您定义的 bean,Spring Boot 将自动配置一个ElasticMeterRegistrybean,因为没有ElasticMeterRegistrybean。CompositeMeterRegistry无需自己创建bean,只需定义一个自定义ElasticMeterRegistrybean,MeterFilter然后让 Spring BootCompositeMeterRegistry为您创建一个(bean)。

对于MeterFilterReplyACCEPT将立即接受仪表,DENY将立即拒绝仪表,并将NEUTRAL决定推迟到下一个过滤器。除非有任何DENY.

于 2019-02-19T14:00:54.507 回答