Monitoreo de aplicaciones Kotlin: Ktor Metrics y Micrometer
Las aplicaciones de servidor modernas en Kotlin, construidas sobre el framework Ktor, requieren una supervisión constante del rendimiento y el estado. Para ello se utiliza la combinación de dos potentes herramientas: Ktor Metrics Plugin (módulo integrado en Ktor) y Micrometer (fachada para la recolección de métricas). En este artículo analizaremos cómo configurar el monitoreo con exportación de datos a Prometheus y visualización en Grafana.
¿Por qué es necesario el monitoreo?
El monitoreo permite:
- Rastrear el tiempo de respuesta de los endpoints (latencia).
- Contar el número de solicitudes (RPS).
- Identificar solicitudes lentas y errores.
- Observar el uso de memoria y CPU (a través de métricas JVM).
- Configurar alertas cuando se superen los umbrales.
Bibliotecas y dependencias
Para el funcionamiento se necesitarán las siguientes dependencias en build.gradle.kts:
dependencies { // Ktor Server implementation("io.ktor:ktor-server-core:2.3.7") implementation("io.ktor:ktor-server-netty:2.3.7")
// Plugin de métricas implementation("io.ktor:ktor-server-metrics-micrometer:2.3.7")
// Exportación a Prometheus implementation("io.micrometer:micrometer-registry-prometheus:1.12.0")
// Métricas JVM (opcional) implementation("io.micrometer:micrometer-core:1.12.0")}Configuración básica de Ktor Metrics
Veamos un ejemplo simple de un servidor con métricas. Crearemos el archivo Application.kt:
import io.ktor.server.application.*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.*import io.micrometer.prometheus.PrometheusMeterRegistryimport io.micrometer.prometheus.PrometheusConfig
fun main() { embeddedServer(Netty, port = 8080) { // Creamos el registro de métricas Prometheus val prometheusRegistry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT)
// Instalamos el plugin de métricas install(MicrometerMetrics) { registry = prometheusRegistry // Nombres de métricas por defecto meterBinders = listOf( // Agregamos métricas JVM io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics(), io.micrometer.core.instrument.binder.system.ProcessorMetrics() ) }
// Enrutamiento routing { // Endpoint para entregar métricas a Prometheus get("/metrics") { call.respond(prometheusRegistry.scrape()) }
// Endpoint de prueba get("/hello") { call.respondText("Hello, World!") }
// Endpoint con retardo artificial get("/slow") { Thread.sleep(500) call.respondText("Slow response") } } }.start(wait = true)}Después de iniciar el servidor, abra http://localhost:8080/metrics — verá las métricas en formato Prometheus:
# HELP ktor_http_server_requests_seconds # TYPE ktor_http_server_requests_seconds summaryktor_http_server_requests_seconds_count{method="GET",route="/hello",status="2xx"} 3.0ktor_http_server_requests_seconds_sum{method="GET",route="/hello",status="2xx"} 0.012# HELP jvm_memory_used_bytes # TYPE jvm_memory_used_bytes gaugejvm_memory_used_bytes{area="heap",id="G1 Survivor Space"} 1048576.0Configuración avanzada: métricas personalizadas
Puede agregar sus propios contadores y temporizadores. Por ejemplo, un contador de pedidos procesados:
import io.micrometer.core.instrument.Counterimport io.micrometer.core.instrument.MeterRegistry
También en la biblioteca
Generación de Swagger/OpenAPI para C++: revisión de herramientas y bibliotecas
Cliente HTTP para Java: revisión de las mejores bibliotecas (Java 11, Apache, OkHttp, Retrofit)
Cliente Redis para Java: Jedis, Lettuce y Redisson — descripción general y ejemplos
React para JavaScript (Node.js): guía completa con ejemplos
Validación de datos en Swift (iOS/macOS): mejores prácticas y herramientas