Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide call that lifts http4s client into trace context without creating new span #47

Open
Tracked by #662
fiadliel opened this issue Dec 1, 2021 · 1 comment

Comments

@fiadliel
Copy link

fiadliel commented Dec 1, 2021

There is a possible minimal implementation of tracing for a http4s client, which is to lift the context to one allowing tracing, and also forwards the tracing headers; but otherwise does not create a new span or decorate the current span.

Reasons?

  • Firstly, it's a valid use case to not want the client to create a span. Maybe there are issues with forwarding trace data for this particular service, or the extra span adds unneeded extra information. However, you will still want to forward headers, so that downstream and upstream services can still be connected for the larger trace.
  • Secondly, the creation of span attributes can be something that users want to customize. E.g. if you want to match OpenTelemetry attribute names, amongst other things. By putting the monad lifting into one place, it makes adding custom behavior much simpler, as you can just use Trace[F].span etc. inside your application code. It's basically a nice building block for custom client tracing schemes.

Example code - doesn't have a Ctx parameter, but shows the general idea:

  def liftTrace[F[_]: MonadCancelThrow, G[_]: MonadCancelThrow](
      client: Client[F],
      toHeaders: ToHeaders = ToHeaders.standard
  )(implicit P: Provide[F, G, Span[F]]): Client[G] =
    Client { (request: Request[G]) =>
      Resource.eval(P.ask).flatMap { span =>
        val traceHeaders = toHeaders
          .fromContext(span.context)
          .values
          .map(Header.Raw.apply)
          .toList

        client
          .run(
            request
              .transformHeaders(_ ++ Headers(traceHeaders))
              .mapK(P.provideK(span))
          )
          .mapK(P.liftK)
          .map(_.mapK(P.liftK))
      }
    }
@catostrophe
Copy link
Member

IMO any outgoing call should have an explicit span. But I accept that users can decide for themselves.
PR is welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants