Интеграция Prometheus метрик в приложениях на Kotlin: полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Prometheus метрики в Kotlin: полное руководство по интеграции

В современной разработке мониторинг и сбор метрик являются критически важными для поддержания стабильности приложений. Prometheus — это ведущая система мониторинга с открытым исходным кодом, которая позволяет собирать, хранить и анализировать данные о производительности. В этой статье мы рассмотрим, как добавить Prometheus метрики в приложения на Kotlin, используя библиотеку Micrometer и настраиваемый HTTP-сервер.

Почему стоит использовать Prometheus с Kotlin?

  • Гибкость: Prometheus поддерживает множество типов метрик: счетчики, гистограммы, суммаризации и датчики.
  • Встроенная интеграция: Kotlin полностью совместим с Java-экосистемой, что позволяет использовать Micrometer — популярный инструмент для сбора метрик.
  • Масштабируемость: Prometheus легко масштабируется для мониторинга микросервисов и распределенных систем.

Настройка проекта с Gradle

Для начала добавьте зависимости в файл build.gradle.kts:

dependencies {
    implementation("io.micrometer:micrometer-core:1.12.0")
    implementation("io.micrometer:micrometer-registry-prometheus:1.12.0")
    // Для HTTP-сервера (используем Ktor)
    implementation("io.ktor:ktor-server-netty:2.3.7")
    implementation("io.ktor:ktor-server-content-negotiation:2.3.7")
}

Создание Prometheus-регистратора

Основой сбора метрик является PrometheusMeterRegistry. Создайте его в вашем приложении:

import io.micrometer.prometheus.PrometheusConfig
import io.micrometer.prometheus.PrometheusMeterRegistry

val registry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT)

Определение метрик

Рассмотрим три основных типа метрик:

  • Counter — счетчик, который только увеличивается (например, количество запросов).
  • Gauge — текущее значение (например, количество активных пользователей).
  • Timer — время выполнения операций.

Пример создания метрик:

import io.micrometer.core.instrument.Counter
import io.micrometer.core.instrument.Gauge
import io.micrometer.core.instrument.Timer

val requestCounter: Counter = Counter
    .builder("api.requests.total")
    .description("Общее количество запросов к API")
    .register(registry)

val activeUsersGauge: Gauge = Gauge
    .builder("app.users.active")
    .description("Количество активных пользователей")
    .register(registry) { activeUsersCount }

val requestTimer: Timer = Timer
    .builder("api.requests.duration")
    .description("Время выполнения запросов")
    .register(registry)

var activeUsersCount = 0

Экспорт метрик через HTTP

Чтобы Prometheus мог собирать метрики, их нужно экспортировать в формате /metrics. Используем Ktor для создания эндпоинта:

import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.routing.get
import io.ktor.server.routing.routing
import io.ktor.server.response.respondText

fun startMetricsServer(port: Int = 9090) {
    embeddedServer(Netty, port = port) {
        routing {
            get("/metrics") {
                val scrape = registry.scrape()
                call.respondText(scrape, contentType = io.ktor.http.ContentType.Text.Plain)
            }
        }
    }.start(wait = false)
}

Интеграция с бизнес-логикой

Обновляйте метрики в коде вашего приложения:

fun handleRequest() {
    requestTimer.record {
        // Имитация обработки запроса
        Thread.sleep(100)
        requestCounter.increment()
    }
}

fun userLoggedIn() {
    activeUsersCount++
}

fun userLoggedOut() {
    activeUsersCount--
}

Полный пример приложения

Соберем всё вместе в одном файле Main.kt:

import io.micrometer.prometheus.PrometheusConfig
import io.micrometer.prometheus.PrometheusMeterRegistry
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.routing.get
import io.ktor.server.routing.routing
import io.ktor.server.response.respondText
import io.micrometer.core.instrument.Counter
import io.micrometer.core.instrument.Timer
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

val registry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT)

val requestCounter = Counter
    .builder("app.requests.total")
    .description("Total API requests")
    .register(registry)

val requestTimer = Timer
    .builder("app.requests.duration")
    .description("Request duration")
    .register(registry)

fun main() {
    // Запуск HTTP-серве                    

Рекомендаций