Web應用中Log4j與JNDI結合1 -- JNDI指定配置文件

Tomcat 定製JNDI URL Resource中我介紹瞭如何在tomcat中實現URL資源訪問,在Log4j配置實踐中我介紹了在Web應用中如何使用log4j xml配置方式記錄日誌。這篇我要介紹如何在Web應用中把Log4j和JNDI結合起來,達到可以動態修改Log4j配置文件路徑和Log4j日誌文件存儲路徑的目的。
我們知道,Spring本身提供了Log4jConfigListenerLog4jWebConfigurer來幫助初始化Log4j,其中參數log4jConfigLocation可以在classpath或者按指定路徑查找log4j配置文件,log4jRefreshInterval指定檢查加載配置文件變化。在這裏,我們要做的是根據Log4jConfigListener和Log4jWebConfiguer來定製自己的Log4jConfigListener,達到可以按JNDI來訪問配置文件的目的。給出實現如下:

package com.demo;
/*...
import ...here
...
*/
public class JndiLog4jConfigListener implements ServletContextListener {

    /** Parameter specifying the location of the log4j config file */
    public static final String CONFIG_LOCATION_PARAM = "log4jConfigLocation";

    /** Parameter specifying the location of the log4j config file */
    public static final String CONFIG_FILENAME_PARAM = "log4jConfigFilename";

    /** Parameter specifying the refresh interval for checking the log4j config file */
    public static final String REFRESH_INTERVAL_PARAM = "log4jRefreshInterval";

    /** Parameter specifying whether to expose the web app root system property */
    public static final String EXPOSE_WEB_APP_ROOT_PARAM = "log4jExposeWebAppRoot";

    public void contextInitialized(ServletContextEvent event) {
        // Expose the web app root system property.
            if (exposeWebAppRoot(servletContext)) {
                WebUtils.setWebAppRootSystemProperty(servletContext);
            }

            // Only perform custom log4j initialization in case of a config file.
            String location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
            String filename = servletContext.getInitParameter(CONFIG_FILENAME_PARAM);
            if (location != null) {
                // Perform actual log4j initialization; else rely on log4j's default initialization.
                try {
                    Context ic = new InitialContext();
                    location = ((URL)ic.lookup(location)).toExternalForm();
                    location = location + File.separator + filename;

                    // Write log message to server log.
                    servletContext.log("Initializing log4j from [" + location + "]");

                    // Check whether refresh interval was specified.
                    String intervalString = servletContext.getInitParameter(REFRESH_INTERVAL_PARAM);
                    if (intervalString != null) {
                        // Initialize with refresh interval, i.e. with log4j's watchdog thread,
                        // checking the file in the background.
                        try {
                            long refreshInterval = Long.parseLong(intervalString);
                            Log4jConfigurer.initLogging(location, refreshInterval);
                        }
                        catch (NumberFormatException ex) {
                            throw new IllegalArgumentException("Invalid 'log4jRefreshInterval' parameter: " + ex.getMessage());
                        }
                    }
                    else {
                        // Initialize without refresh check, i.e. without log4j's watchdog thread.
                        Log4jConfigurer.initLogging(location);
                    }
                }
                catch (Exception ex) {
                    throw new IllegalArgumentException("Invalid log4j Location: " + ex.getMessage());
                }
            }
    }

      public void contextDestroyed(ServletContextEvent event) {
            servletContext.log("Shutting down log4j");
            try {
                Log4jConfigurer.shutdownLogging();
            }
            finally {
                // Remove the web app root system property.
                if (exposeWebAppRoot(servletContext)) {
                    WebUtils.removeWebAppRootSystemProperty(servletContext);
                }
            }
      }

      private static boolean exposeWebAppRoot(ServletContext servletContext) {
        String exposeWebAppRootParam = servletContext.getInitParameter(EXPOSE_WEB_APP_ROOT_PARAM);
        return (exposeWebAppRootParam == null || Boolean.valueOf(exposeWebAppRootParam).booleanValue());
    }
}

Web.xml的配置如下:

<context-param>     
      <param-name>log4jConfigLocation</param-name>     
      <param-value>jndi:java:/comp/env/config_dir</param-value>     
  </context-param>     
 <context-param>     
      <param-name>log4jConfigFilename</param-name>     
      <param-value>log4j-demo.xml</param-value>     
  </context-param>  
  <context-param>     
      <param-name>log4jRefreshInterval</param-name>     
      <param-value>6000</param-value>     
  </context-param>     

  <listener>     
      <listener-class>com.demo.JndiLog4jConfigListener</listener-class>     
  </listener> 

<resource-ref>
     <res-ref-name> config_dir </res-ref-name>
    <res-type> java.net.URL </res-type>
    <res-auth> Container </res-auth>
 </resource-ref>
發佈了110 篇原創文章 · 獲贊 14 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章