Моя установка:
3.1.3
spring-boot-starter-actuator
MyHealthMetricsExportConfiguration
согласно документации (показан ниже)./actuator/metrics
я вижу health
метрику-javaagent:./opentelemetry-javaagent.jar
-Dotel.metrics.exporter=otlp
receiver
, установленным на otlp
Вопрос
Я не знаю, как заставить агента отеля «видеть» и экспортировать показатели Spring, такие как f.e. «MyHealthMetricsExportConfiguration». В этом блоге это должно быть так просто:
// Unregister the OpenTelemetryMeterRegistry from Metrics.globalRegistry and make it available
// as a Spring bean instead.
@Bean
@ConditionalOnClass(name = "io.opentelemetry.javaagent.OpenTelemetryAgent")
public MeterRegistry otelRegistry() {
Optional<MeterRegistry> otelRegistry = Metrics.globalRegistry.getRegistries().stream()
.filter(r -> r.getClass().getName().contains("OpenTelemetryMeterRegistry"))
.findAny();
otelRegistry.ifPresent(Metrics.globalRegistry::remove);
return otelRegistry.orElse(null);
}
Но это не работает для меня. Прежде всего, создание durig bean Metrics.globalRegistry.getRegistries()
пусто. Во-вторых, в коллекторе отелей нет метрики health
. Что я могу сделать, чтобы этот агент отправил мою специальную метрику сборщику?
@Configuration(proxyBeanMethods = false)
public class MyHealthMetricsExportConfiguration {
public MyHealthMetricsExportConfiguration(MeterRegistry registry, HealthEndpoint healthEndpoint) {
// This example presumes common tags (such as the app) are applied elsewhere
Gauge.builder("health", healthEndpoint, this::getStatusCode).strongReference(true).register(registry);
}
private int getStatusCode(HealthEndpoint health) {
Status status = health.health().getStatus();
if (Status.UP.equals(status)) {
return 3;
}
if (Status.OUT_OF_SERVICE.equals(status)) {
return 2;
}
if (Status.DOWN.equals(status)) {
return 1;
}
return 0;
}
}
Если вы напишете ответ здесь, с ф.э. кусок кода, который подойдет вам, тогда я могу дать вам награду.
Судя по вашему описанию, вы смешиваете 2 подхода.
-javaagent:
, который будет инструментировать ваше приложение с весенней загрузкой во время выполненияэто условие @ConditionalOnClass(name = "io.opentelemetry.javaagent.OpenTelemetryAgent")
вернет false для второго варианта (поставьте точку останова или журнал отладки, и вы увидите, что ваше приложение не создает otelRegistry
bean-компонент).
Если вы решите использовать javaagent + prometheus (включите io.micrometer:micrometer-registry-prometheus
в свои зависимости), вы можете отказаться от OpenTelemetryMeterRegistry
(условный компонент)
Metrics.globalRegistry.getRegistries()
чтобы вернуться PrometheusMeterRegistry
Если вы предпочитаете формат optl, перейдите по ссылке выше.
Вам необходимо включить мост OpenTelemetry для Micrometer. Он отключен по умолчанию, начиная с версии 2.0.0 агента OpenTelemetry: https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/tag/v2.0.0
Для использования агента (ваш случай) добавьте это системное свойство в параметры виртуальной машины: -Dotel.instrumentation.micrometer.enabled=true
.
И я бы рекомендовал сначала настроить консольный экспортер (-Dotel.metrics.exporter=console
), чтобы проверять именно в консоли, что экспортируется, независимо от того, что происходит на принимающей стороне (на сборщике).
P.S. Вам не нужен фрагмент кода из упомянутого вами сообщения в блоге (public MeterRegistry otelRegistry() {...
). Возможно, это полезно для чего-то, но ему уже 2 года, а OpenTelemetry все еще находится в альфа-версии и имеет множество критических изменений. Так что на сегодняшний день у меня все работает без него. Примечание: OpenTelemetryMeterRegistry
, о котором они там упоминают, взят из библиотеки моста OpenTelemetry (она автоматически включается как в агент, так и в Spring Starter).
Для тех, кто использует пружинный стартер opentelemetry (io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter
) вместо агента, в него уже включен микрометрический мост, поэтому включите его, установив то же системное свойство (например, в application.properties
добавьте строку otel.instrumentation.micrometer.enabled=true
).
Попробовал оба варианта с последней версией (2.3.0), всё заработало (Spring Boot 3.2.5). Используя ваш класс, я получил следующий журнал показателей (среди многих других) в выводе консоли (см. ...name=health...value=3.0...
):
[otel.javaagent 2024-05-11 00:11:00:926 +0400] [PeriodicMetricReader-1] INFO io.opentelemetry.exporter.logging.LoggingMetricExporter - metric: ImmutableMetricData{resource=Resource{schemaUrl=https://opentelemetry.io/schemas/1.24.0, attributes = {host.arch = "amd64", host.name = "DESKTOP-NCP", os.description = "Windows 10 10.0", os.type = "windows", process.command_line = "C:\Program Files\Eclipse Adoptium\jdk-17.0.10.7-hotspot\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:13011,suspend=y,server=n -javaagent:./opentelemetry-javaagent.jar -Dotel.instrumentation.micrometer.enabled=true -Dotel.metrics.exporter=console -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dmanagement.endpoints.jmx.exposure.include=* -javaagent:C:\Users\Artem\AppData\Local\JetBrains\IntelliJIdea2024.1\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 com.backend.BackendApplication", process.executable.path = "C:\Program Files\Eclipse Adoptium\jdk-17.0.10.7-hotspot\bin\java.exe", process.pid=44220, process.runtime.description = "Eclipse Adoptium OpenJDK 64-Bit Server VM 17.0.10+7", process.runtime.name = "OpenJDK Runtime Environment", process.runtime.version = "17.0.10+7", service.instance.id = "3c1b88b9-bdf6-457f-9e46-abb511930f80", service.name = "backend", telemetry.distro.name = "opentelemetry-java-instrumentation", telemetry.distro.version = "2.3.0", telemetry.sdk.language = "java", telemetry.sdk.name = "opentelemetry", telemetry.sdk.version = "1.37.0"}}, instrumentationScopeInfo=InstrumentationScopeInfo{name=io.opentelemetry.micrometer-1.5, version=null, schemaUrl=null, attributes = {}}, name=health, description=, unit=, type=DOUBLE_GAUGE, data=ImmutableGaugeData{points=[ImmutableDoublePointData{startEpochNanos=1715371800406007400, epochNanos=1715371860420845000, attributes = {}, value=3.0, exemplars=[]}]}}
Отдельно мост Микрометр доступен на этой странице (найдите его в таблице): https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/supported-libraries.md#libraries --фреймворки
Будьте осторожны: включение моста Micrometer также начнет экспортировать метрики Spring по умолчанию, а некоторые из них имеют те же имена, что и инструменты OpenTelemetry. Поскольку у них разные атрибуты, сборщик, похоже, рассматривает их как одну и ту же метрику с разными атрибутами. Так, например, в Grafana вы увидите одну метрику jvm_memory_used
, но некоторые измерения будут дублироваться (пример G1 Eden Space
дублирования):
...
comes from "io.opentelemetry.micrometer-1.5" bridge:
jvm_memory_used{area = "heap", id = "G1 Eden Space", instance = "07d3f12f-c3a5-43bf-a268-bb80bceb6c56", job = "stolpy-backend"}
...
comes from "io.opentelemetry.runtime-telemetry-java8":
jvm_memory_used{instance = "07d3f12f-c3a5-43bf-a268-bb80bceb6c56", job = "stolpy-backend", jvm_memory_pool_name = "G1 Eden Space", jvm_memory_type = "heap"}
Итак, вы, вероятно, захотите отключить метрики Spring Micrometer по умолчанию, где-то в документации должно быть объяснено, как это сделать. Например, в этом сообщении SO упоминается что-то: Метрики привода/микрометра Spring Boot отключают некоторые
Откуда вы это узнали? Должен ли я отлаживать низкоуровневые вещи после рабочего времени, чтобы стать лучше, проходить через вопросы/ответы SO, чтобы быть знакомым с такими проблемами? Проголосуйте против меня столько, сколько хотите, но я впечатлен и буду признателен за совет, что делать, чтобы быть похожим на вас.
@user3529850 user3529850 По иронии судьбы, вчера я наткнулся на ваш вопрос, когда пытался найти ответ на свой собственный вопрос об OpenTelemetry (не на SO), и заметил, что на этот вопрос я могу ответить :) Я сам все еще изучаю OpenTelemetry. Мне пришлось много экспериментировать (проверка вывода отладки часто является хорошей идеей), прочитать много их документации, блогов, кода Github, примечаний к выпуску и т. д., чтобы понять, что происходит. К сожалению, информация пока очень скудная, я согласен, надеюсь, что после альфа-версии она улучшится. Случайно в результате своих экспериментов я узнал ответ на ваш вопрос.
Я не знаю, почему это не работает, поскольку отсутствует информация о вашей инициализации (автоконфигурация, руководство, envvars, версия агента...), но в качестве подсказки: вы прошли opentelemetry.io/docs/languages/java /инструменты ? Если нет, то должно сработать, по крайней мере у меня так было 2 дня назад. Еще одно место, где можно задать вопрос, — это #otel-java в cncf Slack.