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

时间:2017-08-08 13:31:17

标签: scala playframework

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

问题是,如果我使用Play Filter api,我无法访问请求正文,如果我使用play Action api进行换行作为LoggingAction的操作我可以访问正文,但无法获得响应时间,因此我必须同时使用它们并为每个请求创建唯一的ID并按请求ID更新日志。

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

2 个答案:

答案 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...
    }
  }
}