Мониторинг Kotlin приложений: метрики и алерты
В современной разработке программного обеспечения мониторинг стал неотъемлемой частью production-экосистемы. Для приложений на Kotlin, работающих на JVM, грамотно настроенный мониторинг позволяет не только отслеживать состояние системы в реальном времени, но и предотвращать инциденты до того, как они повлияют на пользователей. В этой статье мы рассмотрим, как организовать сбор метрик и настроить алерты для Kotlin-приложений с использованием современных инструментов, таких как Micrometer и Prometheus.
Зачем нужен мониторинг Kotlin-приложений?
Kotlin, будучи языком, работающим поверх JVM, наследует все возможности мониторинга Java-экосистемы, но добавляет свои особенности — корутины, функции-расширения и null-safety. Мониторинг помогает ответить на три ключевых вопроса:
- Что происходит прямо сейчас? — текущая нагрузка, количество запросов, использование памяти.
- Что происходило раньше? — исторические данные для анализа трендов и поиска узких мест.
- Что может пойти не так? — прогнозирование проблем на основе метрик.
Без мониторинга любое приложение работает «вслепую», и даже незначительная утечка памяти может привести к простою.
Основные метрики для Kotlin-приложений
Прежде чем настраивать инструменты, важно понимать, какие метрики критичны для JVM-приложений на Kotlin.
JVM-метрики
Это базовый набор, который показывает здоровье виртуальной машины:
- Использование heap и non-heap памяти
- Количество потоков (активных, демонов, заблокированных)
- Время GC (Garbage Collection) и частота сборок
- Загрузка CPU
Бизнес-метрики
Отражают работу самого приложения:
- Количество HTTP-запросов (RPS — requests per second)
- Время ответа (latency p50, p95, p99)
- Количество ошибок (4xx, 5xx)
- Глубина очередей (если используются корутины или очереди сообщений)
Метрики корутин
Поскольку Kotlin активно использует корутины, полезно мониторить:
- Количество активных корутин
- Время выполнения корутин
- Количество отменённых корутин
Инструменты для мониторинга: Micrometer + Prometheus
Стандартный стек для мониторинга Kotlin-приложений включает Micrometer (библиотека для сбора метрик) и Prometheus (система хранения и оповещения). Micrometer выступает фасадом, который поддерживает множество бэкендов (Prometheus, Datadog, Graphite и др.), но Prometheus — самый популярный выбор.
Подключение зависимостей
Для Gradle (build.gradle.kts):
dependencies {
implementation("io.micrometer:micrometer-core:1.12.0")
implementation("io.micrometer:micrometer-registry-prometheus:1.12.0")
implementation("io.ktor:ktor-server-metrics-micrometer:2.3.7")
}
Настройка сбора метрик в Ktor
Рассмотрим пример настройки для веб-приложения на Ktor — популярном фреймворке для Kotlin:
import io.micrometer.prometheus.PrometheusMeterRegistry
import io.micrometer.prometheus.PrometheusConfig
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.routing.*
import io.ktor.server.response.*
import io.ktor.server.metrics.micrometer.*
fun main() {
val meterRegistry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT)
embeddedServer(Netty, port = 8080) {
install(MicrometerMetrics) {
registry = meterRegistry
// Добавляем стандартные теги
meterRegistry.config().commonTags("application", "my-kotlin-app")
}
routing {
get("/metrics") {
call.respond(meterRegistry.scrape())
}
get("/hello") {
call.respondText("Hello, World!")
}
}
}.start(wait = true)
}
Теперь по адресу /metrics Prometheus сможет забирать данные в формате plain text.
Добавление кастомных метрик
Micrometer позволяет легко создавать собственные счётчики, таймеры и гистограммы:
import io.micrometer.core.instrument.Counter
import io.micrometer.core.instrument.Timer
class OrderService(private val meterRegistry: PrometheusMeterRegistry) {
private val orderCounter: Counter = Counter
.builder("orders.created")
.description("Total number of created orders")
.register(meterRegistry)
private val orderTimer: Timer = Timer
.builder("orders.processing.time")
.description("Time taken to process an order")
.register(meterRegistry)
fun createOrder() {
val sample = Timer.start()
try {
// Логика создания заказа
Thread.sleep(100) // Имитация работы
orderCounter.increment()
} finally {
sample.stop(orderTimer)
}
}
}
Настройка алертов в Prometheus
Сами по себе метрики бесполезны, если на них нет реакций. Prometheus Alertmanager позволяет настроить оповещения по различным каналам: email, Slack, Telegram, PagerDuty.
Пример правил алертов
Создайте файл alerts.yml:
groups:
- name: kotlin-app-alerts
rules:
- alert: HighMemoryUsage
expr: jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"} > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: "Heap memory usage above 85%"
description: "Heap memory usage is {{ $value | humanizePercentage }} for {{ $labels.instance }}"
- alert: HighErrorRate
expr: rate(http_server_requests_seconds_count{status=~"5.."}[5m]) / rate(http_server_requests_seconds_count[5m]) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "Error rate above 5%"
description: "Error rate is {{ $value | humanizePercentage }} for the last 5 minutes"
- alert: HighLatency
expr: histogram_quantile(0.95, rate(http_server_requests_seconds_bucket[5m])) > 1.0