Фильтр микрометра игнорируется CompositeMeterRegistry

Я использую Spring Boot 2.1.2.RELEASE, и я пытаюсь использовать Micrometer с CompositeMeterRegistry. Моя цель - опубликовать некоторые выбранные счетчики в ElasticSearch. В приведенном ниже коде показан мой образец конфигурации. Проблема в том, что фильтр полностью игнорируется (поэтому все метрики отправляются в ElasticSearch), хотя я могу видеть в журналах, что он был обработан (строки «ответ фильтра счетчика ...»).

Как ни странно, если я определяю MeterFilter как bean-компонент Spring, он применяется ко ВСЕМ реестрам (однако я хочу, чтобы он применялся только к «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 будет получать только метрики «возврата», а 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());

ЗАКЛЮЧЕНИЕ:

Так что вроде бы вместо НЕЙТРАЛЬНОГО фильтр должен вернуть ПРИНЯТЬ. Но для счетчиков, не начинающихся с "logback", мой исходный фильтр (с НЕЙТРАЛЬНЫМ) возвращает DENY. Тогда почему эти показатели публикуются в реестре ElasticSearch?

Кто-нибудь может это объяснить?


person Alexander Molnár    schedule 14.02.2019    source источник


Ответы (1)


Это действительно набор вопросов. Отмечу лишь несколько моментов.

Для определенного вами bean-компонента MeterRegistry Spring Boot автоматически настроит ElasticMeterRegistry bean-компонент, поскольку нет ElasticMeterRegistry bean-компонента. Вместо того, чтобы создавать CompositeMeterRegistry bean самостоятельно, просто определите пользовательский bean-компонент ElasticMeterRegistry, который будет применяться MeterFilter, который вы хотите, и позвольте Spring Boot создать его (CompositeMeterRegistry bean) для вас.

Для MeterFilterReply, ACCEPT примет счетчик немедленно, DENY немедленно отклонит счетчик, а NEUTRAL отложит решение до следующего фильтра (ов). Обычно принимаются метры, если нет DENY.

person Johnny Lim    schedule 19.02.2019
comment
Определение ElasticMeterRegistry - хорошее предложение, спасибо. Однако, похоже, это не работает. Сначала я попытался определить bean-компонент elasticMeterRegistry, но это не удалось, потому что bean-компонент с таким же именем уже был зарегистрирован. Оказывается, bean-компонент elasticMeterRegistry определяется в ElasticMetricsExportAutoConfiguration автоматически. Затем я попытался ввести этот bean-компонент (вместо того, чтобы определять свой собственный) и добавить фильтр (в методе, помеченном знаком @PostConstruct, но фильтр не дал никакого эффекта. - person Alexander Molnár; 20.02.2019
comment
Что касается MeterFilterReply, вы правы. Однако, если у вас только один фильтр, возврат NEUTRAL вместо ACCEPT должен иметь тот же эффект, верно? - person Alexander Molnár; 20.02.2019