[英]Spring Boot & Slf4j 2 Http request metadata logging interceptor?
我想配置我的日志記錄設置,以便傳入的請求標記有一個 id(即 UUID),用於跟蹤整個應用程序(即控制器類、服務類等)中的請求和進程以及其他相關信息請求(即主機名、IP 地址...)。
參考 slf4j 2 文檔,我看到提到ThreadContext 。 對於對我的 spring-boot 應用程序提出的每個請求,我想做類似的事情:
ThreadContext.put("id", UUID.randomUUID().toString());
ThreadContext.put("ipAddress", this.request.getRemoteAddr());
...
並在我的調試器的 PatternLayout 中調用這些鍵,如下所示:%X{key}。 理想情況下,這將產生類似於以下內容的內容:
[INFO] request #UUID1 #IP1: start.
[INFO] request #UUID1 #IP1: do something controller class
[INFO] request #UUID2 #IP2: start.
[INFO] request #UUID1 #IP1: do something service class
[INFO] request #UUID2 #IP2: do something controller class
[INFO] request #UUID2 #IP2: do something service class
[INFO] request #UUID1 #IP1: end.
[INFO] request #UUID2 #IP2: end.
雖然我不確定如何開始實際實施。 任何見解將不勝感激!
您應該使用 slf4j https://ivanursul.com/slf4j-mdc查看 MDC(映射診斷上下文)
創建一個 Servlet 過濾器,它在 MDC 中設置所需的參數,它們將在整個請求中可用並自動記錄。
使用實現 Filter 類的類,我能夠通過使用以下代碼以及調用 Log4j 2 PatternLayout 中的鍵來獲得所需的行為:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.TimeZone;
import java.util.UUID;
@Component
public class RequestResponseLoggingFilter implements Filter {
private FilterConfig filterConfig;
private static String TZ_NAME = "timezoneOffset";
private static final Logger LOGGER = LogManager.getLogger(RequestBody.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
/**
* Sample filter that populates the MDC on every request.
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
String requestId = request.getHeader("requestId");
if (requestId == null) {
requestId = UUID.randomUUID().toString();
}
ThreadContext.put("requestId", requestId);
ThreadContext.put("ipAddress", request.getRemoteAddr());
HttpSession session = request.getSession(false);
TimeZone timeZone = null;
ThreadContext.put("hostname", servletRequest.getServerName());
ThreadContext.put("locale", servletRequest.getLocale().getDisplayName());
if (timeZone == null) {
timeZone = TimeZone.getDefault();
}
ThreadContext.put("timezone", timeZone.getDisplayName());
LOGGER.info(
"Logging Request {} : {}", request.getMethod(),
request.getRequestURI());
filterChain.doFilter(servletRequest, servletResponse);
LOGGER.info(
"Logging Response {} : {}",
response.getStatus(), response.getContentType());
ThreadContext.clearMap();
}
@Override
public void destroy() {
}
}
Spring Cloud Sleuth將為您完成所有這些工作......只需將它包含在您的類路徑中,並將您關心的屬性添加到您的日志輸出中。 它還自動檢測控制器和客戶端以傳遞標頭屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.