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
MetricsOps
implementation.MetricsOps
is an algebra located in theinternal-core
module with the needed operations for registering metrics. Mu provides two implementations, one forPrometheus
and another one forDropwizard
but you can provide your own. - A
MetricsServerInterceptor
. Mu provides an interceptor that receives aMetricsOps
as 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.