`

Struts2 日志原理及配置方法(结合Log4j)

    博客分类:
  • SSH
阅读更多

Struts2  日志原理及配置方法
Struts2没有直接使用Log4j或JCL(Apache Java Commons Logger),也没有使用slf4j它先编写了自己的LoggerFactory(com.opensymphony.xwork2.util.logging.LoggerFactory),然后让其选择使用何种LoggerFactory,然后再进行日志处理
如果你在使用Struts2的类中使用它的日志系统,如在action中使用,可以按照以下的方式编码
package cn.sengtang.valuestack_ognl.web.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;

public class FooAction extends ActionSupport {
private Logger logger = LoggerFactory.getLogger(FooAction.class);

@Override
public String execute() throws Exception {
String msg="debug level logger Info";
logger.debug(msg);
return super.execute();
}
}
以下看看LoggerFactory.getLogger();方法的实现
getLoggerFactory().getLoggerImpl(cls);
而getLoggerFactory()的核心代码为
if (factory == null) {
                try {
                    Class.forName("org.apache.commons.logging.LogFactory");
                    factory = new com.opensymphony.xwork2.util.logging.commons.CommonsLoggerFactory();
                } catch (ClassNotFoundException ex) {
                    // commons logging not found, falling back to jdk logging
                    factory = new JdkLoggerFactory();
                }
}
显然,在Struts2的getLoggerFactory中有两种选择:Apache的CommonLogging 和JdkLoggerFactory,在前者不行的情况下将选择后者。
如何使用CommonLogger则其默认的LogFactory也会按照先后顺序决定使用哪个Log实现
References:commons-logging-1.1.1/site/guide.html#Quick Start
Look for a configuration attribute of this factory named org.apache.commons.logging.Log (for backwards compatibility to pre-1.0 versions of this API, an attribute org.apache.commons.logging.log is also consulted). Configuration attributes can be set explicitly by java code, but they are more commonly set by placing a file named commons-logging.properties in the classpath. When such a file exists, every entry in the properties file becomes an "attribute" of the LogFactory. When there is more than one such file in the classpath, releases of commons-logging prior to 1.1 simply use the first one found. From release 1.1, each file may define a priority key, and the file with the highest priority is used (no priority definition implies priority of zero). When multiple files have the same priority, the first one found is used. Defining this property in a commons-logging.properties file is the recommended way of explicitly selecting a Log implementation.
Look for a system property named org.apache.commons.logging.Log (for backwards compatibility to pre-1.0 versions of this API, a system property org.apache.commons.logging.log is also consulted).
If the Log4J logging system is available in the application class path, use the corresponding wrapper class (Log4JLogger).
If the application is executing on a JDK 1.4 system, use the corresponding wrapper class (Jdk14Logger).
Fall back to the default simple logging wrapper (SimpleLog).
大意如下
查找factory的org.apache.commons.logging.Log属性(这个API与1.0之前的版本是向后兼容的).可以通过Java代码对配置属性进行明确的设置,但更通用的方式是在classpath(类路径下)放置一个commons-logging.properties属性文件 。
查找名为org.apache.commons.logging.Log的系统属性
如果Log4j 日志系统在应用程序的类路径下是可用,则使用对用的包装器类Log4jLogger
如果应用程序运行在JDK1.4上,使用对应的包装器类Jdk14Logger
最后回退到使用默认的简单日志包装器SimpleLog
我们可以利用Common-Logger查找日志记录器的第3条原则,直接将Log4 的jar放到项目的Classpath中
并配置Log4j的log4j.properties就可以了
log4j.rootLogger=warn, stdout
log4j.logger.cn.sengtang=debug
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

那Struts2又是如何加载LoggerFactory的呢?
StrutsPrepareAndExecuteFilter中init方法的关键代码为
InitOperations init = new InitOperations();init.initLogging(config);
InitOperations.initLogging()的关键代码为:
String factoryName = filterConfig.getInitParameter("loggerFactory");
Class cls = ClassLoaderUtils.loadClass(factoryName, this.getClass());
LoggerFactory fac = (LoggerFactory) cls.newInstance();
LoggerFactory.setLoggerFactory(fac);
以下代码显示,Struts会通过名为loggerFactory的参数加载LoggerFactory,
则可以通过在web.xml中设置
<filter>
<filter-name>strut2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
<init-param>
<param-name>loggerFactory</param-name>
<param-value>
com.opensymphony.xwork2.util.logging.commons.CommonsLoggerFactory
</param-value>
</init-param>
</filter>
以上的请求过程,用序列图表示为:
可以直接将附件中的WAR部署,访问http://localhost:8080/struts2logger/Foo查看控制台的日志消息
源码包为struts2logger.rar

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics