What's the best way to pass a common request identifier across a chain of Filter/Services for logging in Finagle/Scala?

163 views Asked by At

We use a lot of Finagle Filters and Services in our code. However, we don't support Zipkin in our infrastructure. At times there's a need to trace an incoming request across the chain of Filters/Services, especially in the face of concurrent requests. What's the most non-intrusive way to get such a functionality?

Goal: Would be great if Finagle itself provided an additional apply method like so:

def apply(request: ReqIn, service: Service[ReqOut, RepIn], traceId: String): Future[RepOut]

Then the subclasses could opt-in to using this method instead. The last argument being the identifier that every Filter/Service in the chain could "append to".

override def apply(request, service, traceId): Future[...] = {
  val myTrace = traceId+".me2" // can be logged if needed
  service.apply(..., myTrace)
}

Example:

val chain = FilterA andThen FilterB andThen ServiceP

val response = chain(request, UUID.randomString) // need a way to "seed the request chain with unique string"

The goal is to have something that can uniquely trace/log the series of filter/services effectively. How may I go about by extending Finagle via traits/monkey-patching? Or is this not doable?

1

There are 1 answers

1
fusion On

This can be done using Finagle's Contexts.

Contexts give you access to request-scoped state, such as a request’s deadline, throughout the logical life of a request without requiring them to be explicitly passed