Carlos Teixeira
Carlos Teixeira

Reputation: 111

Akka-http logging request identifier

I've been using akka-http for a while now, and so far I've mostly logged things using scala-logging by extending either StrictLogging or LazyLogging and then calling the:

log.info
log.debug
....

This is kinda ok, but its hard to understand which logs were generated for which request.

As solutions for this go, I've only seen:

Are there any other solutions that are more straightforward and less verbose ? It would be ok to change the logging library btw..

Upvotes: 2

Views: 1243

Answers (1)

Mateusz Kubuszok
Mateusz Kubuszok

Reputation: 27595

Personally I would go with implicit context approach. I'd start with:

(path("api" / "test") & get) {
  val context = generateContext
  action(requestId)
}

Then I'd would make it implicit:

(path("api" / "test") & get) {
  implicit val context = generateContext
  action
}

Then I would make the context generation a directive, like e.g.:

val withContext: Directive1[MyContext] = Directive[Tuple1[MyContext]] {
  inner => ctx => inner(Tuple1(generateContext))(ctx)
}

withContext { implicit context =>
  (path("api" / "test") & get) {
     action
   }
}

Of course, you would have to take context as an implicit parameter to every action. But, it would have some advantages over MDC and AspectJ - it would be easier to test things, as you just need to pass value. Besides, who said you only ever need to pass request id and use it for logging? The context could as well pass data about logged in user, its entitlements and other things that you could resolve once, use even before calling action and reuse inside action.

As you probably guessed, this would not work if you want the ability to e.g. remove logging completely. In such case AspectJ would make more sense.

I would have most doubts with MDC. If I understand correctly it has build in assumption that all logic would happen in the same thread. If you are using Futures or Tasks, could you actually guarantee such thing? I would expect that at best all logging calls would happen in the same thread pool, but not necessarily the same thread.

Bottom line is, all possible posiltions would be some variant of what you already figured out, so the question is your exact use case.

Upvotes: 1

Related Questions