《How Tomcat Works》翻译(5)之 日志
第七章、日志
一、前言部分
A Logger是一个记录消息的组件。在Catalina中的一个logger是与一个Container关联,该组件和其他组件相比是相对比较简单。Tomcat在org.apache.catalina.logger包中提供不同类型重做日志功能。在本章的应用程序将会在ex07.pyrmont包中找到,这两个类( SimpleContext,Bootstrap)发生了改变,其他的代码与第六章的应用程序都是一样。
在本章分为三个部分。第一个部分就是说明org.apache.catalina.Logger接口,该接口一定会被整个loggers实现。第二部分解释在Tomcat中的the Loggers,然后第三部分就十分详细的说明在本应用程序中如何运用Tomcat的Loggers。
二、The Logger接口
一个Logger一定要实现org.apache.catalinna.Logger接口,下面请看代码:
package org.apache.catalina;
import java.beans.PropertyChangeListener;
public interface Logger {
public static final int FATAL = Integer.MIN_VALUE;
public static final int ERROR = 1;
public static final int WARNING = 2;
public static final int INFORMATION = 3;
public static final int DEBUG = 4;
public Container getContainer();
public void setContainer(Container container);
public String getInfo();
public int getVerbosity();
public void setVerbosity(int verbosity);
public void addPropertyChangeListener(PropertyChangeListener listener);
public void log(String message);
public void log(Exception exception, String msg);
public void log(String message, Throwable throwable);
public void log(String message, int verbosity);
public void log(String message, Throwable throwable, int verbosity);
public void removePropertyChangeListener(PropertyChangeListener listener);
}
The Logger接口提供了许多log方法,实现该接口的组件就会调用log方法。这些方法最简单的一个就是接收一个字符串作为消息记录起来。
最后两个log方法主要是接受一个冗长的程度(这里我也不知道是干什么的)。如果传过来的整数要比当前在该组件实例的冗长程度要低,那么该消息就会被记录起来,否则就会该消息就被忽略。五个冗长的程度被定义了(是以公共静态变量):
FATAL,ERROR,WARNING,INFORMATION,DEGUE。the getVerbosity和setVerbosity方法是用了获得和设置这个值。
除此之外,The logger接口也有getContainer和setContainer方法目的就是该组件要与Conatiner相关联起来。该接口也提供了addPropertyChangeListener和removePropertyChangeListener,目的就是添加和移除一个propertyChangeListener.
这些方法当你看到Tomcat中的Logger类你会更加的明白。
三、Tomcat的Loggers
Tomcat提供了三个Loggers分别是(FileLogger,SystemErrLogger,SystemOutLogger).这些类能够在org.apache.catalina.logger包中找到,在Tomcat4中The org.apache.catalina.logger.LoggerBase类实现了Logger接口。而在Tomcat5中LoggerBase也实现了Lifecycle接口(在第六章已经讨论了)和MBeanRegistration(这个将会在第二十章讨论)
下面是其UML类图:
四、The LoggerBase类
在Tomcat5中The LoggerBase类是十分的复杂,因为它把创建MBeans相关的代码也兼容在该类里面,这个我们会在第二十章讨论。因此我们就看看在Tomcat4中的the LoggerBase类。如果你能够理解第二十章内容,那么你也应该能理解在Tomcat5中的the LoggerBase类。
在Tomcat中的LoggerBase类(此类是抽象类)实现了The Logger接口的所有方法除了the log(String msg)方法是抽象方法.
public abstract void log(String msg);
因此就可以在孩子类中实现该方法。注解:典型的模板模式,这个可以借鉴学习。
注意整个其他的log方法都会最终都会调用这个重载的log方法。因为每个孩子的logs 消息有着不同的目的地,因此这个方法在LoggerBase类中是一个抽象方法。
现在让我们看看这个类的冗长(the verbosity)程度。the verbosity程度用成员变量verbosity定义,其默认值是ERROR:
protected int verbosity=ERROR;
The verbosity level可以通过调用setVerbosity方法来改变这个值,主要传的参数是:FATAL, ERROR , WARING , INFOMATION, DEBUG.
下面是在LoggerBase类的setVerbosity方法的代码:
public void setVerbosityLevel(String verbosity) {
if ("FATAL".equalsIgnoreCase(verbosity))
this.verbosity = FATAL;
else if ("ERROR".equalsIgnoreCase(verbosity))
this.verbosity = ERROR;
else if ("WARNING".equalsIgnoreCase(verbosity))
this.verbosity = WARNING;
else if ("INFORMATION".equalsIgnoreCase(verbosity))
this.verbosity = INFORMATION;
else if ("DEBUG".equalsIgnoreCase(verbosity))
this.verbosity = DEBUG;
}
其中有两个log方法接受一个整数作为the Verbosity level。在这些方法中,如果the verbosity程度低于该组件实例的verbosity程度,那么最终都会调用这个要重载的log方法。你可以看看下面的代码:
public void log(String message, int verbosity) {
if (this.verbosity >= verbosity)
log(message);
}
public void log(String message, Throwable throwable, int verbosity) {
if (this.verbosity >= verbosity)
log(message, throwable);
}
LoggerBase类中的三个子类将会在下部分讨论,你将会看到子类是怎样重载the log(message)方法。
五、The SystemOutLogger 类
The LoggerBase类子类实现了the log(message)方法。每接收到消息就会作为参数传到log方法中,然后就在控制台下打印该消息。下面是The SystemOutLogger类的代码:
package org.apache.catalina.logger;
public class SystemOutLogger
extends LoggerBase {
protected static final String info =
"org.apache.catalina.logger.SystemOutLogger/1.0";
public void log(String msg) {
System.out.println(msg);
}
}
六、The SystemErrLogger类
这个类与The SystemOutLogger类十分相似,除了重载the log(String message)方法体不一样,请看下面的代码就一目了然:
package org.apache.catalina.logger;
public class SystemErrLogger
extends LoggerBase {
protected static final String info =
"org.apache.catalina.logger.SystemErrLogger/1.0";
public void log(String msg) {
System.err.println(msg);
}
}
呵呵。。。看到了区别了吧。。。
七、The FileLogger类
The FileLogger类是LoggerBase的子类,该子类是功能最为全面的类。该类一旦接收到与容器关联的消息时它就会把该消息写到一个文件中,并且每条消息都会有任意的时间标记。当第一次实例该类时,这个类就会创建一个文件(文件名字就是创建文件的时间)。如果时间改变了,你将会创建一个新的文件