我有一个必须在Win或Linux机器上部署的java webapp.我现在想添加log4j用于日志记录,我想使用日志文件的相对路径,因为我不想在每个部署上更改文件路径.容器很可能是Tomcat,但不一定.
这样做的最佳方法是什么?
Tomcat设置了catalina.home系统属性.您可以在log4j属性文件中使用它.像这样的东西:
log4j.rootCategory=DEBUG,errorfile log4j.appender.errorfile.File=${catalina.home}/logs/LogFilename.log
在Debian(包括Ubuntu)上,${catalina.home}
将无法工作,因为它指向/ usr/share/tomcat6,它没有链接到/ var/log/tomcat6.这里只是用${catalina.base}
.
如果您使用其他容器,请尝试查找类似的系统属性,或定义自己的属性.设置系统属性将因平台和容器而异.但是对于Linux/Unix上的Tomcat,我会在CATALINA_HOME/bin目录中创建一个setenv.sh.它将包含:
export JAVA_OPTS="-Dcustom.logging.root=/var/log/webapps"
然后你的log4j.properties将是:
log4j.rootCategory=DEBUG,errorfile log4j.appender.errorfile.File=${custom.logging.root}/LogFilename.log
我终于以这种方式完成了它.
添加了一个ServletContextListener,它执行以下操作:
public void contextInitialized(ServletContextEvent event) { ServletContext context = event.getServletContext(); System.setProperty("rootPath", context.getRealPath("/")); }
然后在log4j.properties文件中:
log4j.appender.file.File=${rootPath}WEB-INF/logs/MyLog.log
通过这种方式,Log4j将写入正确的文件夹,只要您在设置"rootPath"系统属性之前不使用它.这意味着您无法从ServletContextListener本身使用它,但您应该能够在应用程序的任何其他位置使用它.
它应该适用于每个Web容器和操作系统,因为它不依赖于特定于容器的系统属性,并且不受操作系统特定路径问题的影响.使用Tomcat和Orion Web容器以及Windows和Linux进行测试,到目前为止工作正常.
你怎么看?
如果您使用Spring,您可以:
1)创建一个log4j配置文件,例如"/WEB-INF/classes/log4j-myapp.properties"不要将其命名为"log4j.properties"
例:
log4j.rootLogger=ERROR, stdout, rollingFile log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender log4j.appender.rollingFile.File=${myWebapp-instance-root}/WEB-INF/logs/application.log log4j.appender.rollingFile.MaxFileSize=512KB log4j.appender.rollingFile.MaxBackupIndex=10 log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout log4j.appender.rollingFile.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.rollingFile.Encoding=UTF-8
稍后我们将在第(3)点定义"myWebapp-instance-root"
2)在web.xml中指定配置位置:
log4jConfigLocation /WEB-INF/classes/log4j-myapp.properties
3)为webapp的根指定唯一的变量名,例如"myWebapp-instance-root"
webAppRootKey myWebapp-instance-root
4)添加Log4jConfigListener:
org.springframework.web.util.Log4jConfigListener
如果您选择其他名称,请记住在log4j-myapp.properties中更改它.
看我的文章(仅限意大利语......但它应该是可以理解的):http: //www.megadix.it/content/configurare-path-relativi-log4j-utilizzando-spring
更新(2009/08/01) 我把我的文章翻译成英文:http: //www.megadix.it/node/136
只是评论Iker的解决方案.
ServletContext
对您的问题是一个很好的解决方案.但我不认为这对维护有好处.大多数时间日志文件都需要保存很长时间.
由于ServletContext
在已部署的文件下生成文件,因此在重新部署服务器时将删除该文件.我的建议是使用rootPath的父文件夹而不是子文件夹.
如果未在FileAppender的path属性中指定根目录,log4j是否只使用应用程序根目录?所以你应该能够使用:
log4j.appender.file.File =日志/ MyLog.log
自从我完成Java Web开发以来已经有一段时间了,但这似乎是最直观的,并且也不会与写入$ {catalina.home}/logs目录的其他不幸的命名日志冲突.