Akka-http记录请求标识符

问题描述 投票:1回答:1

我一直在使用akka-http一段时间了,到目前为止,我主要通过扩展StrictLogging或LazyLogging然后调用以下内容来使用scala-logging记录事物:

log.info
log.debug
....

这有点好,但很难理解为哪个请求生成了哪些日志。

作为解决方案,我只看到:

  • 添加一个传递的隐式日志记录上下文(这有点冗长,会强迫我将此上下文添加到所有方法调用)+自定义记录器,它将上下文信息添加到日志消息中。
  • 使用MDC和自定义调度程序;为了实现这种方法,必须使用刚刚弃用的prepare()调用。
  • 使用AspectJ

还有其他更简单,更简洁的解决方案吗?可以通过btw更改日志库。

scala logging akka akka-http
1个回答
1
投票

我个人会采用隐式上下文方法。我先从:

(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最怀疑。如果我理解正确的话,它假设所有逻辑都发生在同一个线程中。如果你正在使用FuturesTasks,你真的能保证这样吗?我希望最好所有日志记录调用都发生在同一个线程池中,但不一定是相同的线程。

最重要的是,所有可能的位置都将是您已经想到的一些变体,所以问题是您的确切用例。

© www.soinside.com 2019 - 2024. All rights reserved.