如何以编程方式将AccessLogValve添加到Tomcat?

我正在开发一个Spring启动应用程序,我想通过我的slf4j日志系统将Tomcat的访问日志路由到远程系统日志。

因为它是Spring,所以我想避免触及tomcat的server.xml文件。

我的AccessLogValve非常简单:

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:

 @Component public class LogConfig { @Autowired private ServletContext servletContext; @PostConstruct public void setAccessLogValve() { ((ApplicationContextFacade)servletContext).addValve(new Log4JAccessLogValve()); } } 

除了addValve()方法不存在…

那么……任何人都知道如何在我的AccessLogValve中挂钩?


我也接受完全不同的建议,以获取访问日志到远程系统日志,但我们正在制作数十个微服务,所以它必须是一个非常标准化的方法,很容易实现每个微服务。

使用EmbeddedServletContainerCustomizer接口。 向嵌入式tomcat添加自定义阀门。

例如

 @Configuration public class WebConfig extends WebMvcConfigurerAdapter implements EmbeddedServletContainerCustomizer { @Override public void customize(ConfigurableEmbeddedServletContainer container) { if (container instanceof TomcatEmbeddedServletContainerFactory) { TomcatEmbeddedServletContainerFactory factory = (TomcatEmbeddedServletContainerFactory) container; AccessLogValve accessLogValve = new Log4JAccessLogValve(); accessLogValve.setDirectory("/var/log/access_log"); accessLogValve.setPattern("%h %u %t "%r" %s %b - %T"); accessLogValve.setSuffix(".log"); factory.addContextValves(accessLogValve); } else { logger.error("WARNING! this customizer does not support a custom configured container"); } } } 

另外,我建议使用AbstractAccessLogValve而不是AccessLogValve扩展Log4JAccessLogValve。 它不会初始化AccessLogValve的文件访问日志文件相关function

例如:

 import java.io.CharArrayWriter; import org.apache.catalina.valves.AbstractAccessLogValve; public class Log4JAccessLogValve extends AbstractAccessLogValve { @Override protected void log(CharArrayWriter message) { LOGGER.info(message.toString()); } }