播放 2.6.x 日志记录请求正文和处理时间



我正在使用播放服务器 2.6.x 并尝试记录每个请求的请求正文和处理时间。

问题是,如果我使用 PlayFilterapi,我无权访问请求正文,如果我使用 playActionapi 将操作包装为LoggingAction我可以访问正文但无法获得响应时间,所以我必须同时使用它们并为每个请求创建一个唯一的 ID 并按请求 ID 更新日志。

在我看来,必须有更优雅的解决方案。

有同样的问题 - 找到答案并非易事 - 看看play.test.Helpers类 - 你有方法可以实现这一点。

使用哪一个将取决于您是否可以访问材质化器和/或您在哪里/如何执行日志。如果是筛选器或操作。

就我而言,我将其用作操作,符合我类似要求的代码是: ```

@Override
public CompletionStage<Result> call(Http.Context context) {
if(environment.isProd()) {
//let's just not log anything
delegate.call(context);
}
CompletionStage<Result> callResult = null;
try {

Http.RequestBody body = context.request().body();
final String basicCallIdentifier = "Call: " + context.request().method() + ":"  + context.request().uri();
String requestMessage = "Request - " + basicCallIdentifier;
if(body != null) {
requestMessage +=   " body: " + body.asText();
}
LOG.debug(requestMessage);
callResult = delegate.call(context);
return callResult.whenComplete((result, throwable) -> {
String resultMessage = "Response - " + basicCallIdentifier + ":";
if(result == null) {
resultMessage += " Null result!";
LOG.debug(resultMessage, throwable);
} else {
resultMessage += " Status: " +result.status();
HttpEntity resultBody = result.body();
if(resultBody != null
&& resultBody.contentType().isPresent()
&& resultBody.contentType().get().contains("json")) {
HttpEntity.Strict resultBodyStrict = (HttpEntity.Strict) resultBody;
ByteString byteString = resultBodyStrict.data();
resultMessage +=  " body: " + byteString.decodeString("UTF-8");
}
LOG.debug(resultMessage, throwable);
}
});

} catch(Exception ex) {
LOG.error("Caught exception on APILogAction", ex);
if(callResult == null) {
callResult = delegate.call(context);
}
return callResult;
}

}

'''

我也找到了问题的答案,在我看来这更容易一些,所以我会分享它。

它涉及创建自己的Action,以便能够分析请求正文,并记录所有标头。

case class LoggingAction @Inject(override val parser: BodyParsers.Default)(implicit ec:ExecutionContext) extends ActionBuilderImpl(parser){
override def invokeBlock[A](request: Request[A], invoke: (Request[A] => Future[Result])): Future[Result] ={
val startTime = System.currentTimeMillis
try {
invoke(request).map(res => {
val processTime: Long = System.currentTimeMillis - startTime
Logger.log(request,time)
res
})
} catch {
// Throw some error...
}
}
}

最新更新