Skip to content

Commit

Permalink
feat: add trace propagation
Browse files Browse the repository at this point in the history
  • Loading branch information
davdarras committed Aug 19, 2024
1 parent dcf9fd8 commit ee4de63
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<description>Modules for queen back-office</description>

<properties>
<revision>4.3.15</revision>
<revision>4.3.16</revision>
<changelist></changelist>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protected CorsConfigurationSource corsConfigurationSource(ApplicationProperties
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOriginPatterns(applicationProperties.corsOrigins());
configuration.setAllowedMethods(List.of("GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"));
configuration.setAllowedHeaders(List.of("Authorization", "Content-Type", "Access-Control-Allow-Origin"));
configuration.setAllowedHeaders(List.of("Authorization", "Content-Type", "Access-Control-Allow-Origin", "Traceparent", "Tracestate"));
configuration.addExposedHeader("Content-Disposition");
configuration.setMaxAge(3600L);
configuration.setAllowCredentials(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import fr.insee.queen.application.configuration.properties.RoleProperties;
import fr.insee.queen.application.configuration.rest.RestTemplateAddJsonHeaderInterceptor;
import fr.insee.queen.application.configuration.rest.RestTemplateTokenInterceptor;
import fr.insee.queen.application.configuration.rest.RestTemplateTraceIdInterceptor;
import fr.insee.queen.application.web.authentication.AuthenticationHelper;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
Expand Down Expand Up @@ -98,6 +99,7 @@ protected RestTemplate restTemplatePilotage(AuthenticationHelper authenticationH
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(new RestTemplateAddJsonHeaderInterceptor());
restTemplate.getInterceptors().add(new RestTemplateTokenInterceptor(authenticationHelper));
restTemplate.getInterceptors().add(new RestTemplateTraceIdInterceptor());
return restTemplate;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import jakarta.annotation.Nonnull;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
Expand All @@ -13,24 +14,31 @@
import org.springframework.web.servlet.ModelAndView;

import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
@RequiredArgsConstructor
@Slf4j
public class LogInterceptor implements HandlerInterceptor {

private static final Pattern TRACE_PATTERN = Pattern.compile(
"^\\d{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$"
);
private final AuthenticationHelper authenticationHelper;

@Override
public boolean preHandle(HttpServletRequest request, @Nonnull HttpServletResponse response, @Nonnull Object handler) {
String fishTag = UUID.randomUUID().toString();
public boolean preHandle(@NonNull HttpServletRequest request, @Nonnull HttpServletResponse response, @Nonnull Object handler) {

String traceIdentifier = extractTraceIdentifier(request);
String method = request.getMethod();
String operationPath = request.getRequestURI();

Authentication authentication = authenticationHelper.getAuthenticationPrincipal();

String userId = authentication.getName();

MDC.put("id", fishTag);
MDC.put("id", traceIdentifier);
MDC.put("path", operationPath);
MDC.put("method", method);
MDC.put("user", userId);
Expand All @@ -50,4 +58,34 @@ public void afterCompletion(@Nonnull HttpServletRequest request, @Nonnull HttpSe
Exception exception) {
MDC.clear();
}

/**
* @param request current http servlet request
* @return a trace identifier for the current request
*/
private String extractTraceIdentifier(HttpServletRequest request) {
String traceParent = request.getHeader("traceparent");

if (!isTraceValid(traceParent)) {
String version = "00";
String traceId = UUID.randomUUID().toString().replace("-", "");
String spanId = traceId.substring(16);
String traceFlags = "01";
traceParent = String.format("%s-%s-%s-%s", version, traceId, spanId, traceFlags);
}
return traceParent;
}

/**
* Check trace identifier validity
* @param traceIdentifier identifier to check
* @return true if valid, false otherwise
*/
private boolean isTraceValid(String traceIdentifier) {
if (traceIdentifier == null) {
return false;
}
Matcher matcher = TRACE_PATTERN.matcher(traceIdentifier);
return matcher.matches();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package fr.insee.queen.application.configuration.rest;

import org.slf4j.MDC;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;

public class RestTemplateTraceIdInterceptor implements ClientHttpRequestInterceptor {

@Override
public ClientHttpResponse intercept(HttpRequest request, byte [] body,
ClientHttpRequestExecution execution) throws IOException {
// Retrieve the Trace Identifier from MDC
String traceIdentifier = MDC.get("id");

if (traceIdentifier != null) {
// Add the Trace ID to the outgoing request's headers
request.getHeaders().add("traceparent", traceIdentifier);
}

return execution.execute(request, body);
}
}

0 comments on commit ee4de63

Please sign in to comment.