I am instrumenting my Sprint Boot application with AWS XRay which is working really nicely using aws-xray-recorder-sdk-spring
. However I'm only interested in the user interaction with my application, rather than the system health check, but I'm having trouble disabling the instrumentation of the health check.
From what I understand from the documentation, this should be controlled via a @Pointcut
. You can see below that I've tried to configure the @Pointcut
to exclude spring health checks via !within(org.springframework.boot.actuate.health.*)
, but the health check is still being instrumented, as you can see from the XRay debug logging below.
Does anyone know how I can achieve this?
@Aspect
@Component
public class XRayInspector extends BaseAbstractXRayInterceptor {
@Override
@Pointcut("@within(com.amazonaws.xray.spring.aop.XRayEnabled) && !springHealthChecks()")
public void xrayEnabledClasses() {
}
@Pointcut("within(org.springframework.boot.actuate.health.*)")
public void springHealthChecks() {
}
@Override
protected Map<String, Map<String, Object>> generateMetadata(ProceedingJoinPoint proceedingJoinPoint, Subsegment subsegment) {
return super.generateMetadata(proceedingJoinPoint, subsegment);
}
}
2023-05-05T14:40:10.710Z DEBUG 8 --- [io-8080-exec-10] com.amazonaws.xray.emitters.UDPEmitter : {
"name" : "Test Service",
"id" : "5bcf87b917b29e69",
"start_time" : 1.683297610683E9,
"trace_id" : "1-6455154a-b6544c2518e7bd28a18a3267",
"end_time" : 1.683297610709E9,
"http" : {
"request" : {
"method" : "GET",
"client_ip" : "127.0.0.1",
"url" : "http://localhost:8080/testservice/management/health",
"user_agent" : "curl/7.88.1"
},
"response" : {
"status" : 200
}
},
"aws" : {
"xray" : {
"sdk_version" : "2.9.1",
"sdk" : "X-Ray for Java"
}
},
"service" : {
"runtime_version" : "17.0.6",
"runtime" : "OpenJDK 64-Bit Server VM"
}
}
You can achieve this by extending AWSXRayServletFilter.class
and configuring you own filter. This way you can exclude endpoints you don't want to track
Exmaple code:
import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class XrayEndpointFilter extends AWSXRayServletFilter {
private final List<String> ignoredEndpoints;
XrayEndpointFilter(final List<String> ignoredEndpoints) {
super("appName");
this.ignoredEndpoints = ignoredEndpoints;
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws ServletException, IOException {
final String uri = ((HttpServletRequest) request).getRequestURI();
boolean shouldFilter = ignoredEndpoints.stream()
.map(Pattern::compile)
.map(pattern -> pattern.matcher(uri))
.anyMatch(Matcher::find);
if (shouldFilter) {
chain.doFilter(request, response);
} else {
super.doFilter(request, response, chain);
}
}
}