-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: read the TraceId from Header and propagate it
- Loading branch information
1 parent
610d886
commit 7be440e
Showing
9 changed files
with
337 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
src/main/java/ch/bfh/ti/i4mi/mag/CustomPropagationFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package ch.bfh.ti.i4mi.mag; | ||
|
||
import brave.propagation.B3Propagation; | ||
import brave.propagation.Propagation; | ||
import brave.propagation.TraceContext; | ||
import brave.propagation.TraceContextOrSamplingFlags; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
public class CustomPropagationFactory extends Propagation.Factory { | ||
|
||
private static final String TRACE_PARENT = "traceparent"; | ||
private static final String TRACE_STATE = "tracestate"; | ||
|
||
@Override | ||
public <K> Propagation<K> create(Propagation.KeyFactory<K> keyFactory) { | ||
return new CustomPropagation<>(B3Propagation.FACTORY.create(keyFactory), keyFactory); | ||
} | ||
|
||
static final class CustomPropagation<K> implements Propagation<K> { | ||
final Propagation<K> b3; | ||
final K traceParentKey, traceStateKey; | ||
|
||
CustomPropagation(Propagation<K> b3, KeyFactory<K> keyFactory) { | ||
this.b3 = b3; | ||
this.traceParentKey = keyFactory.create(TRACE_PARENT); | ||
this.traceStateKey = keyFactory.create(TRACE_STATE); | ||
} | ||
|
||
@Override | ||
public List<K> keys() { | ||
return Arrays.asList(traceParentKey, traceStateKey); | ||
} | ||
|
||
@Override | ||
public <C> TraceContext.Injector<C> injector(Setter<C, K> setter) { | ||
return b3.injector(setter); | ||
} | ||
|
||
@Override | ||
public <C> TraceContext.Extractor<C> extractor(Getter<C, K> getter) { | ||
return new TraceContext.Extractor<C>() { | ||
@Override | ||
public TraceContextOrSamplingFlags extract(C carrier) { | ||
String traceParent = getter.get(carrier, traceParentKey); | ||
if (traceParent != null) { | ||
return extractFromTraceParent(traceParent); | ||
} | ||
return b3.extractor(getter).extract(carrier); | ||
} | ||
}; | ||
} | ||
|
||
private TraceContextOrSamplingFlags extractFromTraceParent(String traceParent) { | ||
String[] parts = traceParent.split("-"); | ||
if (parts.length != 4) { | ||
return TraceContextOrSamplingFlags.EMPTY; | ||
} | ||
long traceIdHigh = Long.parseUnsignedLong(parts[1].substring(0, 16), 16); | ||
long traceIdLow = Long.parseUnsignedLong(parts[1].substring(16), 16); | ||
long spanId = Long.parseUnsignedLong(parts[2], 16); | ||
byte samplingFlags = Byte.parseByte(parts[3], 16); | ||
|
||
return TraceContextOrSamplingFlags.create(TraceContext.newBuilder() | ||
.traceIdHigh(traceIdHigh) | ||
.traceId(traceIdLow) | ||
.spanId(spanId) | ||
.sampled(samplingFlags == 1) | ||
.build()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package ch.bfh.ti.i4mi.mag; | ||
|
||
import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class FilterConfig { | ||
|
||
@Bean | ||
public FilterRegistrationBean<TraceHeaderLoggingFilter> loggingFilter() { | ||
FilterRegistrationBean<TraceHeaderLoggingFilter> registrationBean = new FilterRegistrationBean<>(); | ||
registrationBean.setFilter(new TraceHeaderLoggingFilter()); | ||
registrationBean.addUrlPatterns("/*"); | ||
registrationBean.setOrder(1); | ||
return registrationBean; | ||
} | ||
|
||
@Bean | ||
public FilterRegistrationBean<RequestIdFilter> requestIdFilter() { | ||
FilterRegistrationBean<RequestIdFilter> registrationBean = new FilterRegistrationBean<>(); | ||
registrationBean.setFilter(new RequestIdFilter()); | ||
registrationBean.addUrlPatterns("/*"); | ||
registrationBean.setOrder(2); | ||
return registrationBean; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package ch.bfh.ti.i4mi.mag; | ||
|
||
import brave.handler.MutableSpan; | ||
import brave.handler.SpanHandler; | ||
import brave.propagation.TraceContext; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class LoggingSpanHandler extends SpanHandler { | ||
private static final Logger logger = LoggerFactory.getLogger(LoggingSpanHandler.class); | ||
|
||
@Override | ||
public boolean begin(TraceContext context, MutableSpan span, TraceContext parent) { | ||
logger.info("Span started: traceId={}, spanId={}, parentId={}", | ||
context.traceIdString(), | ||
context.spanIdString(), | ||
parent != null ? parent.spanIdString() : "none"); | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean end(TraceContext context, MutableSpan span, Cause cause) { | ||
logger.info("Span completed: traceId={}, spanId={}, name={}, duration={}ms", | ||
context.traceIdString(), | ||
context.spanIdString(), | ||
span.name(), | ||
span.finishTimestamp() - span.startTimestamp()); | ||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package ch.bfh.ti.i4mi.mag; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.slf4j.MDC; | ||
import org.springframework.web.filter.OncePerRequestFilter; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
import java.util.UUID; | ||
|
||
public class RequestIdFilter extends OncePerRequestFilter { | ||
private static final Logger logger = LoggerFactory.getLogger(RequestIdFilter.class); | ||
|
||
@Override | ||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) | ||
throws ServletException, IOException { | ||
String requestId = UUID.randomUUID().toString(); | ||
MDC.put("requestId", requestId); | ||
try { | ||
logger.info("Processing request: {}", requestId); | ||
filterChain.doFilter(request, response); | ||
} finally { | ||
logger.info("Completed request: {}", requestId); | ||
MDC.remove("requestId"); | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
src/main/java/ch/bfh/ti/i4mi/mag/TraceHeaderLoggingFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package ch.bfh.ti.i4mi.mag; | ||
|
||
import org.slf4j.MDC; | ||
import org.springframework.stereotype.Component; | ||
|
||
import javax.servlet.Filter; | ||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import javax.servlet.ServletRequest; | ||
import javax.servlet.ServletResponse; | ||
|
||
@Component | ||
public class TraceHeaderLoggingFilter implements Filter { | ||
private static final Logger logger = LoggerFactory.getLogger(TraceHeaderLoggingFilter.class); | ||
|
||
@Override | ||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { | ||
HttpServletRequest request = (HttpServletRequest) servletRequest; | ||
HttpServletResponse response = (HttpServletResponse) servletResponse; | ||
|
||
String traceparent = request.getHeader("traceparent"); | ||
String tracestate = request.getHeader("tracestate"); | ||
String b3 = request.getHeader("b3"); | ||
String b3TraceId = request.getHeader("X-B3-TraceId"); | ||
String b3SpanId = request.getHeader("X-B3-SpanId"); | ||
|
||
// Log the headers in a structured format | ||
logger.info("Trace headers: traceparent={}, tracestate={}, b3={}, X-B3-TraceId={}, X-B3-SpanId={}", | ||
traceparent, tracestate, b3, b3TraceId, b3SpanId); | ||
|
||
// Add the headers to MDC for logging | ||
MDC.put("traceparent", traceparent); | ||
MDC.put("tracestate", tracestate); | ||
MDC.put("b3", b3); | ||
MDC.put("X-B3-TraceId", b3TraceId); | ||
MDC.put("X-B3-SpanId", b3SpanId); | ||
|
||
try { | ||
filterChain.doFilter(request, response); | ||
} finally { | ||
// Clean up MDC | ||
MDC.clear(); // This removes all MDC entries | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/ch/bfh/ti/i4mi/mag/TracingConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package ch.bfh.ti.i4mi.mag; | ||
|
||
import brave.Tracing; | ||
import brave.propagation.B3Propagation; | ||
import brave.propagation.CurrentTraceContext; | ||
import brave.propagation.Propagation; | ||
import brave.propagation.ThreadLocalCurrentTraceContext; | ||
import brave.sampler.Sampler; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class TracingConfiguration { | ||
|
||
@Bean | ||
public Tracing tracing() { | ||
return Tracing.newBuilder() | ||
.sampler(Sampler.ALWAYS_SAMPLE) | ||
.propagationFactory(new CustomPropagationFactory()) | ||
.currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder().build()) | ||
.supportsJoin(false) | ||
.traceId128Bit(true) | ||
.build(); | ||
} | ||
|
||
@Bean | ||
public brave.handler.SpanHandler loggingSpanHandler() { | ||
return new LoggingSpanHandler(); | ||
} | ||
} |
Oops, something went wrong.