我们一直在使用 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 字符串?