概述
在spring搭建项目时,一般都是需要使用log4j。此时,需要在web.xml中配置好log4j,或者log4j.xml中进行路径配置,此时就需要进行log4j的配置了解。
web.xml中的配置
在spring中,使用log4j时,主要2点。一是web.xml中配置log4j;二是项目的webapp下配置log4j.xml。首先是web.xml中配置。如下:
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.xml</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
web.xml最前面写入以上的配置就可以了。
参数:log4jConfigLocation主要是配置log4j.xml的文件位置。可以指定方式如下:
1.类路径,例如:classpath:log4j.xml;
2.绝对文件路径,例如:d:/log4j.xml;
3.如果不指定,默认采取class路径中的”log4j.properties” 或 “log4j.xml”
参数:log4jRefreshInterval主要检测log4j配置文件刷新时间,动态修改log4j配置。
指定参数:配置文件刷新时间(单位是毫秒)
不指定参数:不再检查log4j配置文件有没有发生,同时log4j的监督线程将不会启动。
注意点:
log4j的listener配置要优先于spring的ContextLoaderListener配置。
log4j.xml中的路径问题
在log4j.xml中配置文件时,可以如下配置:
log4j.appender.myfile.File=${webapp.root}/WEB-INF/demo.log
将路径指定为动态的{webapp.root},它会在项目运行时,进行替换操作,它允许日志文件路径相对于web应用程序的根目录。
当需要使用多个webapp.root时,或者需要换个名字时,可以在web.xml中如下配置:
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>demo.root</param-value>
</context-param>
如此,log4j中就可以采取如下方式指定了:
log4j.appender.myfile.File=${demo.root}/WEB-INF/demo.log
Log4jConfigListener说明
采取Log4jConfigListener配置时,它的源码如下:
/**
* <p>This listener should be registered before ContextLoaderListener in {@code web.xml}
* when using custom log4j initialization.
*/
public class Log4jConfigListener implements ServletContextListener {
public Log4jConfigListener() {
}
public void contextInitialized(ServletContextEvent event) {
Log4jWebConfigurer.initLogging(event.getServletContext());
}
public void contextDestroyed(ServletContextEvent event) {
Log4jWebConfigurer.shutdownLogging(event.getServletContext());
}
}
主要使用了Log4jWebConfigurer进行初始化等操作。类说明了,应该在ContextLoaderListener 之前进行初始化操作。其余介绍可参考源码。
Log4jWebConfigurer说明
Log4jWebConfigurer简化源码如下所示:
public abstract class Log4jWebConfigurer {
/** Parameter specifying the location of the log4j config file */
public static final String CONFIG_LOCATION_PARAM = "log4jConfigLocation";
/** 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";
/**
* Initialize log4j, including setting the web app root system property.
* @param servletContext the current ServletContext
* @see WebUtils#setWebAppRootSystemProperty
*/
public static void initLogging(ServletContext servletContext) {
.....
}
/**
* Shut down log4j, properly releasing all file locks
* and resetting the web app root system property.
* @param servletContext the current ServletContext
* @see WebUtils#removeWebAppRootSystemProperty
*/
public static void shutdownLogging(ServletContext servletContext) {
.......
}
/**
* Return whether to expose the web app root system property,
* checking the corresponding ServletContext init parameter.
* @see #EXPOSE_WEB_APP_ROOT_PARAM
*/
private static boolean exposeWebAppRoot(ServletContext servletContext) {
String exposeWebAppRootParam = servletContext.getInitParameter(EXPOSE_WEB_APP_ROOT_PARAM);
return (exposeWebAppRootParam == null || Boolean.valueOf(exposeWebAppRootParam));
}
}
前面的三个参数就是我们在web.xml中进行配置的参数,后面的2个方法是log4j的初始化方法。
log4jConfigLocation说明:
/** Parameter specifying the location of the log4j config file */
public static final String CONFIG_LOCATION_PARAM = "log4jConfigLocation";
/*
* Location of the log4j config file; either a "classpath:" location (e.g.
* "classpath:myLog4j.properties"), an absolute file URL (e.g. "file:C:/log4j.properties),
* or a plain path relative to the web application root directory (e.g.
* "/WEB-INF/log4j.properties"). If not specified, default log4j initialization
* will apply ("log4j.properties" or "log4j.xml" in the class path; see the
* log4j documentation for details).
*/
log4jRefreshInterval说明:
/** Parameter specifying the refresh interval for checking the log4j config file */
public static final String REFRESH_INTERVAL_PARAM = "log4jRefreshInterval";
/*
* Interval between config file refresh checks, in milliseconds. If not specified,
* no refresh checks will happen, which avoids starting log4j's watchdog thread.
*/
log4jExposeWebAppRoot说明:
/** Parameter specifying whether to expose the web app root system property */
public static final String EXPOSE_WEB_APP_ROOT_PARAM = "log4jExposeWebAppRoot";
/**
* Whether the web app root system property should be exposed, allowing for log
* file paths relative to the web application root directory. Default is "true";
* specify "false" to suppress expose of the web app root system property. See
* below for details on how to use this system property in log file locations.
*/
这个参数一般不需要配置,默认是”true”,是否暴漏log4j配置。在 Log4jWebConfigurer的initLogging(ServletContext servletContext)中会去检查,如下所示:
public static void initLogging(ServletContext servletContext) {
// Expose the web app root system property.
if (exposeWebAppRoot(servletContext)) {
WebUtils.setWebAppRootSystemProperty(servletContext);
}
.......
}
setWebAppRootSystemProperty方法就说明了webapp的设置和webAppRootKey的设置问题。
/**
* Web app root key parameter at the servlet context level
* (i.e. a context-param in {@code web.xml}): "webAppRootKey".
*/
public static final String WEB_APP_ROOT_KEY_PARAM = "webAppRootKey";
/** Default web app root key: "webapp.root" */
public static final String DEFAULT_WEB_APP_ROOT_KEY = "webapp.root";
/**
* Set a system property to the web application root directory.
* The key of the system property can be defined with the "webAppRootKey"
* context-param in {@code web.xml}. Default is "webapp.root".
* <p>Can be used for tools that support substition with {@code System.getProperty}
* values, like log4j's "${key}" syntax within log file locations.
* @param servletContext the servlet context of the web application
* @throws IllegalStateException if the system property is already set,
* or if the WAR file is not expanded
* @see #WEB_APP_ROOT_KEY_PARAM
* @see #DEFAULT_WEB_APP_ROOT_KEY
* @see WebAppRootListener
* @see Log4jWebConfigurer
*/
public static void setWebAppRootSystemProperty(ServletContext servletContext) throws IllegalStateException {
Assert.notNull(servletContext, "ServletContext must not be null");
String root = servletContext.getRealPath("/");
if (root == null) {
throw new IllegalStateException(
"Cannot set web app root system property when WAR file is not expanded");
}
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 && !StringUtils.pathEquals(oldValue, root)) {
throw new IllegalStateException(
"Web app root system property already set to different value: '" +
key + "' = [" + oldValue + "] instead of [" + root + "] - " +
"Choose unique values for the 'webAppRootKey' context-param in your web.xml files!");
}
System.setProperty(key, root);
servletContext.log("Set web app root system property: '" + key + "' = [" + root + "]");
}
log4j的init方法如下:
/**
* Initialize log4j, including setting the web app root system property.
* @param servletContext the current ServletContext
* @see WebUtils#setWebAppRootSystemProperty
*/
public static void initLogging(ServletContext servletContext) {
// 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);
if (location != null) {
// Perform actual log4j initialization; else rely on log4j's default initialization.
try {
// Resolve property placeholders before potentially resolving a real path.
location = ServletContextPropertyUtils.resolvePlaceholders(location, servletContext);
// Leave a URL (e.g. "classpath:" or "file:") as-is.
if (!ResourceUtils.isUrl(location)) {
// Consider a plain file path as relative to the web
// application root directory.
location = WebUtils.getRealPath(servletContext, location);
}
// 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 (FileNotFoundException ex) {
throw new IllegalArgumentException("Invalid 'log4jConfigLocation' parameter: " + ex.getMessage());
}
}
}
主要:1.检查是否暴漏;2.读取log4j文件;3.替换log4j文件的占位符;4.读取刷新时间,初始化log4j。最终调用Log4jConfigurer方法。
shutdownLogging主要就是关闭log4j了。
/**
* Shut down log4j, properly releasing all file locks
* and resetting the web app root system property.
* @param servletContext the current ServletContext
* @see WebUtils#removeWebAppRootSystemProperty
*/
public static void shutdownLogging(ServletContext servletContext) {
servletContext.log("Shutting down log4j");
try {
Log4jConfigurer.shutdownLogging();
}
finally {
// Remove the web app root system property.
if (exposeWebAppRoot(servletContext)) {
WebUtils.removeWebAppRootSystemProperty(servletContext);
}
}
}
以上基本介绍了log4j,具体的实现待考虑下。
参考文档:官方文档—https://docs.spring.io/spring/docs/2.5.x/javadoc-api/org/springframework/web/util/Log4jWebConfigurer.html
最后
以上就是喜悦冰棍为你收集整理的Spring搭建:log4j的配置的全部内容,希望文章能够帮你解决Spring搭建:log4j的配置所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复