﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-VIRGIN FOREST OF JAVA-文章分类-Log4j</title><link>http://www.blogjava.net/RR00/category/2663.html</link><description>不要埋头苦干，要学习，学习，再学习。。。。。
&lt;br&gt;
powered  by &lt;font color='orange'&gt;R.Zeus&lt;/font&gt;</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 10:37:59 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 10:37:59 GMT</pubDate><ttl>60</ttl><item><title>Set the Logging Level Over a Tomcat Cluster Dynamically</title><link>http://www.blogjava.net/RR00/articles/69693.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 14 Sep 2006 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/69693.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/69693.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/69693.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/69693.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/69693.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" border="0">
				<tbody>
						<tr>
								<td align="left" width="75">
										<img height="75" src="http://assets.devx.com/articleicons/6484.gif" width="75" align="left" border="0" />
								</td>
								<td width="10"> </td>
								<td valign="top">
										<div class="articleTitle">Set the Logging Level Over a Tomcat Cluster Dynamically</div>
										<div class="articleDek">Rather than modifying your Log4J configuration and then redeploying the correct code version with the modified logging level, you can dynamically set the Log4J logging level over each node in a Tomcat cluster with JMX. </div>
										<br />
										<table cellspacing="0" cellpadding="0" width="100%" border="0">
												<tbody>
														<tr>
																<td class="articleAuthor" align="left">by Jon Dickinson</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />henever you have to fix a problem in a production environment, one of the most common issues is retrieving some useful debug information to tell you what happened. Of course, to avoid needless notifications and enormous log files, most production systems are configured to log only errors. To avoid having to modify your Log4J configuration and then redeploy the correct version of the code with the modified logging level, why not just implement a mechanism for dynamically changing the logging level? <br /><a href="http://www.devx.com/Java/Article/32359#codeitemarea"></a><div><br />Log4J registers a number of MBeans, one of which provides access to the root logger. You can dynamically modify the logging level of the root logger by implementing the following servlet to set the appropriate MBean property through JMX: <pre><code>
public class SetLog4jLevelServlet extends HttpServlet {
    private static final Log log = LogFactory.getLog(SetLog4jLevelServlet.class);

    protected void doGet(HttpServletRequest request, 
            HttpServletResponse response) 
            throws ServletException, IOException {
        List list = MBeanServerFactory.findMBeanServer(null);
        MBeanServer server  = (MBeanServer)list.iterator().next();

        try {
            String loggingLevel = request.getParameter("level");
            Attribute attribute = new Attribute("priority", loggingLevel);
            ObjectName objectName = new ObjectName("log4j:logger=root");
            server.setAttribute(objectName, attribute);
        } catch (Exception e) {
            log.error("log4j:logger=root", e);
        }
    }
}
</code></pre><p>The first two lines of the doGet method look up the MBeanServer. Log4J registers the root logger with the name <i>log4j:logger=root</i>. This MBean provides a property to set the logging level of the root logger. You set the priority of the root logger by passing the ObjectName of the MBean to operate on, along with an instance of javax.management.Attribute to the MBean Server. In this case, you want to set the "priority" attribute. The value will be the new logging level you have specified<br /><br /></p><h4>A Log4J MBean for Each Log4J Configuration</h4><p>Although this technique seems simple, if your Tomcat cluster hosts a number of Web applications—each with its own Log4J configuration that allows it to log to a separate log file—then you will run into your first problem. Given multiple Log4J configurations, only the first one loaded by the JVM will have a root logger MBean associated with it. The reason for this is Log4J hard-codes the JMX Domain that it uses when registering its MBeans as <i>log4j</i>, and the JMX server doesn't allow duplicate names.<br /><br /></p><div><p>The way round this is to leave a Tomcat server Log4J configuration (jars under server/lib and property files under server/classes) registered under the default Log4J name <i>log4j:logger=root</i>. Then register the root logger for each Web application in a startup servlet, using the Web application name to identify the domain: </p><pre><code>
public class RegisterLog4JMBeanServlet extends HttpServlet {

    private static final Log log = LogFactory.getLog(RegisterLog4JMBeanServlet.class);

    public void init(ServletConfig servletConfig) 
            throws ServletException {
        ServletContext context = servletConfig.getServletContext();
        String webappName = context.getServletContextName();
        Hashtable&lt;String, String&gt; nameParameters = new Hashtable&lt;String, String&gt;();
        nameParameters.put("logger", "root");

        Logger rootLogger = LogManager.getRootLogger();
        LoggerDynamicMBean mbean = new LoggerDynamicMBean(rootLogger);
        List list = MBeanServerFactory.findMBeanServer(null);
        MBeanServer server  = (MBeanServer)list.iterator().next();

        ObjectName objectName = null;
        try {
            objectName = new ObjectName(webappName, nameParameters);
            server.registerMBean(mbean, objectName);
        } catch (Exception e) {
            log.error("Problems registering Log4J MBean", e);
        }
    }
}
</code></pre><p>You will end up with an MBean named &lt;<i>web-app-name&gt;: logger=root</i> for each Web application. The webappName is retrieved from the &lt;<i>display-name</i>&gt; element in your application's web.xml file, and the application's root logger is retrieved by calling <code>LogManager.getRootLogger()</code>. Then you can use the LoggerDynamicMBean class from Log4J to create your MBean from the root logger definition. 
</p><p>To create a distinct ObjectName for the new MBean, you should use the Web application name as the JMX domain (this is the text before the colon) and then register the Root Logger MBean with the new ObjectName. This will guard against conflicts with other Log4J MBeans. 
</p><p>Now that you have registered your Root Logger under a different domain, you must modify the servlet that sets the logging level. So in SetLog4JlevelServlet, change this: </p><pre><code>
ObjectName objectName = new ObjectName("log4j:logger=root");
</code></pre><p>To this: </p><pre><code>
ServletContext context = servletConfig.getServletContext();
String webappName = context.getServletContextName();
Hashtable&lt;String, String&gt; nameParameters = new Hashtable&lt;String, String&gt;();
nameParameters.put("logger", "root");
ObjectName objectName = new ObjectName(webappName, nameParameters);
</code></pre><p>When setting up your Log4J configuration, give your Log4J appenders unique names. Otherwise, they will not get registered to the JMX server and you will get lots of the following errors in your log files at startup: </p><pre><code>
ERROR main org.apache.log4j.jmx.LoggerDynamicMBean ? - Could not add appenderMBean for [&lt;<i>appender_name</i>&gt;].
javax.management.InstanceAlreadyExistsException: log4j:appender=&lt;<i>appender_name</i>&gt;
</code></pre><p>Again, the reason for this is because the JMX domain name his hard-coded to <i>log4j</i>, so if you have repeated appender names then only the first of these will be registered. 
</p><p>At this point, configuring the MX4J HTTP adaptor in your Tomcat server might be useful. This will give you a visual representation of the MBeans you are creating and manipulating, and show you what else is exposed via MBeans within Tomcat. To do this, you must put the mx4j-tools.jar file (download it at <a href="http://mx4j.sourceforge.net/" target="new"><font color="#002c99">mx4j.sourceforge.net</font></a>) in your common/lib directory. Then configure your server.xml file to set up the connector as follows: </p><pre><code>
    &lt;Connector port="8010" 
           handler.list="mx" 
           mx.enabled="true" 
           mx.httpHost="localhost"
           mx.httpPort="8013"
           protocol="AJP/1.3"/&gt;
</code></pre><p>When you start your server, you will be able to access the MX4J HTTP connector through your browser at http://localhost:8013, assuming you have no other Tomcat connector running on port 8010. 
</p><h4>Set the Logging Level for All the Nodes in Your Cluster</h4><p>Once you have made the previously discussed changes, you will be able to set the Log4J logging level dynamically for any application running in Tomcat. The next challenge is to make sure you can set the logging level for every node in the cluster. You could either call this servlet manually on each node in the cluster or get the servlet to send a message to every other node in the cluster so the logging levels are always the same across the cluster</p><div>To send a message to the other nodes in a Tomcat cluster, you need to call the <code>send(ClusterMessage)</code> method on the org.apache.catalina.cluster.SimpleTcpCluster class. When implementing a ClusterMessage, you must populate the details of the cluster node that was responsible for sending the request. (<a href="javascript:showSupportItem('listing1')"><font color="#002c99">Listing 1</font></a> provides an example that retrieves the information through the Tomcat MBeans.) The first step is to provide an implementation of the ClusterMessage interface to pass the new logging level and to determine for which application you want to set the logging level. 
<p>It may seem strange, but you must use JMX over RMI to send the message to the cluster because the interface implemented in <a href="javascript:showSupportItem('listing1')"><font color="#002c99">Listing 1</font></a> is defined within the Tomcat server class loader (i.e., it exists in a jar file in the server directory). You will instantiate that class in a Web application, which uses a totally separate class loader (it exists in the WEB-INF directory of your Web application). This means that the cluster message you instantiate in your Web application and send to the SimpleTcpCluster class will be different from the cluster message definition that is placed in the Tomcat server class loader. If you try to send your message directly through JMX, your cluster message instance will not match the cluster message definition accessible to the SimpleTcpCluster class and the call will fail. (See the <a href="http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html" target="new"><font color="#002c99">Tomcat documentation on class loaders</font></a> for a definition of how the class loaders are configured for the Tomcat server.) 
</p><p>The workaround is to use JMX over RMI so the cluster message is serialized in the Web application class loader, instantiated in the Tomcat server class loader (and that is the important point), and then de-serialized. The following method opens a connection to the local JVM's JMX server over RMI, looks up the MBean that wraps the SimpleTcpCluster, and then invokes the <code>send(ClusterMessage)</code> operation on the MBean: </p><pre><code>
public static void sendLogMessageEvent(String applicationName, String logLevel) {
    String port = System.getProperty("com.sun.management.jmxremote.port");
    String urlForJMX = JMX_SERVICE_PREFIX + HOST + ":" + port + JMX_SERVICE_SUFFIX;

    try {
        JMXServiceURL url = new JMXServiceURL(urlForJMX);
        JMXConnector connector = JMXConnectorFactory.connect(url, null);
        MBeanServerConnection server = connector.getMBeanServerConnection();
        ObjectName cluster = new ObjectName("Catalina:type=Cluster,host=localhost");
        log.debug("Cluster cluster: " + cluster.toString());

        LogLevelMessage message = new LogLevelMessage();
        message.setLoggingLevel(logLevel);
        message.setApplication(applicationName);

        Object[] params = new Object[] {message};
        String[] types = new String[] {"org.apache.catalina.cluster.ClusterMessage"};
        server.invoke(cluster, "send", params, types);
    } catch (Exception e) {
        log.error(e.getMessage(), e);
    }
}
</code></pre><p>You should call this method in your SetLog4JLevelServlet to ensure that a message is sent to the other members of the cluster when you set the logging level. 
</p><p>You will need to configure your Tomcat server to allow a JMX connection to be opened up over RMI. Simply add the following line to your catalina.bat file in the bin directory: </p><pre><code>
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.management.jmxremote.port=8012 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false
</code></pre><p>For a quick guide on applying security to this configuration, see the <a href="http://tomcat.apache.org/tomcat-5.5-doc/monitoring.html" target="new"><font color="#002c99">Tomcat documentation</font></a>. For a more in-depth look at configuring JMX Remote, see the <a href="http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html#remote" target="new"><font color="#002c99">Sun documentation</font></a>. 
</p><div><h4>Receiving the Message in the Other Nodes</h4>Once you are able to send these messages to the other nodes in the cluster, you will need to implement a Tomcat ClusterListener to receive the events. This implementation will set the logging level for the correct MBean determined by the application name that is passed as part of the message: <pre><code>
public class ClusterLoggingListener extends ClusterListener {

    private static final Log log = LogFactory.getLog(ClusterLoggingListener.class);
    
    public void messageReceived(ClusterMessage message) {
        if(message instanceof LogLevelMessage) {
            LogLevelMessage logMessage = (LogLevelMessage) message;
            List list = MBeanServerFactory.findMBeanServer(null);
            MBeanServer server  = (MBeanServer)list.iterator().next();
            Hashtable&lt;String, String&gt; nameParameters = new Hashtable&lt;String, String&gt;();
            nameParameters.put("logger", "root");
            try {
                ObjectName logBean = new ObjectName(logMessage.getApplication(), nameParameters);
                Attribute attribute = new Attribute("priority", logMessage.getLoggingLevel());
                server.setAttribute(logBean, attribute);
            } catch (Exception e) {
                log.error("Problem setting the logging level for application " + 
                        logMessage.getApplication() + " to level " + 
                        logMessage.getLoggingLevel(),e);
            }
        }
    }
    public boolean accept(ClusterMessage message) {
        return message instanceof LogLevelMessage;
    }
}
<div><pre></pre><p>You must deploy this class in the server directory and enter it in the Tomcat server.xml file as a ClusterListener within the <code>&lt;Cluster&gt;</code> element: </p><pre><code>
&lt;ClusterListener className="dynamiclogging.tomcat.ClusterLoggingListener"/&gt;
</code></pre><p>You should now be able to set the logging level for any application, over all nodes, in the cluster by calling SetLog4JLevelServlet on any node in the cluster. </p><p></p><h4>Deploying the Example Code</h4>To deploy <a href="http://assets.devx.com/sourcecode/16944.zip"><font color="#002c99">the example code</font></a> for setting the logging level in your cluster, take the following steps: <ol><li>Load the Eclipse project and build it using the dist target. This will create set-log-levels.war and set-log-levels-server.jar in the dist directory. </li><li>Put the set-log-levels-server.jar in the Tomcat server\lib directory and deploy the set-log-levels.war file across the cluster. </li><li>Use the SetLog4jLevelServlet (e.g., <code>/setLogLevel?level=debug</code>) to set the logging level and use PerformLogTestServlet (<code>/testLogLevel</code>) to test the logging level changes. </li></ol><p></p></div></code></pre></div></div></div></div><img src ="http://www.blogjava.net/RR00/aggbug/69693.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-14 17:03 <a href="http://www.blogjava.net/RR00/articles/69693.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j in tomcat</title><link>http://www.blogjava.net/RR00/articles/69638.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 14 Sep 2006 06:41:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/69638.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/69638.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/69638.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/69638.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/69638.html</trackback:ping><description><![CDATA[
		<p>log4j.xml 可以放在2个地方：<br />1〉使用<strong>springframework</strong>在web.xml中配置<br /><font color="#000000">//设置<font color="#ff1493">webAppRootKey</font>的别名，<br />//如果不设置，在log4j.xml中设置为&lt;param name="File" value="<font color="#0000ff">${webapp.root}/</font>WEB-INF/log/frame.log " /&gt;<br />//否则，可以设置为&lt;param name="File" value="<font color="#0000ff">${demo.root}/</font>WEB-INF/log/frame.log " /&gt;<br />//如果不使用<font color="#0000ff">${webapp.root</font>}，就会指向${TOMCAT_HOM},也就是tomcat的安装目录<font color="#ff0000">。</font><br /></font><font color="#a52a2a"> &lt;context-param&gt;<br />  &lt;param-name&gt;<font color="#0000ff">webAppRootKey</font>&lt;/param-name&gt;<br />  &lt;param-value&gt;<font color="#0000ff">demo.root</font>&lt;/param-value&gt;<br /> &lt;/context-param&gt;</font></p>
		<p>
				<font color="#a52a2a">
						<font color="#000000">//设置配置文件</font>   <br />&lt;context-param&gt;<br />        &lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;<br />        &lt;param-value&gt;/WEB-INF/log4j.xml&lt;/param-value&gt;<br />    &lt;/context-param&gt;<br /><br /><font color="#000000">//设置监听器<br /></font>  &lt;listener&gt;<br />  &lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt;<br /> &lt;/listener&gt;<br /></font>这样log4j.xml 就可以WEB-INF里面的任何路径。<br /><br /><strong>Source:<br /></strong><br /><strong>initLogging-&gt;<br />{<br />      WebUtils.setWebAppRootSystemProperty(servletContext);<br /></strong>      {<br />      <strong>String root = servletContext.getRealPath("/");<br />      String param = servletContext.getInitParameter(WEB_APP_ROOT_KEY_PARAM);<br />       String key = (param != null ? param : DEFAULT_WEB_APP_ROOT_KEY);<br />        System.setProperty(key, root);<br />    <font color="#ff0000">  //use system property to deal with </font></strong><font color="#ff0000"><font color="#0000ff">${webapp.root}</font> or its alias.<br />      //once I writed careless <font color="#0000ff">${webapp.root}</font> to <font color="#0000ff">{webapp.root}</font> ,and look up the error for much time.<br /></font><strong>          }<br />      String location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);<br />      Log4jConfigurer.initLogging(location);<br />      {<br /><br />      <font color="#ff0000">   //distinguish the log4j.xml and log4j.properties</font><br />       <font color="#a52a2a">  if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {<br />            DOMConfigurator.configure(url);<br />        }<br />     else {<br />         PropertyConfigurator.configure(url);<br />     }<br />      }<br /></font>}<br />use <font color="#ff0000">DOMConfigurator.configure("log4j.xml"); </font><font color="#000000">to init config ,then LogFactory can work. the "log4j.xml "<br />may be any name .<font color="#ff0000">DOMConfigurator </font>may use cache mechanism as in LogFactory class .cache machanism is<br />another way to implement "single" design pattern.<br /></font></strong><font color="#008000">------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<br /></font>2〉WEB-INF/classes下面 <br /><br />采取这种方式，它的文件appender的相对路径总是指向${TOMCAT_HOM},也就是tomcat的安装目录<font color="#ff0000">。&lt;param name="File" value="demo.log" /&gt; <font color="#000000">会把</font></font><font color="#ff0000">demo.log <font color="#000000">保存到</font></font><font color="#ff0000">${TOMCAT_HOM}/demo.log</font><font color="#ff0000"> ，<br /></font>采用绝对路径则可以任意设置。<br /><br />为了使用相对路径，我们把project放到${TOMCAT_HOMe}/webapps下deploy。<br />如project名为demo，log要保存在demo/log/demo.log文件里，则可以设为：<br /><font color="#ff0000">&lt;param name="File" value="webapps\\demo\\log\\framefile.log" /&gt;<br /><br />---------------------------------------------------------------------------------------------------------------------------<br />---------------------------------------------------------------------------------------------------------------------------<br />---------------------------------------------------------------------------------------------------------------------------<br /></font><font color="#000000">注意<font color="#a52a2a">“\"</font> 要用转义字符<font color="#a52a2a">"\\",</font>如果没加,tomcat启动屏中的路径会变为乱码.<br /><br />tomcat中似乎采取了某种安全策略</font><font color="#000000">,&lt;param name="Append" value="false" /&gt;不起作用。<br /><br />服务器重起后就会新建一个log文件.<br /></font></p>
<img src ="http://www.blogjava.net/RR00/aggbug/69638.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-14 14:41 <a href="http://www.blogjava.net/RR00/articles/69638.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j.properties</title><link>http://www.blogjava.net/RR00/articles/9845.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 11 Aug 2005 14:30:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/9845.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/9845.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/9845.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/9845.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/9845.html</trackback:ping><description><![CDATA[<P><FONT style="BACKGROUND-COLOR: #ffc0cb"><A class=singleposttitle id=viewpost1_TitleUrl HREF="/rr00/articles/9844.html"><FONT color=#223355><FONT style="BACKGROUND-COLOR: #a9a9a9" color=#ff0000>Log4j-----how to use in commons-logging-1.0.4.jar</FONT> </FONT></A><BR><BR>Logger - 日志写出器，供程序员输出日志信息 </FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffc0cb">Appender - 日志目的地，把格式化好的日志信息输出到指定的地方去 <BR>ConsoleAppender - 目的地为控制台的Appender <BR>FileAppender - 目的地为文件的Appender <BR>RollingFileAppender - 目的地为大小受限的文件的Appender </FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffc0cb">Layout - 日志格式化器，用来把程序员的logging request格式化成字符串 <BR>PatternLayout - 用指定的pattern格式化logging request的Layout</FONT> <BR><BR>### direct log messages to stdout ###<BR>log4j.appender.stdout=org.apache.log4j.ConsoleAppender<BR>log4j.appender.stdout.Target=System.out<BR>log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<BR>log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n</P>
<P>### direct messages to file hibernate.log ###<BR>#log4j.appender.file=org.apache.log4j.FileAppender<BR>#log4j.appender.file.File=hibernate.log<BR>#log4j.appender.file.layout=org.apache.log4j.PatternLayout<BR>#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n</P>
<P>### set log levels - for more verbose logging change 'info' to 'debug' ###</P>
<P>log4j.rootLogger=warn, stdout&nbsp;&nbsp;&nbsp; #所有配置继承此配置(在此基础增加),可不要<BR>#可定义自己的级别:<BR><FONT color=#ff0000>log4j.logger.test=info<BR></FONT>#<FONT color=#ff0000>log4j.logger</FONT><FONT color=#000000>必需;其后可加package name or class name;<BR><BR></FONT><FONT style="BACKGROUND-COLOR: #ffc0cb">使用:<BR>package test;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffc0cb">import org.apache.commons.logging.Log;<BR>import org.apache.commons.logging.LogFactory;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffc0cb">/**<BR>&nbsp;* @author herald<BR>&nbsp;* <BR>&nbsp;* TODO 要更改此生成的类型注释的模板，请转至 窗口 － 首选项 － Java － 代码样式 － 代码模板<BR>&nbsp;*/<BR>public class Test {</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffc0cb">&nbsp;public static void main(String[] args) {<BR>&nbsp;&nbsp;Log log = LogFactory.getLog("test");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT style="BACKGROUND-COLOR: #ffff00">其如果存在"test",不重新建立log&nbsp;&nbsp;<BR></FONT>&nbsp;&nbsp;log.info("aa");<BR>&nbsp;&nbsp;log.error("bbbbbb");<BR>&nbsp;}<BR>}<BR></FONT><BR><FONT style="BACKGROUND-COLOR: #deb887"><BR>源码:<BR>CategoryKey key = new CategoryKey(name);<BR>&nbsp;&nbsp;// Synchronize to prevent write conflicts. Read conflicts (in<BR>&nbsp;&nbsp;// getChainedLevel method) are possible only if variable<BR>&nbsp;&nbsp;// assignments are non-atomic.<BR>&nbsp;&nbsp;Logger logger;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #deb887">&nbsp;&nbsp;synchronized (ht) {<BR>&nbsp;&nbsp;&nbsp;Object o = ht.get(key);<BR>&nbsp;&nbsp;&nbsp;if (o == null) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;logger = factory.makeNewLoggerInstance(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;logger.setHierarchy(this);<BR>&nbsp;&nbsp;&nbsp;&nbsp;ht.put(key, logger);<BR>&nbsp;&nbsp;&nbsp;&nbsp;updateParents(logger);<BR>&nbsp;&nbsp;&nbsp;&nbsp;return logger;<BR>&nbsp;&nbsp;&nbsp;} else if (o instanceof Logger) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;return (Logger) o;<BR>&nbsp;&nbsp;&nbsp;} else if (o instanceof ProvisionNode) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;//System.out.println("("+name+") ht.get(this) returned<BR>&nbsp;&nbsp;&nbsp;&nbsp;// ProvisionNode");<BR>&nbsp;&nbsp;&nbsp;&nbsp;logger = factory.makeNewLoggerInstance(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;logger.setHierarchy(this);<BR>&nbsp;&nbsp;&nbsp;&nbsp;ht.put(key, logger);<BR>&nbsp;&nbsp;&nbsp;&nbsp;updateChildren((ProvisionNode) o, logger);<BR>&nbsp;&nbsp;&nbsp;&nbsp;updateParents(logger);<BR>&nbsp;&nbsp;&nbsp;&nbsp;return logger;<BR>&nbsp;&nbsp;&nbsp;} else {<BR>&nbsp;&nbsp;&nbsp;&nbsp;// It should be impossible to arrive here<BR>&nbsp;&nbsp;&nbsp;&nbsp;return null; // but let's keep the compiler happy.<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR></FONT></P><img src ="http://www.blogjava.net/RR00/aggbug/9845.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2005-08-11 22:30 <a href="http://www.blogjava.net/RR00/articles/9845.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Log4j-----how to use in commons-logging-1.0.4.jar </title><link>http://www.blogjava.net/RR00/articles/9844.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 11 Aug 2005 14:22:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/9844.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/9844.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/9844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/9844.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/9844.html</trackback:ping><description><![CDATA[<P><BR><STRONG>commons-logging-1.0.4.jar 使用</STRONG></P>
<H3><FONT style="BACKGROUND-COLOR: #f5f5dc">Configuring the Commons Logging Package</FONT></H3>
<H4><FONT style="BACKGROUND-COLOR: #f5f5dc">Choosing a <CODE>LogFactory</CODE> Implementation</FONT></H4>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">From an application perspective, the first requirement is to retrieve an object reference to the <CODE>LogFactory</CODE> instance that will be used to create <CODE><A href="file:///G:/tools/j2ee/hibernate-3.0/lib/commons-logging-1.0.4/org/apache/commons/logging/Log.html">Log</A></CODE> instances for this application. This is normally accomplished by calling the static <CODE>getFactory()</CODE> method. This method implements the following discovery algorithm to select the name of the <CODE>LogFactory</CODE> implementation class this application wants to use:</FONT></P>
<UL>
<LI><FONT style="BACKGROUND-COLOR: #f5f5dc">Check for a system property named <CODE>org.apache.commons.logging.LogFactory</CODE>. </FONT>
<LI><FONT style="BACKGROUND-COLOR: #f5f5dc">Use the JDK 1.3 JAR Services Discovery mechanism (see </FONT><A href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc"> for more information) to look for a resource named <CODE>META-INF/services/org.apache.commons.logging.LogFactory</CODE> whose first line is assumed to contain the desired class name. </FONT>
<LI><FONT style="BACKGROUND-COLOR: #f5f5dc">Look for a properties file named <CODE>commons-logging.properties</CODE> visible in the application class path, with a property named <CODE>org.apache.commons.logging.LogFactory</CODE> defining the desired implementation class name. </FONT>
<LI><FONT style="BACKGROUND-COLOR: #f5f5dc">Fall back to a default implementation, which is described further below. </FONT></LI></UL>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">If a <CODE>commons-logging.properties</CODE> file is found, all of the properties defined there are also used to set configuration attributes on the instantiated <CODE>LogFactory</CODE> instance.<BR><FONT style="BACKGROUND-COLOR: #ffffff"><BR>使用必须:<BR></FONT><STRONG>commons-logging-1.0.4.jar</STRONG><BR><STRONG>log4j-1.2.9.jar<BR><A href="http://www.blogjava.net/rr00/articles/9845.html">log4j.properties</A></STRONG><BR></FONT></P><img src ="http://www.blogjava.net/RR00/aggbug/9844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2005-08-11 22:22 <a href="http://www.blogjava.net/RR00/articles/9844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Log4J 使用说明</title><link>http://www.blogjava.net/RR00/articles/9827.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 11 Aug 2005 08:13:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/9827.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/9827.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/9827.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/9827.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/9827.html</trackback:ping><description><![CDATA[<TABLE class=chapter-bg cellSpacing=1 align=center>
<TBODY>
<TR class=chapter>
<TD noWrap><B>Logger：日志写出器</B></TD></TR>
<TR class=main>
<TD>
<P><TT>Logger</TT>对象是用来取代<TT>System.out</TT>或者<TT>System.err</TT>的日志写出器，用来供程序员输出日志信息。</P>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>Logger的输出方法</B></TD></TR>
<TR class=main>
<TD>
<P>Logger类对象提供一系列方法供程序员输出日志信息。</P>
<P><TT><PRE>        
<B>
        ------ Log4j APIs : class Logger ------
        </B>
        
        <FONT color=green>
        // Printing methods :
        </FONT>
        public void debug(Object msg);
        public void debug(Object msg, Throwable t);
        
        public void info(Object msg);
        public void info(Object msg, Throwable t);
        
        public void warn(Object msg);
        public void warn(Object msg, Throwable t);
        
        public void error(Object msg);
        public void error(Object msg, Throwable t);
        
        public void fatal(Object msg);
        public void fatal(Object msg, Throwable t);
        <FONT color=green>
        // Generic printing method :
        </FONT>
        public void log(Level l, Object msg);
      </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>Logger的命名规则</B></TD></TR>
<TR class=main>
<TD>
<P>Logger由一个String类的名字识别，logger的名字是大小写敏感的，且名字之间具有继承的关系，子名有父名作为前缀，用点号<B>.</B>分隔。如：<TT>x.y</TT>是<TT>x.y.z</TT>的父亲。</P>
<P>根logger (<TT>root logger</TT>)是所有logger的祖先，它具有如下属性：<B>1)</B> 它总是存在的；<B>2)</B> 它不可以通过名字获得。</P>
<P>通过调用<TT>public static Logger Logger.getRootLogger()</TT>获得<TT>root logger</TT>；通过调用<TT>public static Logger Logger.getLogger(String name)</TT>或者<TT>public static Logger Logger.getLogger(Class clazz)</TT>获得（或者创建）一个<TT>named logger</TT>。后者相当于调用<TT>Logger.getLogger(clazz.getName())</TT>。</P>
<P>在某对象中，用该对象所属的类为参数，调用<TT>Logger.getLogger(Class clazz)</TT>以获得logger被认为是目前所知的最理智的命名logger的方法。</P></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>Log level</B></TD></TR>
<TR class=main>
<TD>
<P>每个logger都被分配了一个日志级别 (<TT>log level</TT>)，用来控制日志信息的输出。未被分配level的logger将继承它最近的父logger的level。</P>
<P>每条输出到logger的日志请求(<TT>logging request</TT>)也都有一个level，如果该request的level大于等于该logger的level，则该request将被处理（称为enabled）；否则该request将被忽略。故可得知： 
<OL>
<LI>logger的level越低，表示该logger越详细 
<LI>logging request的level越高，表示该logging request越优先输出 </LI></OL>
<P></P>
<P><TT>Level</TT>类中预定义了五个level，它们的大小关系如下：</P>
<P><TT><PRE>        Level.ALL &lt; Level.DEBUG &lt; Level.INFO &lt; Level.WARN &lt; Level.ERROR &lt; Level.FATAL &lt; Level.OFF
      </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>示例代码</B></TD></TR>
<TR class=main>
<TD>
<P>以下代码将用自己所属的类为参数，创建一个logger，启用默认配置，设置其level并向其输出若干logging request。</P>
<P><TT><PRE>import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;

public class Log4jTest {
    public static void main(String argv[]) {
    
        <FONT color=green>
        // Create a logger by the name of class Log4jTest.
        </FONT>
        Logger logger = Logger.getLogger(Log4jTest.class);
        <FONT color=green>
        // Use the default configuration.
        </FONT>
        BasicConfigurator.configure();
        <FONT color=green>
        // Set the logger level to Level.INFO
        </FONT>
        logger.setLevel(Level.INFO);
        <FONT color=green>
        // This request will be disabled since Level.DEBUG &lt; Level.INFO.
        </FONT>          
        logger.debug("This is debug.");
        <FONT color=green>
        // These requests will be enabled.
        </FONT>          
        logger.info("This is an info.");
        logger.warn("This is a warning.");
        logger.error("This is an error.");
        logger.fatal("This is a fatal error.");
        
        return;
    }
}
      </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>关于logger的两点说明</B></TD></TR>
<TR class=main>
<TD>
<P>
<OL>
<LI>用同名参数调用<TT>Logger.getLogger(String name)</TT>将返回同一个logger的引用。故可以在一个地方配置logger，在另外一个地方获得配置好的logger，而无须相互间传递logger的引用。 
<LI>logger的创建可以按照任意的顺序，即，父logger可以后于子logger被创建。log4j将自动维护logger的继承树。 </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE><BR>
<TABLE class=chapter-bg cellSpacing=1 align=center>
<TBODY>
<TR class=chapter>
<TD noWrap><B>Appender：日志目的地</B></TD></TR>
<TR class=main>
<TD>
<P>每个logger都可以拥有一个或者多个appender，每个appender表示一个日志的输出目的地，比如console或者某个文件。可以使用<TT>Logger.addAppender(Appender app)</TT>为logger增加一个appender；可以使用<TT>Logger.removeAppender(Appender app)</TT>为logger移除一个appender。</P>
<P>默认情况下，logger的additive标志被设置为true，表示子logger将继承父logger的所有appenders。该选项可以被重新设置，表示子logger将不再继承父logger的appenders。</P>
<P><TT>root logger</TT>拥有目标为<TT>system.out</TT>的<TT>consoleAppender</TT>，故默认情况下，所有的logger都将继承该appender。</P>
<P><TT><PRE>      
<B>
      ------ Log4j APIs : class Logger ------
      </B>
      
      <FONT color=green>
      // 为logger对象增加或者移除一个Appender对象 :.
      </FONT>
      public void appAppender(Appender app);
      public void removeAppender(Appender app);
      <FONT color=green>
      // 获得和设置additive标志：是否继承父logger的appenders :.
      // <B>注意：</B>在设置additive标志为false时，必须保证已经为该logger设置了新的appender， :.
      // 否则log4j将报错：log4j:WARN No appenders could be found for logger (x.y.z). :.
      </FONT>
      public boolean getAdditivity();
      public void setAdditivity(boolean additive);
    </PRE></TT>
<P></P>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>ConsoleAppender</B></TD></TR>
<TR class=main>
<TD>
<P>可以使用<TT>ConsoleAppender</TT>对象把日志输出到控制台。每个<TT>ConsoleAppender</TT>都有一个<TT>target</TT>，表示它的输出目的地。它可以是<TT>System.out</TT>，标准输出设备（缓冲显示屏）；或者是<TT>System.err</TT>，标准错误设备（不缓冲显示屏）。<TT>ConsoleAppender</TT>的使用方法参考如下API :.</P>
<P><TT><PRE>        
<B>
        ------ Log4j APIs : class ConsoleAppender extends WriterAppender ------
        </B>
      
        <FONT color=green>
        // 构造方法，使用一个Layout对象构造一个ConsoleAppender对象 :.
        // 默认情况下，ConsoleAppender的target是System.out :.
        </FONT>
        public ConsoleAppender(Layout layout);
        <FONT color=green>
        // 构造方法，使用一个Layout对象和一个target字符串构造ConsoleAppender对象 :.
        // target的可能取值为ConsoleAppender.SYSTEM_OUT和ConsoleAppender.SYSTEM_ERR :.
        </FONT>
        public ConsoleAppender(Layout layout, String target);
      </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>FileAppender</B></TD></TR>
<TR class=main>
<TD>
<P>可以使用<TT>FileAppender</TT>对象把日志输出到一个指定的日志文件中去。使用方法可以参考如下的API :.</P>
<P><TT><PRE>        
<B>
        ------ Log4j APIs : class FileAppender extends WriterAppender ------
        </B>
      
        <FONT color=green>
        // 构造方法，使用一个Layout对象和日志文件名构造一个FileAppender对象 :.
        </FONT>
        public FileAppender(Layout layout, String filename)
            throws IOException;
        public FileAppender(Layout layout, String filename, boolean append)
            throws IOException;
      </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>RollingFileAppender</B></TD></TR>
<TR class=main>
<TD>
<P>可以使用<TT>FileAppender</TT>的子类<TT>RollingFileAppender</TT>对象，把日志输出到一个指定的日志文件中。不同的是该日志文件的大小受到限制，当日志内容超出最大的尺寸时，该文件将向上滚动（最老的日志被擦除）。还可以在该类对象中指定为日志文件做多少个备份。具体使用方法参考如下API :.</P>
<P><TT><PRE>        
<B>
        ------ Log4j APIs : class RollingFileAppender extends FileAppender ------
        </B>
      
        <FONT color=green>
        // 构造方法，使用一个Layout对象和日志文件名构造一个RollingFileAppender对象 :.
        </FONT>
        public RollingFileAppender(Layout layout, String filename)
            throws IOException;
        public RollingFileAppender(Layout layout, String filename, boolean append)
            throws IOException;
        <FONT color=green>
        // 获得和设置日志备份文件的个数 :.
        </FONT>
        public int getMaxBackupIndex();
        public void setMaxBackupIndex(int index);
        <FONT color=green>
        // 获得和设置滚动日志文件的最大尺寸 :.
        </FONT>
        public long getMaximumFileSize();
        public void setMaximumFileSize(long size);
      </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE><BR>
<TABLE class=chapter-bg cellSpacing=1 align=center>
<TBODY>
<TR class=chapter>
<TD noWrap><B>Layout：日志格式化器</B></TD></TR>
<TR class=main>
<TD>
<P>每个appender都和一个layout相联系；layout的任务是格式化用户的logging request，appender的任务是把layout格式化好的输出内容送往指定的目的地。</P>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>PatternLayout</B></TD></TR>
<TR class=main>
<TD>
<P><TT>PatternLayout</TT>是Layout的一个子类，用来使用类似C语言的<TT>printf</TT>函数中使用的格式控制字符串来控制日志的输出格式。使用方法参考如下API :.</P>
<P><TT><PRE>        
<B>
        ------ Log4j APIs : class PatternLayout extends Layout ------
        </B>
      
        <FONT color=green>
        // 无参数构造方法，使用DEFAULT_CONVERSION_PATTERN构造一个PatternLayout :.
        // <B>注意：</B>DEFAULT_CONVERSION_PATTERN为"%m%n"，只打印消息信息 :.
        </FONT>
        public PatternLayout();
        <FONT color=green>
        // 构造方法，使用自定义的pattern构造一个PatternLayout :.
        </FONT>
        public PatternLayout(String pattern);
        <FONT color=green>
        // 获得和设置PatternLayout对象的日志pattern :.
        </FONT>
        public String getConversionPattern();
        public void setConversionPattern(String pattern);
      </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>patterns in PatternLayout</B></TD></TR>
<TR class=main>
<TD>
<P><FONT color=#ff0000>未完待续</FONT> </P></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE><BR>
<TABLE class=chapter-bg cellSpacing=1 align=center>
<TBODY>
<TR class=chapter>
<TD noWrap><B>Configuration：配置</B></TD></TR>
<TR class=main>
<TD>
<P>对log4j环境的配置就是对root logger的配置，包括把root logger设置为哪个级别(level)；为它增加哪些appender，等等。这些可以通过设置系统属性的方法来隐式地完成，也可以在程序里调用<TT>XXXConfigurator.configure()</TT>方法来显式地完成。</P>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>默认的log4j初始化过程</B></TD></TR>
<TR class=main>
<TD>
<P><TT>Logger</TT>类的静态初始化块(<TT>static initialization block</TT>)中对log4j的环境做默认的初始化。<B>注意：</B>如果程序员已经通过设置系统属性的方法来配置了log4j环境，则不需要再显式地调用<TT>XXXConfigurator.configure()</TT>方法来配置log4j环境了。</P>
<P>Logger的静态初始化块在完成初始化过程时将检查一系列log4j定义的系统属性。它所做的事情如下： 
<OL>
<LI>检查系统属性<TT>log4j.defaultInitOverride</TT>，如果该属性被设置为false，则执行初始化；否则（只要不是false，无论是什么值，甚至没有值，都是否则），跳过初始化。 
<LI>把系统属性<TT>log4j.configuration</TT>的值赋给变量resource。如果该系统变量没有被定义，则把resource赋值为<TT>"log4j.properties"</TT>。<B>注意：</B>在apache的log4j文档中建议使用定义<TT>log4j.configuration</TT>系统属性的方法来设置默认的初始化文件是一个好方法。 
<LI>试图把resource变量转化成为一个<TT>URL</TT>对象<TT>url</TT>。如果一般的转化方法行不通，就调用<TT>org.apache.log4j.helpers.Loader.getResource(resource, Logger.class)</TT>方法来完成转化。 
<LI>如果<TT>url</TT>以".html"结尾，则调用方法<TT>DOMConfigurator.configure(url)</TT>来完成初始化；否则，则调用方法<TT>PropertyConfigurator.configure(url)</TT>来完成初始化。如果<TT>url</TT>指定的资源不能被获得，则跳出初始化过程。 </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>BasicConfigurator.configure()</B></TD></TR>
<TR class=main>
<TD>
<P><TT>BasicConfigurator.configure()</TT>方法使用最简的方法配置log4j环境。<B>注：</B>所谓配置log4j环境，就是指配置root logger，因为所有其它的logger都是root logger的后代，所以它们（默认情况下）都将继承root logger的性质。</P>
<P><TT>BasicConfigurator.configure()</TT>完成的任务是： 
<OL>
<LI>用默认pattern创建PatternLayout对象p：<BR>PatternLayout p = new PatternLayout("%-4r[%t]%-5p%c%x - %m%n"); 
<LI>用p创建ConsoleAppender对象a，目标是system.out，标准输出设备：<BR>ConsoleAppender a = new ConsoleAppender(p,ConsoleAppender.SYSTEM_OUT); 
<LI>为root logger增加一个ConsoleAppender p：<BR>rootLogger.addAppender(p); 
<LI>把root logger的log level设置为DEBUG级别：<BR>rootLogger.setLevel(Level.DEBUG); </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>xml格式的log4j配置文件概述</B></TD></TR>
<TR class=main>
<TD>
<P>xml格式的log4j配置文件需要使用<TT>org.apache.log4j.html.DOMConfigurator.configure()</TT>方法来读入。对xml文件的语法定义可以在log4j的发布包中找到：<TT>org/apache/log4j/xml/log4j.dtd</TT>。</P>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>log4j的xml配置文件的树状结构</B></TD></TR>
<TR class=main>
<TD>
<P>log4j的xml配置文件的树状结构如下所示，注意下图只显示了常用的部分。 :.</P>
<P><TT><PRE>          xml declaration and dtd
            |
          log4j:configuration
            |
            +-- appender (name, class)
            |     |
            |     +-- param (name, value)
            |     +-- layout (class)
            |           |
            |           +-- param (name, value)
            +-- logger (name, additivity)
            |     |
            |     +-- level (class, value)
            |     |     |
            |     |     +-- param (name, value)
            |     +-- appender-ref (ref)
            +-- root
                  |
                  +-- param (name, class)
                  +-- level
                  |     |
                  |     +-- param (name, value)
                  +-- appender-ref (ref)  
        </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>xml declaration and dtd</B></TD></TR>
<TR class=main>
<TD>
<P>xml配置文件的头部包括两个部分：xml声明和dtd声明。头部的格式如下： :.</P>
<P><TT><PRE>          &lt;?xml version="1.0" encoding="UTF-8" ?&gt;
          &lt;!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"&gt;
        </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>log4j:configuration (root element)</B></TD></TR>
<TR class=main>
<TD>
<P>
<OL>
<LI><TT><B>xmlns:log4j</B> [#FIXED attribute]</TT> : 定义log4j的名字空间，取定值<TT>"http://jakarta.apache.org/log4j/"</TT> 
<LI><TT><B>appender</B> [* child]</TT> : 一个appender子元素定义一个日志输出目的地 
<LI><TT><B>logger</B> [* child]</TT> : 一个logger子元素定义一个日志写出器 
<LI><TT><B>root</B> [? child]</TT> : root子元素定义了root logger </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>appender</B></TD></TR>
<TR class=main>
<TD>
<P>appender元素定义一个日志输出目的地。</P>
<P>
<OL>
<LI><TT><B>name</B> [#REQUIRED attribute]</TT> : 定义appender的名字，以便被后文引用 
<LI><TT><B>class</B> [#REQUIRED attribute]</TT> : 定义appender对象所属的类的全名 
<LI><TT><B>param</B> [* child]</TT> : 创建appender对象时传递给类构造方法的参数 
<LI><TT><B>layout</B> [? child]</TT> : 该appender使用的layout对象 </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>layout</B></TD></TR>
<TR class=main>
<TD>
<P>layout元素定义与某一个appender相联系的日志格式化器。</P>
<P>
<OL>
<LI><TT><B>class</B> [#REQUIRED attribute]</TT> : 定义layout对象所属的类的全名 
<LI><TT><B>param</B> [* child]</TT> : 创建layout对象时传递给类构造方法的参数 </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>logger</B></TD></TR>
<TR class=main>
<TD>
<P>logger元素定义一个日志输出器。</P>
<P>
<OL>
<LI><TT><B>name</B> [#REQUIRED attribute]</TT> : 定义logger的名字，以便被后文引用 
<LI><TT><B>additivity</B> [#ENUM attribute]</TT> : 取值为"true"（默认）或者"false"，是否继承父logger的属性 
<LI><TT><B>level</B> [? child]</TT> : 定义该logger的日志级别 
<LI><TT><B>appender-ref</B> [* child]</TT> : 定义该logger的输出目的地 </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>root</B></TD></TR>
<TR class=main>
<TD>
<P>root元素定义根日志输出器root logger。</P>
<P>
<OL>
<LI><TT><B>param</B> [* child]</TT> : 创建root logger对象时传递给类构造方法的参数 
<LI><TT><B>level</B> [? child]</TT> : 定义root logger的日志级别 
<LI><TT><B>appender-ref</B> [* child]</TT> : 定义root logger的输出目的地 </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>level</B></TD></TR>
<TR class=main>
<TD>
<P>level元素定义logger对象的日志级别。</P>
<P>
<OL>
<LI><TT><B>class</B> [#IMPLIED attribute]</TT> : 定义level对象所属的类，默认情况下是"org.apache.log4j.Level类 
<LI><TT><B>value</B> [#REQUIRED attribute]</TT> : 为level对象赋值。可能的取值从小到大依次为"all"、"debug"、"info"、"warn"、"error"、"fatal"和"off"。当值为"off"时表示没有任何日志信息被输出 
<LI><TT><B>param</B> [* child]</TT> : 创建level对象时传递给类构造方法的参数 </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>appender-ref</B></TD></TR>
<TR class=main>
<TD>
<P>appender-ref元素引用一个appender元素的名字，为logger对象增加一个appender。</P>
<P>
<OL>
<LI><TT><B>ref</B> [#REQUIRED attribute]</TT> : 一个appender元素的名字的引用 
<LI>appender-ref元素没有子元素 </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>param</B></TD></TR>
<TR class=main>
<TD>
<P>param元素在创建对象时为类的构造方法提供参数。它可以成为<TT>appender</TT>、<TT>layout</TT>、<TT>filter</TT>、<TT>errorHandler</TT>、<TT>level</TT>、<TT>categoryFactory</TT>和<TT>root</TT>等元素的子元素。</P>
<P>
<OL>
<LI><TT><B>name</B> and <B>value</B> [#REQUIRED attributes]</TT> : 提供参数的一组名值对 
<LI>param元素没有子元素 </LI></OL>
<P></P></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>在xml文件中配置appender和layout</B></TD></TR>
<TR class=main>
<TD>
<P>创建不同的Appender对象或者不同的Layout对象要调用不同的构造方法。可以使用param子元素来设定不同的参数值。</P>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>创建ConsoleAppender对象</B></TD></TR>
<TR class=main>
<TD>
<P>ConsoleAppender的构造方法不接受其它的参数。 :.</P>
<P><TT><PRE>          ... ... ... ...
          &lt;appender name="console.log" class="org.apache.log4j.ConsoleAppender"&gt;
            &lt;layout ... &gt;
              ... ...
            &lt;/layout&gt;
          &lt;/appender&gt;
          ... ... ... ...
        </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>创建FileAppender对象</B></TD></TR>
<TR class=main>
<TD>
<P>可以为FileAppender类的构造方法传递两个参数：<TT>File</TT>表示日志文件名；<TT>Append</TT>表示如文件已存在，是否把日志追加到文件尾部，可能取值为"true"和"false"（默认）。 :.</P>
<P><TT><PRE>          ... ... ... ...
          &lt;appender name="file.log" class="org.apache.log4j.FileAppender"&gt;
            &lt;param name="File" value="/tmp/log.txt" /&gt;
            &lt;param name="Append" value="false" /&gt;
            &lt;layout ... &gt;
              ... ...
            &lt;/layout&gt;
          &lt;/appender&gt;
          ... ... ... ...
        </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>创建RollingFileAppender对象</B></TD></TR>
<TR class=main>
<TD>
<P>除了<TT>File</TT>和<TT>Append</TT>以外，还可以为RollingFileAppender类的构造方法传递两个参数：<TT>MaxBackupIndex</TT>备份日志文件的个数（默认是1个）；<TT>MaxFileSize</TT>表示日志文件允许的最大字节数（默认是10M）。 :.</P>
<P><TT><PRE>          ... ... ... ...
          &lt;appender name="rollingFile.log" class="org.apache.log4j.RollingFileAppender"&gt;
            &lt;param name="File" value="/tmp/rollingLog.txt" /&gt;
            &lt;param name="Append" value="false" /&gt;
            &lt;param name="MaxBackupIndex" value="2" /&gt;
            &lt;param name="MaxFileSize" value="1024" /&gt;
            &lt;layout ... &gt;
              ... ...
            &lt;/layout&gt;
          &lt;/appender&gt;
          ... ... ... ...
        </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR>
<TABLE class=subsection-bg cellSpacing=1 align=center>
<TBODY>
<TR class=subsection>
<TD noWrap><B>创建PatternLayout对象</B></TD></TR>
<TR class=main>
<TD>
<P>可以为PatternLayout类的构造方法传递参数ConversionPattern。 :.</P>
<P><TT><PRE>          ... ... ... ...
          &lt;layout class="org.apache.log4j.PatternLayout&gt;
            &lt;param name="Conversion" value="%d [%t] %p - %m%n" /&gt;
          &lt;/layout&gt;
          ... ... ... ...
        </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE><BR>
<TABLE class=section-bg cellSpacing=1 align=center>
<TBODY>
<TR class=section>
<TD noWrap><B>我自己的一个使用xml文件配置log4j环境的很简单的例子</B></TD></TR>
<TR class=main>
<TD>
<P>为WSOTA项目开发java web start的胖客户端时，使用了如下的xml文件配置log4j环境（文件名为wsota-rc.log4j.html）：:.</P>
<P><TT><PRE>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"&gt;

&lt;log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"&gt;
  <FONT color=green>
  &lt;!-- ================================================================= --&gt;
  &lt;!--                     a rolling file appender                       --&gt;
  &lt;!-- ================================================================= --&gt;
  </FONT>
  &lt;appender name="wsota-rc.file.log" class="org.apache.log4j.RollingFileAppender"&gt;
    &lt;param name="File" value="/tmp/wsota-rc.log" /&gt;
    &lt;param name="Append" value="false" /&gt;
    &lt;layout class="org.apache.log4j.PatternLayout"&gt;
      &lt;param name="ConversionPattern" value="%d [%t] %p - %m%n" /&gt;
    &lt;/layout&gt;
  &lt;/appender&gt;
  <FONT color=green>
  &lt;!-- ================================================================= --&gt;
  &lt;!--                       a console appender                          --&gt;
  &lt;!--     debug can be turned off by setting level of root to "off"     --&gt;
  &lt;!-- ================================================================= --&gt;
  </FONT>
  &lt;appender name="wsota-rc.console.log" class="org.apache.log4j.ConsoleAppender"&gt;
    &lt;layout class="org.apache.log4j.PatternLayout"&gt;
      &lt;param name="ConversionPattern" value="%d [%t] %p - %m%n" /&gt;
    &lt;/layout&gt;
  &lt;/appender&gt;
  <FONT color=green>
  &lt;!--  use this to turn on debug to a rolling file. --&gt;
  </FONT>
  &lt;root&gt;
    &lt;level value="debug" /&gt;
    &lt;appender-ref ref="wsota-rc.file.log" /&gt;
  &lt;/root&gt;
  <FONT color=green>
  &lt;!--  use this to turn on debug to console. --&gt;
  &lt;!--
  &lt;root&gt;
    &lt;level value="off" /&gt;
    &lt;appender-ref ref="wsota-rc.console.log" /&gt;
  &lt;/root&gt;
  --&gt;
  </FONT>
  <FONT color=green>
  &lt;!--  use this to turn off debug. --&gt;
  &lt;!--
  &lt;root&gt;
    &lt;level value="off" /&gt;
    &lt;appender-ref ref="wsota-rc.console.log" /&gt;
  &lt;/root&gt;
  --&gt;
  </FONT>
&lt;/log4j:configuration&gt;
      </PRE></TT>
<P></P>
<P>在胖客户程序中使用了如下代码来使用外部xml文件配置log4j环境，注意该代码段位于程序的main class的静态初始化块中，含有以下代码的类和xml配置文件在同一个目录下：:.</P>
<P><TT><PRE>  import org.apache.log4j.html.DOMConfigurator;
  
  public class SapFrame extends JFrame {
      static {
          DOMConfigurator.configure(SapFrame.class.getResource("wsota-rc.log4j.html"));
      }
      ... ... ... ...
  }
      </PRE></TT>
<P></P></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE><BR>
<TABLE class=chapter-bg cellSpacing=1 align=center>
<TBODY>
<TR class=chapter>
<TD noWrap><B>Log4j的编码习惯</B></TD></TR>
<TR class=main>
<TD>
<P>
<OL>
<LI>让每个类都拥有一个private static的Logger对象，用来输出该类中的全部日志信息 
<LI>使用xml文件来完成对log4j环境的配置。在项目的main class中的静态初始化块里放log4j环境的配置代码。注意：在一个项目中，log4j环境只需要被配置一次，而不是在每个使用了logger的类里都需要调用一次 
<LI>用<TT>MyClass.class</TT>作为参数创建该类的静态Logger对象 
<LI><FONT color=#ff0000>补充中...</FONT> </LI></OL></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/RR00/aggbug/9827.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2005-08-11 16:13 <a href="http://www.blogjava.net/RR00/articles/9827.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>