Logging Request/Responses in PlayFramework with Java

Viewed 11

I want to log every single request/response from PlayFramework services. I was following the documentation: here and I have created the Essential filter and the Filter in self and is not working. I have read some other posts from here, about configure and bind the Filter and I have tried too but is still not working.

I have added the play.http.filters = "filters.HttpFilters" in the application.config and this is the filter code:

package filters;

import java.util.concurrent.Executor;
import javax.inject.Inject;
import akka.util.ByteString;
import play.Logger;
import play.libs.streams.Accumulator;
import play.mvc.*;

public class EssentialLoggingFilter extends EssentialFilter {

    private final Executor executor;

    @Inject
    public EssentialLoggingFilter(Executor executor) {
        super();
        this.executor = executor;
    }

    @Override
    public EssentialAction apply(EssentialAction next) {
        return EssentialAction.of(request -> {
            long startTime = System.currentTimeMillis();
            Accumulator<ByteString, Result> accumulator = next.apply(request);
            return accumulator.map(result -> {
                long endTime = System.currentTimeMillis();
                long requestTime = endTime - startTime;

                Logger.info("{} {} took {}ms and returned {}",
                        request.method(), request.uri(), requestTime, result.status());

                return result.withHeader("Request-Time", "" + requestTime);
            }, executor);
        });
    }
}

and

package filters;

import play.http.DefaultHttpFilters;

public class HttpFilters extends DefaultHttpFilters {
    public HttpFilters(EssentialLoggingFilter filter) {
        super(filter);
    }
}

I have even try to bind the Filter like this:

bind(EssentialLoggingFilter.class).annotatedWith(Names.named("custom-http-filters"));

and I'm still having the same error:


    <p id="detail" class="pre">CreationException: Unable to create injector, see the following errors:

        1) No implementation for filters.HttpFilters (with no qualifier annotation) was bound, and could not find an
        injectable constructor. Injectable classes must have either one (and only one) constructor annotated with
        @Inject or a zero-argument constructor that is not private.
        at filters.HttpFilters.class(HttpFilters.java:7)
        at play.utils.Reflect$.bindingsFromConfiguration(Reflect.scala:78):
        Binding(class filters.HttpFilters to self) (via modules: com.google.inject.util.Modules$OverrideModule -&gt;
        play.api.inject.guice.GuiceableModuleConversions$$anon$4)

        2) No implementation for filters.EssentialLoggingFilter annotated with
        @com.google.inject.name.Named(value=custom-http-filters) was bound.
        at module.FZModule.configure(FZModule.java:58) (via modules: com.google.inject.util.Modules$OverrideModule -&gt;
        module.FZModule)

        2 errors</p>

What am I doing wrong? I'm just simply following the documentation.

1 Answers

Finally I was able to handle the answer by myself:

  1. Remove the bind config because it was no needed (bind(EssentialLoggingFilter.class).annotatedWith(Names.named("custom-http-filters"));)
  2. Inject the filter EssentialLoggingFilter in the contructor of HttpFilter like this:
public class HttpFilters extends DefaultHttpFilters {
    @Inject
    public HttpFilters(EssentialLoggingFilter filter) {
        super(filter);
    }
}

That solved my problem.

Related