我一直在使用akka-http一段时间了,到目前为止,我主要通过扩展StrictLogging或LazyLogging然后调用以下内容来使用scala-logging记录事物:
log.info
log.debug
....
这有点好,但很难理解为哪个请求生成了哪些日志。
作为解决方案,我只看到:
还有其他更简单,更简洁的解决方案吗?可以通过btw更改日志库。
我个人会采用隐式上下文方法。我先从:
(path("api" / "test") & get) {
val context = generateContext
action(requestId)
}
然后我会隐瞒它:
(path("api" / "test") & get) {
implicit val context = generateContext
action
}
然后我会将上下文生成一个指令,例如:
val withContext: Directive1[MyContext] = Directive[Tuple1[MyContext]] {
inner => ctx => inner(Tuple1(generateContext))(ctx)
}
withContext { implicit context =>
(path("api" / "test") & get) {
action
}
}
当然,您必须将上下文作为每个操作的隐式参数。但是,它会比MDC和AspectJ有一些优势 - 它会更容易测试,因为你只需要传递价值。此外,谁说你只需要传递请求ID并用它来记录?上下文还可以传递有关登录用户,其权利以及您可以解决一次的其他事项的数据,甚至在调用操作和重用内部操作之前使用。
正如你可能猜到的那样,如果你想要这样的能力,这将不起作用。完全删除日志记录在这种情况下,AspectJ会更有意义。
我对MDC最怀疑。如果我理解正确的话,它假设所有逻辑都发生在同一个线程中。如果你正在使用Futures
或Tasks
,你真的能保证这样吗?我希望最好所有日志记录调用都发生在同一个线程池中,但不一定是相同的线程。
最重要的是,所有可能的位置都将是您已经想到的一些变体,所以问题是您的确切用例。