/
ServletTraceFilter.java
137 lines (117 loc) · 5.07 KB
/
ServletTraceFilter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package com.github.kristofa.brave.jersey;
import com.github.kristofa.brave.BraveHttpHeaders;
import com.github.kristofa.brave.EndpointSubmitter;
import com.github.kristofa.brave.IdConversion;
import com.github.kristofa.brave.ServerTracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* Servlet filter that will extract trace headers from the request and send
* sr (server received) and ss (server sent) annotations.
*/
@Singleton
public class ServletTraceFilter implements Filter {
private static Logger logger = LoggerFactory.getLogger(ServletTraceFilter.class);
private final ServerTracer serverTracer;
private final EndpointSubmitter endpointSubmitter;
@Inject
public ServletTraceFilter(ServerTracer serverTracer, EndpointSubmitter endpointSubmitter) {
this.serverTracer = serverTracer;
this.endpointSubmitter = endpointSubmitter;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
boolean traceEstablished = tryEstablishServerTrace(request);
chain.doFilter(request, response);
if (traceEstablished) {
finalizeServerTrace();
}
}
/**
* Clear current span and perhaps start a new one. We do this all in a try/catch so that
* we are safe by default.
*
* @return true if we were able to establish a trace without exception
*/
private boolean tryEstablishServerTrace(ServletRequest request) {
try {
serverTracer.clearCurrentSpan();
if (request instanceof HttpServletRequest) {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
submitEndpoint(httpServletRequest);
TraceData traceData = getTraceDataFromHeaders(httpServletRequest);
if (Boolean.FALSE.equals(traceData.shouldBeTraced())) {
serverTracer.setStateNoTracing();
logger.debug("Not tracing request");
} else {
String spanName = getSpanName(traceData, httpServletRequest);
if (traceData.getTraceId() != null && traceData.getSpanId() != null) {
logger.debug("Received span information as part of request");
serverTracer.setStateCurrentTrace(traceData.getTraceId(), traceData.getSpanId(),
traceData.getParentSpanId(), spanName);
} else {
logger.debug("Received no span state");
serverTracer.setStateUnknown(spanName);
}
}
}
serverTracer.setServerReceived();
return true;
} catch (Exception e) {
logger.warn("Exception establishing server trace", e);
return false;
}
}
private void finalizeServerTrace() {
try {
serverTracer.setServerSend();
} catch (Exception e) {
logger.warn("Exception finalizing server trace", e);
}
}
private void submitEndpoint(HttpServletRequest request) {
if (!endpointSubmitter.endpointSubmitted()) {
String contextPath = request.getContextPath();
String localAddr = request.getLocalAddr();
int localPort = request.getLocalPort();
endpointSubmitter.submit(localAddr, localPort, contextPath);
logger.debug("Setting endpoint: addr: {}, port: {}, contextpath: {}", localAddr, localPort, contextPath);
}
}
private String getSpanName(TraceData traceData, HttpServletRequest request) {
if (traceData.getSpanName() == null || traceData.getSpanName().isEmpty()) {
return request.getRequestURI();
}
return traceData.getSpanName();
}
private TraceData getTraceDataFromHeaders(HttpServletRequest httpRequest) {
TraceData traceData = new TraceData();
traceData.setTraceId(longOrNull(httpRequest.getHeader(BraveHttpHeaders.TraceId.getName())));
traceData.setSpanId(longOrNull(httpRequest.getHeader(BraveHttpHeaders.SpanId.getName())));
traceData.setParentSpanId(longOrNull(httpRequest.getHeader(BraveHttpHeaders.ParentSpanId.getName())));
traceData.setShouldBeSampled(nullOrBoolean(httpRequest.getHeader(BraveHttpHeaders.Sampled.getName())));
traceData.setSpanName(httpRequest.getHeader(BraveHttpHeaders.SpanName.getName()));
return traceData;
}
private Boolean nullOrBoolean(String value) {
return (value == null) ? null : Boolean.valueOf(value);
}
private Long longOrNull(String value) {
if (value == null) {
return null;
}
return IdConversion.convertToLong(value);
}
@Override
public void destroy() {
}
}