Skip to content

Instantly share code, notes, and snippets.

@yusufcakal
Last active February 8, 2021 08:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yusufcakal/c593d8d92619559675ee90b38f932459 to your computer and use it in GitHub Desktop.
Save yusufcakal/c593d8d92619559675ee90b38f932459 to your computer and use it in GitHub Desktop.
Helps you easy to tracing logs to request and response via Spring
logging:
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %clr([%thread]){magenta} %yellow([%X{requestId}]) %highlight(%-5level) %cyan(%-40.40logger{40}) - %msg %n"
import com.dolap.settlement.model.request.CreateSettlementRequest;
import com.dolap.settlement.model.response.GetSettlementResponse;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.MDC;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Component
public class LoggingFilter extends OncePerRequestFilter {
private static final Map<String, HttpMethod> EXCLUDED_LOGGING_ENDPOINT = new HashMap<>() {{
put("/actuator/health", HttpMethod.GET);
}};
private static final Map<String, Map.Entry<HttpMethod, Object>> MASKABLE_DATA_OF_REQUEST_ENDPOINTS = new HashMap<>() {{
put("/settlement/create", new ImmutablePair<>(HttpMethod.POST, CreateSettlementRequest.class));
}};
private static final Map<String, Map.Entry<HttpMethod, Object>> MASKABLE_DATA_OF_RESPONSE_ENDPOINTS = new HashMap<>() {{
put("/settlement/", new ImmutablePair<>(HttpMethod.GET, GetSettlementResponse.class));
}};
private final ObjectMapper objectMapper;
public LoggingFilter(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
for (String uri : EXCLUDED_LOGGING_ENDPOINT.keySet()) {
if (uri.equals(request.getRequestURI()) && EXCLUDED_LOGGING_ENDPOINT.get(uri).toString().equals(request.getMethod())) {
return;
}
}
MDC.put("requestId", "Correlation ID: " + UUID.randomUUID().toString());
String method = request.getMethod();
String endpoint = request.getRequestURL().toString();
ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);
filterChain.doFilter(wrappedRequest, wrappedResponse);
String requestBody = getContentAsString(wrappedRequest.getContentAsByteArray());
String responseBody = getContentAsString(wrappedResponse.getContentAsByteArray());
for (String url : MASKABLE_DATA_OF_REQUEST_ENDPOINTS.keySet()) {
if (request.getRequestURI().equals(url) && request.getMethod().equals(MASKABLE_DATA_OF_REQUEST_ENDPOINTS.get(url).getKey().toString())) {
Object object = MASKABLE_DATA_OF_REQUEST_ENDPOINTS.get(url).getValue();
Object o = objectMapper.readValue(requestBody, convertToTypeReference(ParameterizedTypeReference.forType((Type) object)));
logger.info("Request: " + method + " - " + endpoint + "\n" + o.toString());
} else {
logger.info("Request: " + method + " - " + endpoint + "\n" + requestBody);
}
}
for (String url : MASKABLE_DATA_OF_RESPONSE_ENDPOINTS.keySet()) {
if (request.getRequestURI().equals(url) && request.getMethod().equals(MASKABLE_DATA_OF_RESPONSE_ENDPOINTS.get(url).getKey().toString())) {
Object object = MASKABLE_DATA_OF_RESPONSE_ENDPOINTS.get(url).getValue();
Object o = objectMapper.readValue(responseBody, convertToTypeReference(ParameterizedTypeReference.forType((Type) object)));
logger.info("Response: " + "\n" + o.toString());
} else {
logger.info("Response: " + "\n" + responseBody);
}
}
wrappedResponse.copyBodyToResponse();
}
private String getContentAsString(byte[] bytes) {
return (bytes != null && bytes.length > 0) ? new String(bytes, 0, bytes.length, StandardCharsets.UTF_8) : Strings.EMPTY;
}
private <T> TypeReference<T> convertToTypeReference(ParameterizedTypeReference<T> parameterizedTypeReference) {
return new TypeReference<T>() {
public Type getType() {
return parameterizedTypeReference.getType();
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment