Как зарегистрировать таймер микрометра с SLA и тегами?

Я пытаюсь перенести свои метрики Prometheus на микрометр, но теперь я застрял в одном ...

На данный момент у меня гистограмма Прометея настроена следующим образом:

private static final Histogram REQUEST_DURATION = Histogram
        .build("http_request_duration_milliseconds", "Duration in milliseconds for processing a request.")
        .labelNames("http_method", "http_status", "java_class", "java_method")
        .buckets(10, 25, 50, 100, 500, 1000)
        .register();

Поэтому для перехода на микрометр я заменил его следующим образом:

Timer.builder("http.request.duration")
            .description("Duration in seconds for processing a request.")
            .sla(Duration.ofMillis(10), Duration.ofMillis(25), Duration.ofMillis(50), Duration.ofMillis(100), Duration.ofMillis(500), Duration.ofMillis(1000), Duration.ofMillis(5000))
            .register(registry);

Ok. Посмотрим, как я хочу его использовать ... На данный момент я просто звоню

REQUEST_DURATION.labels(httpMethod, httpStatus, javaClass, javaMethod).observe(milliseconds);

Поэтому я заменил это на

Metrics.timer("http.request.duration",
            "http.method", httpMethod,
            "http.status", httpStatus,
            "java.class", javaClass,
            "java.method", javaMethod)
            .record(Duration.ofNanos(nanoseconds));

Но проблема в том, что Micrometer жалуется на то, что я ранее настраивал метрику без этих тегов. Конечно, знал, потому что на тот момент я не знал ценностей. Здесь исключение:

java.lang.IllegalArgumentException: Prometheus requires that all meters with the same name have the same set of tag keys. There is already an existing meter containing tag keys []. The meter you are attempting to register has keys [http.method, http.status, java.class, java.method].

Ok. Итак, я подумал, тогда давайте укажем сегменты с помощью вызова Metrics.timer. Но это не работает, потому что нет способа передать эти значения.

Итак ... Как мне установить sla сегменты и tags для моей метрики?


person Ethan Leroy    schedule 16.05.2018    source источник
comment
Хорошо .. только что понял, что в этом случае я должен использовать Timer вместо DistributionSummary. Обновлю вопрос.   -  person Ethan Leroy    schedule 16.05.2018


Ответы (2)


Я получил ответ о канале провисания микрометра. Микрометрический способ решения этой проблемы состоит не в том, чтобы зарегистрировать саму метрику, а вместо этого зарегистрировать фильтр следующим образом:

registry.config().meterFilter(new MeterFilter() {
    @Override
    public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticConfig config) {
        if (id.getName().equals("http.request.duration")) {
            return DistributionStatisticConfig.builder()
                    .sla(Duration.ofMillis(10).toNanos(),
                         Duration.ofMillis(25).toNanos(),
                         Duration.ofMillis(50).toNanos(), 
                         Duration.ofMillis(100).toNanos(),
                         Duration.ofMillis(500).toNanos(),
                         Duration.ofMillis(1000).toNanos(), 
                         Duration.ofMillis(5000).toNanos())
                    .build()
                    .merge(config);
        }
        return config;
    }
});

При вводе значения метрики с помощью Metrics.timer(...), как указано выше, Micrometer вызовет этот фильтр и применит всю указанную здесь конфигурацию. Этот фильтр вызывается только при инициализации счетчика, т.е. когда Metrics.timer(...) вызывается в первый раз с этими конкретными name и tags. Так что нам не нужно беспокоиться о производительности здесь.

person Ethan Leroy    schedule 16.05.2018

Во-первых, между частями имени лучше всего использовать разделители точек. Это сохраняет метрику нейтральной для поставщика, поэтому, если вы когда-нибудь решите отправить товар чему-либо, кроме Prometheus, это сработает! Другими словами, лучше всего записывать это как http.request.duration. Когда применяется соглашение об именах Prometheus, оно будет отображаться как http_request_duration_seconds.

Если это приложение Spring Boot, вы можете объявить SLA в фильтр счетчиков на основе свойств:

management.metrics.distribution.sla.http.request.duration=10ns,25ns,50ns,100ns,500ns,1000ns,5000ns

Если вы используете Spring Boot 1.x, вам придется экранировать имя, как описано в здесь.

Кстати, Spring уже автоматически записывает продолжительность запроса с показателем http_server_requests. На нем нет класса Java и метода Java, но есть метод и статус, а также несколько других вещей, которых у вас здесь нет. У вас есть возможность переопределить WebMvcTagsProvider, чтобы предоставить дополнительные теги (включая класс и метод Java):

@Bean
WebMvcTagsProvider requestTags() {
   return customProvider; // can be extended from DefaultWebMvcTagsProvider
}

Для WebMvcTagsProvider#httpRequestTags есть параметр handler, по которому вы можете определить тип и метод.

person jkschneider    schedule 16.05.2018
comment
О, круто! Доступны ли эти свойства уже в Spring Boot 1? Потому что в моем случае я пока не могу перейти на версию 2. - person Ethan Leroy; 16.05.2018
comment
Вы можете включить micrometer-spring-legacy и micrometer-registry-prometheus в качестве зависимостей в свое приложение Spring Boot 1, и вы готовы к работе. Нет необходимости вручную настраивать конечные точки / контроллеры MVC. Кроме того, вы бесплатно получаете целый набор автоматически настраиваемых показателей JVM. - person mweirauch; 16.05.2018
comment
Спасибо за подсказку с точками. У меня это уже было в моем коде, но я забыл обновить его здесь. Я обновил свой код сейчас. - person Ethan Leroy; 17.05.2018
comment
Что касается _1 _... я знаю, что Spring уже записывает его. Но он записывает не имя класса java и имя метода, а только путь. Кроме того, он не настраивает эти сегменты, ... но теперь я думаю, что могу установить сегменты с помощью параметра конфигурации. - person Ethan Leroy; 17.05.2018
comment
@Ethan Обновил ответ, чтобы показать вам, как добавить класс / метод Java в инструментарий Spring по умолчанию. Как правило, мы не добавляем SLA / процентили и т. Д. К таймерам по умолчанию, а позволяем вам добавлять их по своему усмотрению с помощью таких свойств. - person jkschneider; 17.05.2018