I am trying to create filters in a separate jar from my main spring boot project. One of them is the Trace filter in Actuator (the one which is executed when calling /trace), and I am configuring it to not tracing the calls to /trace itself. If I define the filter inside the project, it works perfectly and it does not trace the calls to /trace.
However, when I extract the class to another library and reference it from the main project, it is tracing those calls. I have checked that all references are correct, and the filter is being executed. However, I suspect that when initializing dependencies, both my filter and WebRequestTraceFilter (the class from my filter is inheriting) are being instantiated. This is the Filter class:
package common.api.filters.trace;
import org.springframework.boot.actuate.trace.TraceProperties;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.boot.actuate.trace.WebRequestTraceFilter;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
/**
* Class to exclude some some endpoints to be traced such as /admin/**, * /trace and
* endpoints provide static files like /css/** and /js/**.
*/
@Component
public class RequestTraceFilter extends WebRequestTraceFilter {
private static final String[] excludedEndpoints = new String[]{"/css/**", "/js/**", "/trace"};
public RequestTraceFilter(TraceRepository repository, TraceProperties properties) {
super(repository, properties);
}
/*
The default implementation was always returning false.
With this implementation, it returns true for the endpoints we don’t want to trace.
*/
@Override
protected boolean shouldNotFilter(final HttpServletRequest request) throws ServletException {
return Arrays
.stream(excludedEndpoints)
.anyMatch(e -> new AntPathMatcher().match(e, request.getServletPath()));
}
}
I also have tried to remove the tag @Component and initialize the Filter this way in a class tagged with @Configuration:
@Bean
public FilterRegistrationBean createTraceFilter(){
FilterRegistrationBean frb = new FilterRegistrationBean();
frb.setFilter(new RequestTraceFilter(new InMemoryTraceRepository(), new TraceProperties()));
return frb;
}
But the result is the same: filter is being executed but the calls to /trace are being traced.
How can I initialize my Filter in main project to be the only one that is executed when tracing?
I have found out what was happening: as I thought, there were being instantiated two classes: RequestTraceFilter and WebRequestTraceFilter. So, mine was being executed correctly, but WebRequestTraceFilter was also being executed and returning false in shouldNotFilter method, tracing the call to /trace itself. I have solved it changing the way I initialize dependencies this way:
@Bean
public WebRequestTraceFilter createTraceFilter(){
return new RequestTraceFilter(new InMemoryTraceRepository(), new TraceProperties());
}
So now, when Spring boot is asking an instance of WebRequestTraceFilter, it is returning only mine.