natchez-http4s icon indicating copy to clipboard operation
natchez-http4s copied to clipboard

Custom Request/Response/Error Tracers

Open gerryfletch opened this issue 3 years ago • 0 comments

Description

It would be useful to be able to provide custom tracers, of the form:

  • Request[F] => F[Unit]
  • Response[F] => F[Unit]
  • Throwable => F[Unit]

Use Case

  • Trace the request+response body based on Content-Type encoding and, for example, do-not-trace headers
  • Write non-sensitive HTTP headers as trace properties
  • Custom traces based on Throwable properties for monitoring & alerting

API Suggestion

def server[F[_]: Trace](
  routes: HttpRoutes[F],
  withRequestTracer: Option[Request[F] => F[Unit]] = None,
  withResponseTracer: Option[Response[F] => F[Unit]] = None,
  withErrorTracer: Option[Throwable => F[Unit]] = None
)(
  implicit ev: MonadCancel[F, Throwable]
): HttpRoutes[F] =
  Kleisli { req =>
    val additionalRequestTracer = withRequestTracer.getOrElse((_: Request[F]) => ().pure[F])
    val additionalResponseTracer = withResponseTracer.getOrElse((_: Response[F]) => ().pure[F])
    val additionalErrorTracer = withErrorTracer.getOrElse((_: Throwable) => ().pure[F])
    // ...
    val addRequestFields: F[Unit] =
      Trace[F].put(
        Tags.http.method(req.method.name),
        Tags.http.url(req.uri.renderString),
      ) *> additionalRequestTracer(req)
     // etc    

gerryfletch avatar Nov 15 '21 21:11 gerryfletch