我们正在使用Tomcat 7.0.54。
web.xml:
<context-param>
<param-name>log4jContextName</param-name>
<param-value>SabaLog4jContext</param-value>
</context-param>
有一个样本servlet在加载时启动
<servlet>
<servlet-name>startUp</servlet-name>
<servlet-class>foo.StartupServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
StartupServlet简单如下:
public class StartupServlet extends HttpServlet {
@Override
public void init() throws ServletException {
getServletContext().setAttribute("test", "ATest");
super.init();
}
}
log4j2无法使用test
访问${web:attr.test}
属性,我收到警告:
INFO: org.apache.logging.log4j.web.WebLookup unable to resolve key 'test'
似乎Log4j2工作正常,但问题是它在我的Startup之前启动。我尝试使用servletContextListener
课,但没有运气。
我还尝试在web.xml中禁用Log4jAutoInitialization,然后手动启动它们,如下所示。
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
但没有运气:(
log4j2.xml如下:
<property name="baseFolder">${web:rootDir}/../logs/${web:test}</property>
那么如何设置我的web.xml以便我的代码在Log4j上下文之前执行。
web.xml
还包含spring Listeners:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
答案 0 :(得分:1)
首先,确保Tomcat配置为在web.xml
文件中提供servlet 3.0容器的功能:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
您需要3.0功能,以便指定加载servlet的顺序。然后,您将希望拥有自己的ServletContainerInitializer来初始化ServletContext属性。这是我的一个片段:
/* Initializer that is configured, via web.xml, to initialize before Log4j2's initializer. This gives us the
* opportunity to set some servlet context attributes that Log4j2 will use when it eventually initializes.
*/
public class BitColdHardCashContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(final Set<Class<?>> classes, final ServletContext servletContext) throws ServletException {
if (servletContext.getMajorVersion() > 2) {
servletContext.log("BitColdHardCashContainerInitializer starting up in Servlet 3.0+ environment.");
}
// Set the webapp.name attribute so that Log4j2 may use it to create a path for log files.
servletContext.setAttribute("webapp.name", servletContext.getContextPath().replaceAll("/", "").trim());
接下来,您希望ServerContainerInitializer在Log4j2之前运行。在您的web.xml中,为您的servlet命名:
<absolute-ordering>
<name>BitColdHardCash</name>
<others/>
</absolute-ordering>
这需要在<servlet>
元素之前指定。
创建web-fragment.xml
文件:
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
version="3.0" metadata-complete="true">
<name>BitColdHardCash</name>
<distributable />
<ordering>
<before>
<others />
</before>
</ordering>
</web-fragment>
这告诉Tomcat首先初始化你的ServletContainerInitializer,其他任何东西,包括Log4j2&#39; s。这位于META-INF目录中。
应该这样做。还需要检查的是catalina.properties
文件。您正在使用Tomcat的一个版本来修复有关调用ServletContextInitializers的错误。我不确定该错误是在Tomcat源代码中还是在默认提供的catalina.properties文件中。如果您使用的是catalina.properties文件,该文件在修复之前,只需将其打开,确保log4j * .jar未包含在为tomcat.util.scan.DefaultJarScanner.jarsToSkip
属性指定的文件列表中。