TODO this page looks fine but needs a review just in case
Metrics Reporting
Currently, Mu provides two different ways to monitor gRPC services: Prometheus and Dropwizard. The usage is quite similar for both.
Monitor Server Calls
In order to monitor the RPC calls on the server side we need two things:
- A
MetricsOpsimplementation.MetricsOpsis an algebra located in theinternal-coremodule with the needed operations for registering metrics. Mu provides two implementations, one forPrometheusand another one forDropwizardbut you can provide your own. - A
MetricsServerInterceptor. Mu provides an interceptor that receives aMetricsOpsas an argument and register server metrics.
Let’s see how to register server metrics using Prometheus in the following fragment.
import cats.effect.IO
import higherkindness.mu.rpc.prometheus.PrometheusMetrics
import higherkindness.mu.rpc.server._
import higherkindness.mu.rpc.server.interceptors.implicits._
import higherkindness.mu.rpc.server.metrics.MetricsServerInterceptor
import io.prometheus.client.CollectorRegistry
import service._
object InterceptingServerCalls extends CommonRuntime {
lazy val cr: CollectorRegistry = new CollectorRegistry()
implicit val greeterServiceHandler: ServiceHandler[IO] = new ServiceHandler[IO]
val server: IO[GrpcServer[IO]] = for {
metricsOps <- PrometheusMetrics.build[IO](cr, "server")
service <- Greeter.bindService[IO]
grpcConfig = AddService(service.interceptWith(MetricsServerInterceptor(metricsOps)))
server <- GrpcServer.default[IO](8080, List(grpcConfig))
} yield server
}
Monitor Client Calls
In this case, in order to intercept the client calls we need additional configuration settings (by using AddInterceptor):
import cats.effect.{IO, Resource}
import higherkindness.mu.rpc._
import higherkindness.mu.rpc.config._
import higherkindness.mu.rpc.channel._
import higherkindness.mu.rpc.channel.metrics.MetricsChannelInterceptor
import higherkindness.mu.rpc.config.channel._
import io.prometheus.client.CollectorRegistry
import service._
object InterceptingClientCalls extends CommonRuntime {
lazy val cr: CollectorRegistry = new CollectorRegistry()
implicit val serviceClient: Resource[IO, Greeter[IO]] =
for {
channelFor <- Resource.liftF(ConfigForAddress[IO]("rpc.host", "rpc.port"))
metricsOps <- Resource.liftF(PrometheusMetrics.build[IO](cr, "client"))
serviceClient <- Greeter.client[IO](
channelFor = channelFor,
channelConfigList = List(UsePlaintext(), AddInterceptor(MetricsChannelInterceptor(metricsOps))))
} yield serviceClient
}
That is how we use Prometheus to monitor both gRPC ends.
Dropwizard Metrics
The usage the same as before, but in this case we need to create a Dropwizard backed MetricsOps
import cats.effect.IO
import com.codahale.metrics.MetricRegistry
import higherkindness.mu.rpc.dropwizard.DropWizardMetrics
import com.codahale.metrics.MetricRegistry
val registry: MetricRegistry = new MetricRegistry()
val metricsOps = DropWizardMetrics[IO](registry)
To check the metrics from our server or client, Dropwizard exposes it through JMX. You’ll need the following dependency:
"io.dropwizard.metrics" % "metrics-jmx" % "4.0.5"
And to associate the reporter with the metrics registry on your project,
val jmxReporter = JmxReporter.forRegistry(registry)
jmxReporter.build().start()
More
For more details, in metrics integration with Mu you can check a full example about Mu metrics.