Home > front end >  How to integrate Prometheus Metrics Middleware with http4s DSL service
How to integrate Prometheus Metrics Middleware with http4s DSL service

Time:02-19

To analyze the performance issues with our ember-server, Trying to get the server metrics on prometheus using the document mentioned here: https://http4s.org/v0.23/middleware/

build.sbt

      "org.http4s"            %% "http4s-ember-server"       % "0.23.1",
      "org.http4s"            %% "http4s-blaze-client"       % "0.23.1",
      "org.http4s"            %% "http4s-dsl"                % "0.23.1",
      "org.http4s"            %% "http4s-prometheus-metrics" % "0.23.1"

Sample code:

import cats.effect._
import org.http4s.metrics.prometheus.Prometheus
import io.prometheus.client.CollectorRegistry
import org.http4s.server.middleware.Metrics

// build router
val testRoute: Resource[IO, HttpRoutes[IO]] = Prometheus
    .metricsOps[IO](registry, "server")
    .map(ops =>
         Metrics[IO](ops)( {
            val dsl = new Http4sDsl[IO] {}
            import dsl._
            HttpRoutes.of[IO] { 
                case req @ POST -> Root / "test" => 
                  OK("test Ok!")
                case _: Exception =>
                  InternalServerError()
             }
           )
        )
     )

// build server with the router
EmberServerBuilder
  .default[IO]
  .withHost(Host.fromString("0.0.0.0").get)
  .withPort(Port.fromInt(8080).get)
  .withHttpApp(testRoute.orNotFound)
  .build

  1. Getting compilation error at .withHttpApp(testRoute.orNotFound) which is expected but not sure of the solution. This is a working example without Prometheus and Metrics wrapping.
  2. Definitely this is a compatibility issue but not sure how to wrap the middleware (which is not supposed to change the return type from HttpRoutes[IO] to Resource[IO, HttpRoutes[IO]] that is happening while wrapping the test Route.

I'm newbie to the functional way of programming (and so to the Scala, Cats lib and http4s) and this all generics seems to be too much confusing.

CodePudding user response:

try:

// build server with the router
testRoute.flatMap { route =>
  EmberServerBuilder
    .default[IO]
    .withHost(Host.fromString("0.0.0.0").get)
    .withPort(Port.fromInt(8080).get)
    .withHttpApp(route.orNotFound)
    .build
}

You need to compose the Resource[IO, HttpRoutes[IO]] from prometheus with the Resource[IO, Server] from http4s.

  • Related