我正在使用播放服务器2.6.x并尝试记录请求正文和每个请求的处理时间。
问题是,如果我使用Play Filter
api,我无法访问请求正文,如果我使用play Action
api进行换行作为LoggingAction
的操作我可以访问正文,但无法获得响应时间,因此我必须同时使用它们并为每个请求创建唯一的ID并按请求ID更新日志。
在我看来,必须有更优雅的解决方案。
答案 0 :(得分:0)
有相同的问题-找到答案并非易事-看一下play.test.Helpers类-您那里有实现此目的的方法。
使用哪个取决于您是否有权访问Materializer,以及/或者在何处/如何执行日志。是过滤器还是操作。
就我而言,我将其用作Action,并且符合我类似要求的代码是: ```
@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;
}
}
```
答案 1 :(得分:0)
我也找到了我问题的答案,在我看来,这要容易一些,所以我将与大家分享。
它涉及创建自己的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...
}
}
}