简体   繁体   English

tomcat access-logs中的MDC相关内容

[英]MDC related content in tomcat access-logs

Can MDC related content be made available in tomcat access logs in spring boot application.能否在spring boot应用程序的tomcat访问日志中提供MDC相关内容。

I have gone through lot of blogs but everywhere the contents of MDC are logged to application logs but not in access logs.我浏览了很多博客,但 MDC 的内容到处都记录到应用程序日志中,而不是访问日志中。

Is there any way to add them in tomcat access log pattern.有什么方法可以将它们添加到 tomcat 访问日志模式中。

As explained in Tomcat's documentation the AccessLogValve does not use any traditional logging framework:正如Tomcat 的文档中所解释的, AccessLogValve使用任何传统的日志框架:

This Valve uses self-contained logic to write its log files, which can be automatically rolled over at midnight each day.这个Valve使用独立的逻辑来编写它的日志文件,这些文件可以在每天午夜自动翻转。 (The essential requirement for access logging is to handle a large continuous stream of data with low overhead. This Valve does not use Apache Commons Logging, thus avoiding additional overhead and potentially complex configuration). (访问日志的基本要求是以低开销处理大量连续数据流。此Valve不使用 Apache Commons Logging,因此避免了额外的开销和潜在的复杂配置)。

The formatting logic is in the AbstractAccessLogValve class, while the logic that writes to the actual log file is in the AccessLogValve .格式化逻辑在AbstractAccessLogValve类中,而写入实际日志文件的逻辑在AccessLogValve中。

The formatting pattern uses simple %c and %{param}c AccessLogElement s (where c is any character and param is a string) and can be easily extended for your purposes.格式化模式使用简单的%c%{param}c AccessLogElement s(其中c是任何字符, param是字符串),并且可以根据您的目的轻松扩展。 For example you can add an element %{key}M that returns the MDC value associated to the key key :例如,您可以添加一个元素%{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);
    }
}

If you want to use this valve in Spring Boot instead of the standard valve, you can add the valve in a WebServerFactoryCustomizer :如果你想在 Spring 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);
            }
        };
    }

Final Verdict is: Access logs don't support MDC as per date.最终结论是:按日期访问日志不支持 MDC。

Found this on github which provides a work-around to enable MDC for access logs.在 github 上找到了这个,它提供了一种解决方法来启用 MDC 访问日志。

https://github.com/dropwizard/dropwizard/issues/2419 https://github.com/dropwizard/dropwizard/issues/2419

In this there is a jira link which elaborates on the solution.在此有一个 jira 链接,详细说明了解决方案。

You can keep MDC content in session attributes.您可以将 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);
}
}

And then you can add that into access log format.然后您可以将其添加到访问日志格式中。

server:
  tomcat:
    accesslog:
      pattern: "%t %{sessionKey}s - %r - %s - %D"

Logs would look like...日志看起来像......

[17/Jun/2022:14:10:40 -0500] E8CFB537F4481717BA120B6232CAE715 - GET /URL HTTP/1.1 - 200 - 58

Where E8CFB537F4481717BA120B6232CAE715 is the sessionKey其中E8CFB537F4481717BA120B6232CAE715sessionKey

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM