我有两个在同一个WebSphere 8.5.5服务器上运行的Web应用程序。第一个应用程序能够在web.xml中使用表达式语言(EL)来访问JVM变量,如下所示:
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/config/log4j-${app.env}.xml</param-value>
</context-param>
这允许我在服务器上设置名为app.env的JVM变量,该变量确定使用哪个log4j配置文件。根据环境将此变量设置为rad,test或production。
此外,因为这些应用程序将在集群环境中运行但是登录到同一网络共享,所以我需要在log4j配置文件中使用EL来区分日志文件。这是在log4j配置文件中使用EL实现的,如下所示:
<appender name="file" class="com.example.util.CustodianDailyRollingFileAppender">
<param name="maxNumberOfDays" value="10" />
<param name="compressBackups" value="yes" />
<param name="File" value="/netshare/logs/${app.serv}_app.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d] %-5p %c - %m%n" />
</layout>
</appender>
app.serv JVM变量在集群中的第一台服务器上设置为“1”,在第二台服务器上设置为“2”,这导致每个正在创建的服务器的日志文件分别名为1_app.log和2_app.log 。
第一个应用程序使用Servlets 2.4和Spring Framework 3.0.4。
在第二个应用程序中,我正在尝试对我的日志文件使用相同的方案,但是,我正在使用Servlets 3.0而不使用Spring Framework,而是试图坚持使用JEE6。但是,不会在web.xml或log4j配置文件中评估EL。
如果我将EL放在第二个应用程序的web.xml中,那么log4j会抛出异常,因为它无法在定义的位置找到配置文件,因为EL尚未被评估:
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>/WEB-INF/log4j2-${app.env}.xml</param-value>
</context-param>
这会导致异常,因为log4j正在寻找log4j2 - $ {app.env} .xml而不是log4j2-rad.xml。
类似地,如果我硬编码配置位置并尝试在log4j2配置中使用EL,则EL不会被评估,并且当它应该评估时,我最终得到名为$ {app.serv} _app.log的日志文件。 EL并命名文件1_app.log。
提出了我的问题:
1)应用程序1和应用程序2之间的区别是导致我的web.xml和log4j配置中的EL不被评估?
2)如何在应用程序2中的web.xml和log4j配置文件中使用EL?
答案 0 :(得分:0)
我想我已经设法回答了我自己的问题:
1)应用程序1和应用程序2之间有什么区别导致我的web.xml和log4j配置中的EL无法评估?
差异是双重的:
首先,Applicaton A是一个Spring应用程序,它使用Spring附带的Log4JConfigListener类。 Log4JConfigListener是一个ServletContextListener,它基本上只是帮助Log4j配置类查找配置文件。此外,在执行此操作之前,它会解析web.xml中Log4J配置位置上下文参数中使用的任何占位符。我自己能够通过实现自己的ServletContextListener来重现这种行为,它与Spring完全相同。
其次,应用程序A使用的是Log4j 1.2.x,而应用程序B正在尝试使用Log4j 2.x.最初,我认为Log4j 2.x根本没有做Log4j 1.2.x在其OptionConverter类中所做的占位符分辨率。所以,我通过恢复到Log4j 1.2.x解决了这个问题。从那以后,我将更改回Log4j 1.2.x,我注意到log4j-1.2-api-2.x.jar中似乎有适配器类。这个罐子不存在于我的应用程序B的类路径中,如果他们在那里可能会有所不同。我可能会在以后对此进行调查,但是现在,我很高兴能够使用Log4j 1.2.x。
2)如何在应用程序2中的web.xml和log4j配置文件中使用EL?
上面回答了问题2,其中ServletContextListener在将文件位置传递给Log4j配置器之前解析表达式,并使用Log4j 1.2.x而不是Log4j 2.x解析表达式。我再次强调,如果log4j-1.2-api-2.x.jar在类路径上,Log4j 2.x可能会有相同的行为,但我现在无法亲自验证这一点。