package cc.fascinated.log; import cc.fascinated.common.IPUtils; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @ControllerAdvice @Slf4j(topic = "Req/Res Transaction") public class TransactionLogger implements ResponseBodyAdvice { @Override public Object beforeBodyWrite(Object body, @NonNull MethodParameter returnType, @NonNull MediaType selectedContentType, @NonNull Class> selectedConverterType, @NonNull ServerHttpRequest rawRequest, @NonNull ServerHttpResponse rawResponse) { HttpServletRequest request = ((ServletServerHttpRequest) rawRequest).getServletRequest(); HttpServletResponse response = ((ServletServerHttpResponse) rawResponse).getServletResponse(); // Get the request ip ip String ip = IPUtils.getRealIp(request); // Getting params Map params = new HashMap<>(); for (Entry entry : request.getParameterMap().entrySet()) { params.put(entry.getKey(), Arrays.toString(entry.getValue())); } // Getting headers Map headers = new HashMap<>(); Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); headers.put(headerName, request.getHeader(headerName)); } // Log the request log.info(String.format("[Req] %s | %s | '%s', params=%s, headers=%s", request.getMethod(), ip, request.getRequestURI(), params, headers )); // Getting response headers headers = new HashMap<>(); for (String headerName : response.getHeaderNames()) { headers.put(headerName, response.getHeader(headerName)); } // Log the response log.info(String.format("[Res] %s, headers=%s", response.getStatus(), headers )); return body; } @Override public boolean supports(@NonNull MethodParameter returnType, @NonNull Class> converterType) { return true; } }