2016-10-21 56 views
1

我正在開發一個Spring引導應用程序,我想通過我的slf4j日誌記錄系統將Tomcat的訪問日誌路由到一個遠程系統日誌。如何以編程方式將AccessLogValve添加到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?


我也開到完全不同的建議,以訪問登錄到遠程系統日誌,但我們正在做幾十個微服務,它必須是一個非常標準化的方法,它易於實現對每個微服務。

回答

1

使用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"); 
     } 
    } 

} 
+0

現在我已經嘗試了一堆不同的版本,但我的日誌(的CharArrayWriter消息)方法從不運行時,根據我的分析器...我猜Tomcat由於某種原因沒有運行閥門。 – schuttek

+0

是否有可能將factory.addContextValves()添加到沒有連接到實際Tomcat服務器的東西上? – schuttek

+1

我自己的解決方案將非常簡單:螺絲系統日誌...它是一個過時的系統黑客無論如何... 我只是要將日誌轉儲到本地文件系統,並設置logstash收集,集中和處理它們。 我只需要弄清楚如何讓Tomcat每30秒左右刷新一次訪問日誌緩存,但這是另一回事...... 感謝您的幫助Johnny,我希望它可以幫助別人:) – schuttek

0

此外,我會建議與AbstractAccessLogValve代替AccessLogValve延伸Log4JAccessLogValve。它不會初始化的AccessLogValve

例如文件訪問日誌文件相關的功能:

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()); 
    } 

} 
相關問題