1. 程式人生 > >spring中的Log4jConfigListener作用和webapp.root的設定

spring中的Log4jConfigListener作用和webapp.root的設定

轉:http://blog.sina.com.cn/s/blog_7bbf356c01016wld.html

使用spring中的Log4jConfigListener有如如下好處: 
 1. 動態的改變記錄級別和策略,不需要重啟Web應用,如《Effective Enterprise Java》所說。 
 2. 把log檔案定在 /WEB-INF/logs/ 而不需要寫絕對路徑。 
因為 系統把web目錄的路徑壓入一個叫webapp.root的系統變數。這樣寫log檔案路徑時不用寫絕對路徑了. 
log4j.appender.logfile.File=${webapp.root}/WEB-INF/logs/myfuse.log 


 3. 可以把log4j.properties和其他properties一起放在/WEB-INF/ ,而不是Class-Path。 
 4.log4jRefreshInterval為6000表示 開一條watchdog執行緒每6秒掃描一下配置檔案的變化; 
 在web.xml 新增

  <context-param> 
        <param-name>log4jConfigLocation</param-name> 
        <param-value>WEB-INF/log4j.properties</param-value> 
    </context-param> 

    <context-param> 
        <param-name>log4jRefreshInterval</param-name> 
        <param-value>6000</param-value> 
    </context-param> 

    <listener> 
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
    </listener>

在使用spring先後開發了兩個模組,單獨測試都正常。也先後上線執行,之後發現有個模組在啟動Tomcat後總是初始化失敗,必須到tomcat管理控制檯手動啟動。找了半天也沒發現原因。後來管理員在每次重啟Tomcat後這個模組沒有執行導致一堆問題和麻煩,今天特意查看了其他的tomcat日誌檔案,終於發現了問題所在,原來是Log4jConfigListener。使用它是為了隨時調整列印日誌的級別而不用重啟服務。沒想到沒有享受到它的便利,反而出了一堆問題,只能怪自己沒有稍微仔細研究一下。 
<context-param>   
    <param-name>webAppRootKey</param-name>   
        <param-value>cang.qing6.com.root</param-value>   
    </context-param>   
   
    <context-param>   
        <param-name>log4jConfigLocation</param-name>   
        <param-value>/WEB-INF/classes/log4j.properties</param-value>   
    </context-param>   
   
    <context-param>   
        <param-name>log4jRefreshInterval</param-name>   
        <param-value>6000</param-value>   
    </context-param>   
    <listener>   
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>   
    </listener>   

<context-param>
 <param-name>webAppRootKey</param-name>
  <param-value>cang.qing6.com.root</param-value>
 </context-param>

 <context-param>
  <param-name>log4jConfigLocation</param-name>
  <param-value>classpath:log4j.properties</param-value>
 </context-param>

 <context-param>
  <param-name>log4jRefreshInterval</param-name>
  <param-value>6000</param-value>
 </context-param>
 <listener>
  <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
 </listener>

log4j.properties配置
layoutPattern=[%d{HH:mm:ss}] %-5p : %m%n    
log.file=${message.web.root}/logs/app.log    
   
log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender    
log4j.appender.logfile.File=${log.file}    
log4j.appender.logfile.Append=true   
log4j.appender.logfile.DatePattern='.'yyyyMMdd    
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout    
log4j.appender.logfile.layout.ConversionPattern=${layoutPattern}   

layoutPattern=[%d{HH:mm:ss}] %-5p : %m%n
log.file=${message.web.root}/logs/app.log

log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.File=${log.file}
log4j.appender.logfile.Append=true
log4j.appender.logfile.DatePattern='.'yyyyMMdd
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=${layoutPattern}
其實需要注意的地方就是應用伺服器下有不止一個的應用在使用spring的Log4jConfigListener需要修改web環境中webAppRootKey值(這個值其實是web應用的根目錄在環境變數名,這樣在log4j配置檔案中如果有相對web目錄的路徑就不用寫死了)。 
否則兩個預設值web.root在環境變數中就會有衝突導致第二個應用啟動失敗。

轉:http://blog.csdn.net/cx921138/article/details/4736825

參考:

http://blogabc.googlecode.com/svn/trunk/doc/log4j.txt

http://jeiofw.blog.51cto.com/3319919/963145

近日,因為懶惰,直接從原有專案切出一個分塊成了一個專案,然後同時釋出啟動,出現以下異常

Exception sending context initialized event to listener instance of class org.springframework.web.util.Log4jConfigListener
java.lang.IllegalStateException: Web app root system property already set to different value: 'webapp.root' = [D:/tomcat-5.0.19/webapps/tzbms/] instead of [D:/tomcat-5.0.19/webapps/its/] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files!

at org.springframework.web.util.WebUtils.setWebAppRootSystemProperty(WebUtils.java:99)
    at org.springframework.web.util.Log4jWebConfigurer.initLogging(Log4jWebConfigurer.java:116)
    at org.springframework.web.util.Log4jConfigListener.contextInitialized(Log4jConfigListener.java:51)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3773)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4270)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:866)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:850)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:638)
    at org.apache.catalina.core.StandardHostDeployer.install(StandardHostDeployer.java:320)
    at org.apache.catalina.core.StandardHost.install(StandardHost.java:875)
    at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:657)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:476)
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1008)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:394)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:166)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1134)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:832)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1126)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:521)
    at org.apache.catalina.core.StandardService.start(StandardService.java:519)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:2345)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:594)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:324)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:297)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:398)

看看異常,還是挺簡單的,應該是兩個專案的設定重複了,導致出錯,但我發現web.xml裡並沒有配置webAppRootKey項,原來是因為如果沒有web.xm 內沒有設定webAppRootKey項,是為預設設定
public  static  void  setWebAppRootSystemProperty(ServletContext servletContext) throws  IllegalStateException  {
        String  param = servletContext.getInitParameter(WEB_APP_ROOT_KEY_PARAM);
        String  key = (param != null  ? param : DEFAULT_WEB_APP_ROOT_KEY);
        String  oldValue = System .getProperty(key);
        if  (oldValue != null ) {
            throw  new  IllegalStateException ("WARNING: Web app root system property already set: "  + key + " = "  +
                                                                
            oldValue + " - Choose unique webAppRootKey values in your web.xml files!" );
        }
        String  root = servletContext.getRealPath("/" );
        if  (root == null ) {
            throw  new  IllegalStateException ("Cannot set web app root system property when WAR file is not 
expanded");
        }
        System .setProperty(key, root);
        servletContext.log("Set web app root system property: "  + key + " = "  + root);
    }

從程式碼看出,該方法其實就是把該web application的根目錄的絕對檔案路徑作為屬性儲存在 System的屬性列表中。該屬性的名字,由web.xml檔案中的名為"webAppRootKey"的引數值指出。如果不在web.xml中定義 webAppRootKey引數,那麼屬性名就是預設的"webapp.root".在我們的petclinic專案中已經定義了 webAppRootKey引數,其值為"petclinic.root",因此,屬性的名字就是"petclinic.root".