http://jira.mfd.msk:8088/browse/BKI-3215 Moved member code logging logic to MemberCodeHttpLoggingFilter; Added CachedServletInputStream; Updated CachedHttpRequestWrapper
This commit is contained in:
parent
3b9c2eaa15
commit
f950f98536
4 changed files with 99 additions and 95 deletions
|
|
@ -13,18 +13,11 @@ import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
import org.springframework.web.util.ContentCachingRequestWrapper;
|
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||||
import org.springframework.web.util.ContentCachingResponseWrapper;
|
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||||
import ru.nbch.credit_tracker.config.rest.wrappers.CachedHttpRequestWrapper;
|
|
||||||
import ru.nbch.credit_tracker.entities.user_request.active_packages.MonitoringActivePackagesRequest;
|
|
||||||
import ru.nbch.credit_tracker.entities.user_request.all_packages.MonitoringAllPackagesRequest;
|
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Order(0)
|
@Order(0)
|
||||||
|
|
@ -33,12 +26,6 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
private static final Set<String> SENSITIVE_HEADERS = Set.of("authorization", "cookie", "set-cookie");
|
private static final Set<String> SENSITIVE_HEADERS = Set.of("authorization", "cookie", "set-cookie");
|
||||||
private static final int MAX_BODY = 10 * 1024;
|
private static final int MAX_BODY = 10 * 1024;
|
||||||
|
|
||||||
private final IXmlProcessor xmlProcessor;
|
|
||||||
|
|
||||||
public HttpLoggingFilter(IXmlProcessor xmlProcessor) {
|
|
||||||
this.xmlProcessor = xmlProcessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldNotFilter(HttpServletRequest request) {
|
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||||
String path = request.getRequestURI();
|
String path = request.getRequestURI();
|
||||||
|
|
@ -52,7 +39,7 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
long startNs = System.nanoTime();
|
long startNs = System.nanoTime();
|
||||||
|
|
||||||
HttpServletRequestWrapper req = wrapRequest(request);
|
ContentCachingRequestWrapper req = wrapRequest(request);
|
||||||
ContentCachingResponseWrapper resp = new ContentCachingResponseWrapper(response);
|
ContentCachingResponseWrapper resp = new ContentCachingResponseWrapper(response);
|
||||||
|
|
||||||
String correlationId = Optional.ofNullable(request.getHeader("X-Correlation-Id"))
|
String correlationId = Optional.ofNullable(request.getHeader("X-Correlation-Id"))
|
||||||
|
|
@ -60,15 +47,14 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
.orElse(UUID.randomUUID().toString());
|
.orElse(UUID.randomUUID().toString());
|
||||||
resp.setHeader("X-Correlation-Id", correlationId);
|
resp.setHeader("X-Correlation-Id", correlationId);
|
||||||
|
|
||||||
String memberCode = parseMemberCode(req);
|
logIncomingRequest(req, correlationId);
|
||||||
logIncomingRequest(req, correlationId, memberCode);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
chain.doFilter(req, resp);
|
chain.doFilter(req, resp);
|
||||||
} finally {
|
} finally {
|
||||||
long tookMs = (System.nanoTime() - startNs) / 1_000_000;
|
long tookMs = (System.nanoTime() - startNs) / 1_000_000;
|
||||||
|
|
||||||
Map<String, String> reqParams = paramsMap(req, memberCode);
|
Map<String, String> reqParams = paramsMap(req);
|
||||||
|
|
||||||
Map<String, String> reqHeaders = headersMap(req);
|
Map<String, String> reqHeaders = headersMap(req);
|
||||||
Map<String, String> respHeaders = headersMap(resp);
|
Map<String, String> respHeaders = headersMap(resp);
|
||||||
|
|
@ -92,46 +78,8 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String parseMemberCode(HttpServletRequestWrapper req) {
|
private void logIncomingRequest(ContentCachingRequestWrapper req, String correlationId) {
|
||||||
String memberCode = null;
|
Map<String, String> reqParams = paramsMap(req);
|
||||||
if (!(req instanceof CachedHttpRequestWrapper)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String body = ((CachedHttpRequestWrapper) req).getBody();
|
|
||||||
if (isBlank(body)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
switch (req.getRequestURI()) {
|
|
||||||
case "/api/v1/signal/active_packages":
|
|
||||||
try {
|
|
||||||
MonitoringActivePackagesRequest activePackagesRequest = xmlProcessor.read(body, MonitoringActivePackagesRequest.class);
|
|
||||||
if (activePackagesRequest != null && isNotBlank(activePackagesRequest.getUserId())) {
|
|
||||||
memberCode = activePackagesRequest.getUserId().substring(0, 6);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
memberCode = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "/api/v1/signal/all_packages":
|
|
||||||
try {
|
|
||||||
MonitoringAllPackagesRequest allPackagesRequest = xmlProcessor.read(body, MonitoringAllPackagesRequest.class);
|
|
||||||
if (allPackagesRequest != null && isNotBlank(allPackagesRequest.getUserId())) {
|
|
||||||
memberCode = allPackagesRequest.getUserId().substring(0, 6);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
memberCode = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return memberCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void logIncomingRequest(HttpServletRequestWrapper req, String correlationId, String memberCode) {
|
|
||||||
Map<String, String> reqParams = paramsMap(req, memberCode);
|
|
||||||
Map<String, String> reqHeaders = headersMap(req);
|
Map<String, String> reqHeaders = headersMap(req);
|
||||||
mask(reqHeaders);
|
mask(reqHeaders);
|
||||||
|
|
||||||
|
|
@ -145,13 +93,8 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HttpServletRequestWrapper wrapRequest(HttpServletRequest request) throws IOException {
|
private static ContentCachingRequestWrapper wrapRequest(HttpServletRequest request) throws IOException {
|
||||||
return switch (request.getRequestURI()) {
|
return (request instanceof ContentCachingRequestWrapper c) ? c : new ContentCachingRequestWrapper(request, MAX_BODY);
|
||||||
case "/api/v1/signal/active_packages", "/api/v1/signal/all_packages" ->
|
|
||||||
new CachedHttpRequestWrapper(request);
|
|
||||||
default ->
|
|
||||||
(request instanceof ContentCachingRequestWrapper c) ? c : new ContentCachingRequestWrapper(request, MAX_BODY);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -160,7 +103,7 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
.collect(Collectors.toMap(h -> h, req::getHeader, (a, b) -> a, LinkedHashMap::new));
|
.collect(Collectors.toMap(h -> h, req::getHeader, (a, b) -> a, LinkedHashMap::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, String> paramsMap(HttpServletRequestWrapper req, String memberCode) {
|
private static Map<String, String> paramsMap(HttpServletRequestWrapper req) {
|
||||||
Map<String, String> paramsMap = new LinkedHashMap<>();
|
Map<String, String> paramsMap = new LinkedHashMap<>();
|
||||||
req.getParameterMap().forEach((k, v) -> {
|
req.getParameterMap().forEach((k, v) -> {
|
||||||
String params = String.join(", ", v);
|
String params = String.join(", ", v);
|
||||||
|
|
@ -175,11 +118,6 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memberCode != null) {
|
|
||||||
paramsMap.put("memberCode", memberCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return paramsMap;
|
return paramsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package ru.nbch.credit_tracker.config.rest.filters;
|
||||||
|
|
||||||
|
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
import ru.nbch.credit_tracker.config.rest.wrappers.CachedHttpRequestWrapper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
@Order(1)
|
||||||
|
public class MemberCodeHttpLoggingFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||||
|
String path = request.getRequestURI();
|
||||||
|
return !(path.startsWith("/api/v1/signal/all_packages") || path.startsWith("/api/v1/signal/active_packages"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
CachedHttpRequestWrapper req = wrapRequest(request);
|
||||||
|
String body = IOUtils.toString(req.getBody(), req.getCharacterEncoding());
|
||||||
|
if (StringUtils.isNotBlank(body)) {
|
||||||
|
try {
|
||||||
|
int startIndex = body.indexOf("<UserId>") + 8;
|
||||||
|
int endIndex = body.indexOf("</UserId>");
|
||||||
|
String userId = body.substring(startIndex, endIndex);
|
||||||
|
log.info(
|
||||||
|
"HTTP (REQUEST) {} {} | memberCode={}",
|
||||||
|
req.getMethod(),
|
||||||
|
req.getRequestURI(),
|
||||||
|
userId.substring(0, 6)
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filterChain.doFilter(req, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CachedHttpRequestWrapper wrapRequest(HttpServletRequest request) throws IOException {
|
||||||
|
return new CachedHttpRequestWrapper(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,47 +1,25 @@
|
||||||
package ru.nbch.credit_tracker.config.rest.wrappers;
|
package ru.nbch.credit_tracker.config.rest.wrappers;
|
||||||
|
|
||||||
import jakarta.servlet.ReadListener;
|
|
||||||
import jakarta.servlet.ServletInputStream;
|
import jakarta.servlet.ServletInputStream;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class CachedHttpRequestWrapper extends HttpServletRequestWrapper {
|
public class CachedHttpRequestWrapper extends HttpServletRequestWrapper {
|
||||||
private final String body;
|
private final byte[] body;
|
||||||
|
|
||||||
|
|
||||||
public CachedHttpRequestWrapper(HttpServletRequest request) throws IOException {
|
public CachedHttpRequestWrapper(HttpServletRequest request) throws IOException {
|
||||||
super(request);
|
super(request);
|
||||||
body = IOUtils.toString(request.getReader());
|
this.body = request.getInputStream().readAllBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServletInputStream getInputStream() {
|
public ServletInputStream getInputStream() {
|
||||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(getBody().getBytes());
|
return new CachedServletInputStream(body);
|
||||||
return new ServletInputStream() {
|
|
||||||
public int read() {
|
|
||||||
return byteArrayInputStream.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFinished() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isReady() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setReadListener(ReadListener listener) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package ru.nbch.credit_tracker.config.rest.wrappers;
|
||||||
|
|
||||||
|
import jakarta.servlet.ReadListener;
|
||||||
|
import jakarta.servlet.ServletInputStream;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
|
public class CachedServletInputStream extends ServletInputStream {
|
||||||
|
|
||||||
|
private final ByteArrayInputStream byteArray;
|
||||||
|
|
||||||
|
public CachedServletInputStream(byte[] data) {
|
||||||
|
this.byteArray = new ByteArrayInputStream(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() {
|
||||||
|
return byteArray.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFinished() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReady() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReadListener(ReadListener listener) {
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue