如何以编程方式将AccessLogValve添加到Tomcat? [英] How to add an AccessLogValve to Tomcat programmatically?

查看:381
本文介绍了如何以编程方式将AccessLogValve添加到Tomcat?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring引导应用程序,我想通过slf4j日志记录系统将Tomcat的访问日志路由到远程syslog.

I'm working on a Spring boot application, and I'd like to route Tomcat's access logs through my slf4j logging system and finally to a remote syslog.

因为是春天,所以我想避免触摸tomcat的server.xml文件.

Since it's Spring, I'd like to avoid touching tomcat's server.xml file.

我的AccessLogValve非常简单:

My AccessLogValve is pretty simple:

import java.io.CharArrayWriter;
import org.apache.catalina.valves.AccessLogValve;

public class Log4JAccessLogValve extends AccessLogValve {
    @Override
    public void log(CharArrayWriter message) {
        log.info(message.toString());
    }
}

我希望可以使用类似这样的方法将其连接到Tomcat:

And I was hoping it would be possible to use something like this to hook it up to Tomcat:

@Component
public class LogConfig {

    @Autowired
    private ServletContext servletContext;

    @PostConstruct
    public void setAccessLogValve() {
        ((ApplicationContextFacade)servletContext).addValve(new Log4JAccessLogValve());
    }

}

除了addValve()方法不存在外...

except the addValve() method doesn't exist...

所以...任何人都有一个想法如何可以将我的AccessLogValve钩住?

So... anyone have an idea how I can hook in my AccessLogValve?

对于开放访问日志到远程syslog的建议,我也持完全不同的建议,但是我们正在制作数十种微服务,因此它必须是一种非常标准化的方法,对于每个微服务都必须易于实现.

I'm also open to completely different suggestions to get access logs into a remote syslog, but we're making dozens of micro services so it has to be a pretty standardized approach that's simple to implement for each micro service.

推荐答案

将这些答案组合成适用于springboot 2.0的内容

combining these answers into something that works with springboot 2.0

import org.apache.catalina.valves.AbstractAccessLogValve;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

import java.io.CharArrayWriter;

/**
 * see https://www.baeldung.com/embeddedservletcontainercustomizer-configurableembeddedservletcontainer-spring-boot
 * 
*/
@Component
@Slf4j
public class CustomizeEmbeddedTomcatContainer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {

        log.info("configuring embedded Tomcat");
        TomcatSlf4jAccessValve accessLogValve = new TomcatSlf4jAccessValve();
        accessLogValve.setEnabled(true);

        /**
         * for pattern format see https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/valves/AccessLogValve.html
         */
        accessLogValve.setPattern("request: method=%m uri=\"%U\" response: statuscode=%s bytes=%b duration=%D(ms) client: remoteip=%a user=%u useragent=\"%{User-Agent}i\"");

        factory.addContextValves(accessLogValve);
    }


    public static class TomcatSlf4jAccessValve extends AbstractAccessLogValve {

        Logger httpAccessLogLogger = LoggerFactory.getLogger("http_access_log");

        @Override
        protected void log(CharArrayWriter message) {
            httpAccessLogLogger.info(message.toString());
        }

    }
}

这篇关于如何以编程方式将AccessLogValve添加到Tomcat?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆