Monitoring Kotlin Applications: Ktor Metrics and Micrometer Library

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Monitoring Kotlin Applications: Ktor Metrics and Micrometer



Modern server-side Kotlin applications built on the Ktor framework require constant monitoring of performance and status. For this purpose, a combination of two powerful tools is used: Ktor Metrics Plugin (a built-in Ktor module) and Micrometer (a facade for collecting metrics). In this article, we will cover how to set up monitoring with data export to Prometheus and visualization in Grafana.



Why is monitoring needed?

Monitoring allows you to:

  • Track endpoint response time (latency).
  • Count the number of requests (RPS).
  • Identify slow requests and errors.
  • Monitor memory and CPU usage (via JVM metrics).
  • Configure alerts when thresholds are exceeded.


Libraries and Dependencies

The following dependencies are required in build.gradle.kts:



dependencies {    // Ktor Server    implementation("io.ktor:ktor-server-core:2.3.7")    implementation("io.ktor:ktor-server-netty:2.3.7")

// Metrics Plugin implementation("io.ktor:ktor-server-metrics-micrometer:2.3.7")

// Prometheus Export implementation("io.micrometer:micrometer-registry-prometheus:1.12.0")

// JVM Metrics (optional) implementation("io.micrometer:micrometer-core:1.12.0")}


Basic Ktor Metrics Configuration

Let's look at a simple server example with metrics. Create a file 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) { // Create a Prometheus metric registry val prometheusRegistry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT)

// Install the metrics plugin install(MicrometerMetrics) { registry = prometheusRegistry // Default metric names meterBinders = listOf( // Add JVM metrics io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics(), io.micrometer.core.instrument.binder.system.ProcessorMetrics() ) }

// Routing routing { // Endpoint for serving Prometheus metrics get("/metrics") { call.respond(prometheusRegistry.scrape()) }

// Test endpoint get("/hello") { call.respondText("Hello, World!") }

// Endpoint with artificial delay get("/slow") { Thread.sleep(500) call.respondText("Slow response") } } }.start(wait = true)}


After starting the server, open http://localhost:8080/metrics — you will see metrics in Prometheus format:



# 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.0


Advanced Configuration: Custom Metrics

You can add your own counters and timers. For example, a counter for processed orders:



import io.micrometer.core.instrument.Counterimport io.micrometer.core.instrument.MeterRegistry

Recommendations