tomcat访问日志中的MDC相关内容

kmbjn2e3  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(202)

可以在spring Boot 应用程序的tomcat访问日志中提供MDC相关内容吗?
我看过很多博客,但是MDC的内容都记录在应用程序日志中,而不是访问日志中。
有没有办法在tomcat访问日志模式中添加它们。

whhtz7ly

whhtz7ly1#

正如Tomcat文档中所解释的,AccessLogValve使用任何传统的日志框架:
这个Valve使用自包含逻辑来写它的日志文件,这些日志文件可以在每天午夜自动滚动。(访问日志的基本要求是以较低的开销处理大量连续的数据流。这个Valve不使用Apache Commons Logging,因此避免了额外的开销和潜在的复杂配置)。
格式化逻辑在AbstractAccessLogValve类中,而写入实际日志文件的逻辑在AccessLogValve类中。
格式化模式使用简单的%c%{param}cAccessLogElement s(其中c是任意字符,param是字符串),并且可以根据您的需要轻松扩展。例如,您可以添加一个元素%{key}M,该元素返回与键key关联的MDC值:

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中添加阀:

@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);
            }
        };
    }
ou6hu8tu

ou6hu8tu2#

最终裁决为:访问日志不支持按日期的MDC。
在github上找到了这个,它提供了一个变通方案来启用访问日志的MDC。
https://github.com/dropwizard/dropwizard/issues/2419
其中有一个jira链接,详细说明了解决方案。

w46czmvw

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

其中,E8CFB537F4481717BA120B6232CAE715sessionKey

相关问题