Metrics Reporting
Currently, frees-rpc provides two different ways to monitor gRPC services: Prometheus
and Dropwizard
(using the Prometheus
extension). The usage is quite similar for both.
Monitor Server Calls
In order to monitor the RPC calls on the server side, it’s necessary to intercept them. We’ll see how to do this in the next code fragment:
import cats.~>
import cats.effect.IO
import freestyle.rpc.server._
import freestyle.rpc.server.handlers._
import freestyle.rpc.server.implicits._
import freestyle.rpc.prometheus.shared.Configuration
import freestyle.rpc.prometheus.server.MonitoringServerInterceptor
import io.prometheus.client.CollectorRegistry
import service._
object InterceptingServerCalls extends CommonRuntime {
import freestyle.rpc.interceptors.implicits._
lazy val cr: CollectorRegistry = new CollectorRegistry()
lazy val monitorInterceptor = MonitoringServerInterceptor(
Configuration.defaultBasicMetrics.withCollectorRegistry(cr)
)
implicit val greeterServiceHandler: ServiceHandler[IO] = new ServiceHandler[IO]
// The Greeter service is the service defined in the Core concepts section
val grpcConfigs: List[GrpcConfig] = List(
AddService(Greeter.bindService[IO].interceptWith(monitorInterceptor))
)
val server: IO[GrpcServer[IO]]= GrpcServer.default[IO](8080, grpcConfigs)
}
Monitor Client Calls
In this case, in order to intercept the client calls we need additional configuration settings (by using AddInterceptor
):
import cats.implicits._
import cats.effect.IO
import freestyle.rpc._
import freestyle.rpc.config._
import freestyle.rpc.client._
import freestyle.rpc.client.config._
import freestyle.rpc.client.implicits._
import monix.eval.Task
import io.grpc.ManagedChannel
import service._
import scala.util.{Failure, Success, Try}
import freestyle.rpc.prometheus.shared.Configuration
import freestyle.rpc.prometheus.client.MonitoringClientInterceptor
object InterceptingClientCalls extends CommonRuntime {
val channelFor: ChannelFor =
ConfigForAddress[IO]("rpc.host", "rpc.port").unsafeRunSync
implicit val serviceClient: Greeter.Client[Task] =
Greeter.client[Task](
channelFor = channelFor,
channelConfigList = List(
UsePlaintext(),
AddInterceptor(
MonitoringClientInterceptor(
Configuration.defaultBasicMetrics
)
)
)
)
}
That’s using Prometheus
to monitor both gRPC ends.
Dropwizard Metrics
The usage is equivalent, however, in this case, we need to put an instance of com.codahale.metrics.MetricRegistry
on the scene, then, using the Dropwizard integration that Prometheus already provides (DropwizardExports
) you can associate it with the collector registry:
import com.codahale.metrics.MetricRegistry
import io.prometheus.client.dropwizard.DropwizardExports
val metrics: MetricRegistry = new MetricRegistry
val configuration: Configuration = Configuration.defaultBasicMetrics
configuration.collectorRegistry.register(new DropwizardExports(metrics))