可以在spring Boot 应用程序的tomcat访问日志中提供MDC相关内容吗?我看过很多博客,但是MDC的内容都记录在应用程序日志中,而不是访问日志中。有没有办法在tomcat访问日志模式中添加它们。
whhtz7ly1#
正如Tomcat文档中所解释的,AccessLogValve不使用任何传统的日志框架:这个Valve使用自包含逻辑来写它的日志文件,这些日志文件可以在每天午夜自动滚动。(访问日志的基本要求是以较低的开销处理大量连续的数据流。这个Valve不使用Apache Commons Logging,因此避免了额外的开销和潜在的复杂配置)。格式化逻辑在AbstractAccessLogValve类中,而写入实际日志文件的逻辑在AccessLogValve类中。格式化模式使用简单的%c和%{param}cAccessLogElement s(其中c是任意字符,param是字符串),并且可以根据您的需要轻松扩展。例如,您可以添加一个元素%{key}M,该元素返回与键key关联的MDC值:
AccessLogValve
Valve
AbstractAccessLogValve
%c
%{param}c
AccessLogElement
c
param
%{key}M
key
import org.slf4j.MDC; public class MDCAccessLogValve extends AccessLogValve { @Override protected AccessLogElement createAccessLogElement(String name, char pattern) { if (pattern == 'M') { return new AccessLogElement() { @Override public void addElement(CharArrayWriter buf, Date date, Request request, Response response, long time) { buf.append(MDC.get(name)); } }; } return super.createAccessLogElement(name, pattern); } }
如果要在Sping Boot 中使用此阀而不是标准阀,则可以在WebServerFactoryCustomizer中添加阀:
WebServerFactoryCustomizer
@Bean public WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory> accessLogCustomizer(Environment env) { return new WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory>() { @Override public void customize(ConfigurableTomcatWebServerFactory factory) { final MDCAccessLogValve valve = new MDCAccessLogValve(); valve.setPattern(env.getProperty("server.tomcat.accesslog.pattern", "common")); factory.addEngineValves(valve); } }; }
ou6hu8tu2#
最终裁决为:访问日志不支持按日期的MDC。在github上找到了这个,它提供了一个变通方案来启用访问日志的MDC。https://github.com/dropwizard/dropwizard/issues/2419其中有一个jira链接,详细说明了解决方案。
w46czmvw3#
您可以将MDC内容保留在会话属性中。
@Component public class WebRequestsFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; httpServletRequest.getSession().setAttribute("sessionKey", httpServletRequest.getSession().getId()); filterChain.doFilter(servletRequest, servletResponse); } }
然后您可以将其添加到访问日志格式中。
server: tomcat: accesslog: pattern: "%t %{sessionKey}s - %r - %s - %D"
日志看起来像...
[17/Jun/2022:14:10:40 -0500] E8CFB537F4481717BA120B6232CAE715 - GET /URL HTTP/1.1 - 200 - 58
其中,E8CFB537F4481717BA120B6232CAE715是sessionKey
E8CFB537F4481717BA120B6232CAE715
sessionKey
3条答案
按热度按时间whhtz7ly1#
正如Tomcat文档中所解释的,
AccessLogValve
不使用任何传统的日志框架:这个
Valve
使用自包含逻辑来写它的日志文件,这些日志文件可以在每天午夜自动滚动。(访问日志的基本要求是以较低的开销处理大量连续的数据流。这个Valve
不使用Apache Commons Logging,因此避免了额外的开销和潜在的复杂配置)。格式化逻辑在
AbstractAccessLogValve
类中,而写入实际日志文件的逻辑在AccessLogValve
类中。格式化模式使用简单的
%c
和%{param}c
AccessLogElement
s(其中c
是任意字符,param
是字符串),并且可以根据您的需要轻松扩展。例如,您可以添加一个元素%{key}M
,该元素返回与键key
关联的MDC值:如果要在Sping Boot 中使用此阀而不是标准阀,则可以在
WebServerFactoryCustomizer
中添加阀:ou6hu8tu2#
最终裁决为:访问日志不支持按日期的MDC。
在github上找到了这个,它提供了一个变通方案来启用访问日志的MDC。
https://github.com/dropwizard/dropwizard/issues/2419
其中有一个jira链接,详细说明了解决方案。
w46czmvw3#
您可以将MDC内容保留在会话属性中。
然后您可以将其添加到访问日志格式中。
日志看起来像...
其中,
E8CFB537F4481717BA120B6232CAE715
是sessionKey