Prometheus метрики в Java: библиотека simpleclient
Prometheus — это мощная система мониторинга и оповещения с открытым исходным кодом, которая собирает метрики из различных источников. Для Java-приложений существует несколько библиотек для интеграции с Prometheus. Основная и наиболее популярная — simpleclient от самого проекта Prometheus. Она предоставляет минималистичный, потокобезопасный и высокопроизводительный способ создания, регистрации и экспорта метрик.
Что такое simpleclient?
simpleclient — это официальная Java-библиотека Prometheus, которая позволяет разработчикам добавлять метрики в приложения с минимальными накладными расходами. Она поддерживает четыре основных типа метрик:
- Counter — счетчик, который только увеличивается (например, количество запросов).
- Gauge — значение, которое может как увеличиваться, так и уменьшаться (например, количество активных соединений, температура).
- Histogram — гистограмма, измеряющая распределение значений (например, время выполнения запросов).
- Summary — сводка, похожая на гистограмму, но вычисляющая квантили на стороне клиента.
Установка и подключение
Для работы с simpleclient добавьте в pom.xml (Maven) следующие зависимости:
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>0.16.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.16.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_servlet</artifactId>
<version>0.16.0</version>
</dependency>
Для Gradle:
implementation 'io.prometheus:simpleclient:0.16.0'
implementation 'io.prometheus:simpleclient_hotspot:0.16.0'
implementation 'io.prometheus:simpleclient_servlet:0.16.0'
Создание и регистрация метрик
Рассмотрим создание простого счетчика запросов. Метрики регистрируются в глобальном реестре CollectorRegistry.defaultRegistry.
import io.prometheus.client.Counter;
import io.prometheus.client.Gauge;
public class MetricsExample {
// Создаем счетчик с именем "http_requests_total" и метками "method" и "endpoint"
static final Counter requests = Counter.build()
.name("http_requests_total")
.help("Total number of HTTP requests.")
.labelNames("method", "endpoint")
.register();
// Создаем датчик для количества активных сессий
static final Gauge activeSessions = Gauge.build()
.name("active_sessions")
.help("Current number of active sessions.")
.register();
public static void processRequest(String method, String endpoint) {
// Увеличиваем счетчик
requests.labels(method, endpoint).inc();
// Устанавливаем значение датчика (например, размер очереди)
activeSessions.set(42);
}
}
Экспорт метрик через HTTP
Чтобы Prometheus мог собрать метрики, нужно предоставить эндпоинт /metrics. Проще всего это сделать с помощью встроенного сервлета. Если вы используете Spring Boot, добавьте зависимость simpleclient_spring_boot.
import io.prometheus.client.exporter.MetricsServlet;
import io.prometheus.client.hotspot.DefaultExports;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/metrics")
public class MetricsExporterServlet extends HttpServlet {
private MetricsServlet metricsServlet = new MetricsServlet();
@Override
public void init() {
// Включаем стандартные метрики JVM (память, GC, потоки)
DefaultExports.initialize();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
metricsServlet.service(req, resp);
}
}
Интеграция с Micrometer
Если вы используете современный стек Spring Boot, рекомендуется использовать Micrometer — фасад для метрик, который поддерживает Prometheus как один из бэкендов. Для этого добавьте зависимость:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.9.0</version>
</dependency>
В application.properties укажите:
management.endpoints.web.exposure.include=prometheus
management.metrics.export.prometheus.enabled=true
Теперь эндпоинт /actuator/prometheus будет отдавать мет