如何使用 logRequestResult 记录请求和响应主体

时间:2021-07-23 13:52:02

标签: scala akka-http

我们一直在使用 logRequestResult 来记录经过的时间以及 URI 和方法,没有问题,但是我一直在尝试从流中获取响应和请求正文。我最近的尝试是使用 toStrict 将它们转换为字符串,并在两者都准备好后记录:

val logTimeout = FiniteDuration(900, MILLISECONDS)

def logParts(requestTime: Long)(req: HttpRequest)(res: RouteResult): Unit =
  res match {
    case RouteResult.Complete(httpResp) =>
      val futureReqBody = req.entity.toStrict(logTimeout).map(_.data).map(_.utf8String)
      val futureResBody = httpResp.entity.toStrict(logTimeout).map(_.data).map(_.utf8String)
      (for {
        reqBody <- futureReqBody
        resBody <- futureResBody
      } yield (reqBody, resBody)).foreach { case (reqBody, resBody) =>
        // This is grizzled.slf4j.Logger.info
        info(s"%s %s".format(reqBody, resBody)
      )}
    case RouteResult.Rejected(_) => warn(s"Request ${req.method.value} ${req.uri} rejected")
  }

private val withLogging = DebuggingDirectives.logRequestResult(LoggingMagnet(_ => {
  val requestTime = System.currentTimeMillis()
  logParts(requestTime)
}))

我可以看到正在生成的日志,但是输出的不是纯文本,而是一堆字节,并且还抛出了以下异常:

java.lang.NullPointerException: Deflater has been closed
    at java.base/java.util.zip.Deflater.ensureOpen(Deflater.java:898)
    at java.base/java.util.zip.Deflater.deflate(Deflater.java:566)
    at java.base/java.util.zip.Deflater.deflate(Deflater.java:484)
    at akka.http.scaladsl.coding.DeflateCompressor$.drainDeflater(Deflate.scala:94)
    at akka.http.scaladsl.coding.DeflateCompressor.compressWithBuffer(Deflate.scala:59)
    at akka.http.scaladsl.coding.GzipCompressor.compressWithBuffer(Gzip.scala:50)
    at akka.http.scaladsl.coding.DeflateCompressor.compressAndFlush(Deflate.scala:45)
    at akka.http.scaladsl.coding.Encoder.encodeChunk$1(Encoder.scala:38)
    at akka.http.scaladsl.coding.Encoder.$anonfun$newEncodeTransformer$1(Encoder.scala:41)
    at akka.http.impl.util.StreamUtils$$anon$1$$anon$2.onPush(StreamUtils.scala:39)
    at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:523)
    at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:510)
    at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:376)
    at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:606)
    at akka.stream.impl.fusing.GraphInterpreterShell.init(ActorGraphInterpreter.scala:576)
    at akka.stream.impl.fusing.ActorGraphInterpreter.tryInit(ActorGraphInterpreter.scala:682)
    at akka.stream.impl.fusing.ActorGraphInterpreter.finishShellRegistration(ActorGraphInterpreter.scala:725)
    at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$shortCircuitBatch(ActorGraphInterpreter.scala:740)
    at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:765)
    at akka.actor.Actor.aroundReceive(Actor.scala:539)
    at akka.actor.Actor.aroundReceive$(Actor.scala:537)
    at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:671)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:612)
    at akka.actor.ActorCell.invoke(ActorCell.scala:581)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:268)
    at akka.dispatch.Mailbox.run(Mailbox.scala:229)
    at akka.dispatch.Mailbox.exec(Mailbox.scala:241)
    at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

我不确定问题出在哪里。我是否正在使用流,这就是抛出异常的原因?如果是这样,为什么日志没有按要求显示 UTF-8 字符串?

0 个答案:

没有答案