Hello All,
I’m trying to create a filter to log request and response. Is there a way to log result body in the filter?
Hello All,
I’m trying to create a filter to log request and response. Is there a way to log result body in the filter?
In Java or in Scala?
Hi, Looking for in Java
I haven’t used Java with Play in a while, but looking at the latest documentation, I would start with
Then you could check wether the request header is an instance of Request. And if so, ask for the request body via Request’s body() method:
https://www.playframework.com/documentation/2.8.x/api/java/play/mvc/Http.Request.html
Sounds like what you need is a custom ActionCreator
.
import akka.util.ByteString;
import play.http.DefaultActionCreator;
import play.http.HttpEntity;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;
import javax.inject.Inject;
import java.lang.reflect.Method;
import java.util.Optional;
import java.util.concurrent.CompletionStage;
public class CustomActionCreator extends DefaultActionCreator {
@Inject
public CustomActionCreator() {}
@Override
public Action.Simple createAction(Http.Request request, Method actionMethod) {
Optional.ofNullable(request.body())
.map(Http.RequestBody::asBytes)
.map(ByteString::toArray)
.ifPresent(requestBodyBytes -> {
// Do what you want with it
});
return new Action.Simple() {
@Override
public CompletionStage<Result> call(Http.Request request) {
return delegate.call(request).thenApply(result -> {
final HttpEntity body = result.body();
if (body instanceof HttpEntity.Strict) {
final byte[] responseBodyBytes = ((HttpEntity.Strict) body).data().toArray();
// do what you want with it
}
return result;
});
}
};
}
}
For obvious reasons, this will only works with in-memory bodies.
Thanks @slisaasquatch . I’ve been looking around trying to figure this out. With the HttpEntity body does this work only with Entity strict , how do you if body is instanceof Chunked entity? Is there a way to log result body for other entity types?
The fundamental problem with Chunked is that it’s not in-memory, so there isn’t a good way of logging it. The same restriction applies to the request body as well. If the request body is not in-memory, Http.RequestBody::asBytes
will return null
.
Thanks for you help @slisaasquatch . I was trying to figure out a way to actually log response body but I suppose like you mentioned there’s no good way
I’d say logging in-memory request and response bodies is already pretty good. If your requests are things like in-memory JSON or byte array, and if your responses are things like ok(String)
or ok(JsonNode)
, then those are all guaranteed to be in-memory, and my solution should work. The problem is only when you handle things like streams or files.