我正在Tomcat 8.0.12中运行的Servlet 3.0 Web应用程序中使用log4j2(2.0.2)。我正在尝试使用weblookup来获取Web应用程序上下文路径以用作日志文件名的一部分。 (我们使用属性对其进行配置,在几个不同的上下文中运行相同的war文件)。

log4j2.xml文件包括

        <RollingFile name="Web" fileName="/srv/dnsnet/logs/web-${web:contextPath}.logfile" filePattern="/srv/dnsnet/logs/web-${web:contextPath}-%d{yyyy-MM-dd}-%i.log.gz" append="true" immediateFlush="false">
        <PatternLayout>
            <Pattern>%d %-5p [%25.25t] %40.40c{3.} %15X{sysid} %m%n</Pattern>
        </PatternLayout>
        <Policies>
            <TimeBasedTriggeringPolicy />
        </Policies>
        <DefaultRolloverStrategy max="8"/>
    </RollingFile>


但是web:contextPath没有得到解决。我的Web应用程序中有log4j-web-2.0.2.jar。我向WebLookup类添加了一些消息,问题是LoggerContext的外部上下文为null。

因此,我试图查看在何处创建LoggerContext。调用LoggerContext构造函数时的堆栈跟踪为

at org.apache.logging.log4j.core.LoggerContext.<init>(LoggerContext.java:114)
    at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.locateContext(ClassLoaderContextSelector.java:218)
    at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:113)
    at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:80)
    at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:82)
    at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:37)
    at org.apache.logging.log4j.LogManager.getContext(LogManager.java:269)
    at org.apache.logging.log4j.jcl.LogFactoryImpl$PrivateManager.getContext(LogFactoryImpl.java:108)
    at org.apache.logging.log4j.jcl.LogFactoryImpl.getLoggersMap(LogFactoryImpl.java:52)
    at org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(LogFactoryImpl.java:43)
    at org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(LogFactoryImpl.java:75)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685)
    at org.apache.myfaces.webapp.AbstractMyFacesListener.<clinit>(AbstractMyFacesListener.java:34)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at java.lang.Class.newInstance(Class.java:433)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:151)
    at org.apache.catalina.core.ApplicationContext.addListener(ApplicationContext.java:1231)
    at org.apache.catalina.core.ApplicationContextFacade.addListener(ApplicationContextFacade.java:647)
    at org.apache.jasper.servlet.JasperInitializer.onStartup(JasperInitializer.java:110)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5164)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:724)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:700)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:714)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:581)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1686)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745


但是ClassLoaderContextSelector始终为外部上下文传递null。所以看起来好像我缺少什么。

有人可以暗示我做错了什么,还是想念吗?我是否必须指定其他ContextSelector?

最佳答案

您可能在log4j中发现了一个错误。我怀疑是Commons Logging和WebLookup的组合不起作用。您是否可以验证这种情况(如果您的应用程序使用log4j 2 API而不是Commons Logging,请检查WebLookup是否工作)并在log4j2 Jira issue tracker中提交错误报告?

07-24 18:22