您的位置:首页 > 其它

Web应用中Log4j与JNDI结合1 -- JNDI指定配置文件

2016-05-14 21:00 543 查看
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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: