Introducción: Por qué el monitoreo es vital para las aplicaciones Kotlin
\nLas aplicaciones Kotlin modernas, que se ejecutan en la JVM (Java Virtual Machine), a menudo se convierten en nodos críticos de la infraestructura. Sin un monitoreo adecuado, corre el riesgo de enfrentar fallos repentinos, fugas de memoria o degradación del rendimiento que pasarán desapercibidos hasta el momento del incidente. En este artículo, analizaremos cómo construir un sistema completo de monitoreo de aplicaciones Kotlin «de la A a la Z»: desde la recopilación de métricas básicas (CPU, memoria, GC) hasta la configuración de alertas en Grafana y Prometheus.
\nAnalizaremos tres herramientas clave: Micrometer (fachada para métricas), Prometheus (almacenamiento y recolector) y Grafana (visualización y alertas). Todos los ejemplos de código están escritos en Kotlin.
\n\n1. Fundamentos de la recopilación de métricas: Micrometer y Prometheus
\nMicrometer es, de facto, la fachada estándar para el monitoreo en el ecosistema Spring y Kotlin. Proporciona una API unificada para enviar métricas a varios sistemas (Prometheus, Datadog, New Relic, etc.).
\n\n1.1. Adición de dependencias (Gradle)
\ndependencies {\n implementation("io.micrometer:micrometer-registry-prometheus:1.12.0")\n implementation("org.springframework.boot:spring-boot-starter-actuator")\n}\nPara Ktor o Kotlin puro sin Spring, puede agregar solo micrometer-core y micrometer-registry-prometheus.
1.2. Configuración básica de Micrometer en Spring Boot
\nEn application.yml, simplemente habilite Actuator y el endpoint de Prometheus:
management:\n endpoints:\n web:\n exposure:\n include: health,info,prometheus\n metrics:\n export:\n prometheus:\n enabled: true\nDespués de iniciar la aplicación, las métricas estarán disponibles en /actuator/prometheus.
1.3. Creación de métricas personalizadas (ejemplo en Kotlin)
\nSupongamos que desea contar la cantidad de pedidos procesados y su tiempo de procesamiento:
\nimport io.micrometer.core.instrument.MeterRegistry\nimport io.micrometer.core.instrument.Timer\nimport org.springframework.stereotype.Service\nimport java.util.concurrent.atomic.AtomicLong\n\n@Service\nclass OrderService(private val registry: MeterRegistry) {\n\n private val processedOrders: AtomicLong = registry.gauge(\n "orders.processed.count",\n AtomicLong(0)\n )\n private val orderProcessingTime: Timer = registry.timer("orders.processing.time")\n\n fun processOrder(orderId: String) {\n val sample = Timer.start()\n try {\n // Lógica de procesamiento del pedido\n Thread.sleep((50..200).random().toLong())\n processedOrders.incrementAndGet()\n } finally {\n sample.stop(orderProcessingTime)\n }\n }\n}\nAhora las métricas orders_processed_count y orders_processing_time_seconds aparecerán en Prometheus.
2. Configuración de Prometheus para la recopilación de métricas
\nPrometheus es un servidor que «raspa» (solicita) métricas de sus aplicaciones según un cronograma.
\n\n2.1. Configuración de prometheus.yml
\nAgregue su servicio Kotlin como objetivo (target):
\nscrape_configs:\n - job_name: 'kotlin-app'\n metrics_path: '/actuator/prometheus'\n static_configs:\n - targets: ['localhost:8080']\nSi la aplicación se ejecuta en Docker/Kubernetes, utilice el descubrimiento de servicios.
\n\n2.2. Métricas JVM importantes por defecto
\nMicrometer exporta automáticamente muchas métricas de la JVM:
\n- \n
jvm_memory_used_bytes— memoria utilizada (heap/no heap) \n jvm_gc_pause_seconds— tiempo de pausas del GC \n jvm_threads_live_threads— número de hilos activos \n process_cpu_usage— uso de CPU por el proceso \n
Estos datos ya están disponibles en Prome