問題描述:一個web項目想在一個tomcat下運行多個實例(通過修改war包名稱的實現),然后每個實例都將日志輸出到tomcat的logs目錄下實例名命名的文件夾下進行區分查看每個實例日志,要求通過盡可能少的改動配置文件,最好修改實例名后可以不修改log4j的配置文件。
實現分析:一般實現上面需求,需要在修改完war包名稱之外要再做下面配置:
1、修改每個實例名下web.xml中參數webAppRootKey為不同值。同一個tomcat下運行多個web應用時,該值相同的話,運行時會拋異常。
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webApp.root</param-value>
</context-param>
2、log4j配置文件日志輸出路徑修改
log4j配置文件中路徑配置一般有三種方法:
(1)絕對路徑法:直接配置為系統絕對路徑;
(2)相對路徑法:
log4j.appender.logfile.File=../logs/app.log,將日志記錄到tomcat下的logs文件夾;
log4j.appender.logfile.File=logs/app.log,將日志記錄到tomcat的bin目錄下的logs文件夾;
(3)使用環境變量相對路徑法:程序會優先找jvm環境變量,然后再找系統環境變量,來查找配置文件中的變量。
log4j.appender.logfile.File=${user.dir}/logs/app.log,使用tomcat容器時
${user.dir}
對應tomcat的bin目錄;
log4j.appender.logfile.File=${user.home}/logs/app.log,
${user.home}對應操作系統當前用戶目錄
;
log4j.appender.logfile.File=${
webApp.root
}/logs/app.log,
${
webApp.root
}
對應當前應用根目錄
;
暫時沒找到不修改log4j配置而實現上面需求的方法。在log4j配置文件中可以獲取環境變量來配置,但變量里沒有當前應用的名稱(不能直接通
過
webApp.root,因為它在不同的實例名稱不一樣
),嘗試在web.xml中增加listener,獲取應用名稱,然后調用System.setProperty("contextPath", sce.getServletContext().getContextPath());將上下文設置到系統變量中在log4j應用,但多實例運行時每個實例都會改變該屬性值。
結論,該問題的解決方法:
1、手動修改配置,修改war名稱后手動修改web.xml和log4j配置文件,實現上述需求。
2、通過其它程序來進行批量修改,若bat或maven等在修改war包名稱時,自動修改掉web.xml和log4j中相關配置。