Application monitoring is an essential thing to keep the application available every time. We can do application monitoring through multiple ways such as through healthcheck endpoint, exposing metrics etc. Here, in this blog, we will see, how we can expose the metrics in Prometheus format for an Akka HTTP application.
First, we need to add below maven dependency in pom.xml:
<dependency>
<groupId>fr.davit</groupId>
<artifactId>akka-http-metrics-prometheus_2.12</artifactId>
<version>1.1.1</version>
</dependency>
Then, we need to create a MetricController where we need to create a registry and the route for the metrics:
MetricsController:
import akka.http.scaladsl.server.Directives.{path, _}
import akka.http.scaladsl.server.Route
import fr.davit.akka.http.metrics.core.scaladsl.server.HttpMetricsDirectives.metrics
import fr.davit.akka.http.metrics.prometheus.marshalling.PrometheusMarshallers._
import fr.davit.akka.http.metrics.prometheus.{Buckets, PrometheusRegistry, PrometheusSettings, Quantiles}
import io.prometheus.client.CollectorRegistry
class MetricsController {
import MetricsController._
val route: Route = (get & path("admin" / "prometheus" / "metrics")) (metrics(registry))
}
object MetricsController {
val routes: Route = new MetricsController().route
private val settings: PrometheusSettings = PrometheusSettings
.default
.withIncludePathDimension(true)
.withIncludeMethodDimension(true)
.withIncludeStatusDimension(true)
.withDurationConfig(Buckets(1, 2, 3, 5, 8, 13, 21, 34))
.withReceivedBytesConfig(Quantiles(0.5, 0.75, 0.9, 0.95, 0.99))
.withSentBytesConfig(PrometheusSettings.DefaultQuantiles)
.withDefineError(_.status.isFailure)
private val collector: CollectorRegistry = CollectorRegistry.defaultRegistry
val registry: PrometheusRegistry = PrometheusRegistry(collector, settings)
}
After this, we need to make the change in the main application file:
Application:
val routes = ApiController.routes ~ MetricsController.routes
val routesWithMetrics = HttpMetricsRoute(routes).recordMetrics(MetricsController.registry)
val bindingFuture = Http().bindAndHandle(routesWithMetrics, "0.0.0.0", 8080)
That’s it. We are done.
Now run the application and hit the below url:
http://localhost:8080/admin/prometheus/metrics
and you will see the metrics as below:
You can see that we are getting metrics as unlabelled for the path. If we have multiple APIs in our service then we would like to label the metrics so that we can easily differentiate the metrics. For that you need to use pathLabeled directive as follows:
pathLabeled("message", "message") {
complete(StatusCodes.OK, "This is an application to show the way to expose the Prometheus metrics")
}
First parameter is the label and second parameter is the path.
Now you will get the metrics as follows:
I have used the Prometheus format for the metrics, there are some more formats available in which we can expose the metrics. For more details see here.
I hope, this will be helpful for you guys. Feel free to give your suggestions as the comment to this blog.
References: