public void start() throws LifecycleException {
// Validate and update our current component state
if (started)
throw new LifecycleException
(sm.getString("fileLogger.alreadyStarted"));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
}
public void stop() throws LifecycleException {
// Validate and update our current component state
if (!started)
throw new LifecycleException
(sm.getString("fileLogger.notStarted"));
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
close();
}
The FileLogger类最重要的方法是the log方法,请看下面的代码:
public void log(String msg) {
// Construct the timestamp we will use, if requested
Timestamp ts = new Timestamp(System.currentTimeMillis());
String tsString = ts.toString().substring(0, 19);
String tsDate = tsString.substring(0, 10);
// If the date has changed, switch log files
if (!date.equals(tsDate)) {
synchronized (this) {
if (!date.equals(tsDate)) {
close();
date = tsDate;
open();
}
}
}
// Log this message, timestamped if necessary
if (writer != null) {
if (timestamp) {
writer.println(tsString + " " + msg);
} else {
writer.println(msg);
}
}
}
The log方法接收到一个消息就把它写到一个日志文件里。在FileLogger实例的生命周期里,the log方法中的可能打开和关闭多个日志文件。如果日期改变,The log方法就会关闭当前的日志文件并且打开了一个新创建的一个日志文件。现在让我们来看看the log方法中的open, close 方法是怎样工作的。
八、The open方法
The open方法请看下面的代码,他主要是在制定的目录下创建一个日志文件。
/**
* Open the new log file for the date specified by <code>date</code>.
*/
private void open() {
// Create the directory if necessary
File dir = new File(directory);
if (!dir.isAbsolute())
dir = new File(System.getProperty("catalina.base"), directory);
dir.mkdirs();
// Open the current log file
try {
String pathname = dir.getAbsolutePath() + File.separator +
prefix + date + suffix;
writer = new PrintWriter(new FileWriter(pathname, true), true);
} catch (IOException e) {
writer = null;
}
}
The open方法开始就核实一下目录(创建日志文件)是否存在。如果目录不存在,该方法也会创建一个目录,然后该目录就会存储到类的成员变量中。
File dir=new File(directory);
if(!dir.isAbsolute())
dir=new File(System.getProperty("catalina.base"),directory);
dir.mkdirs();
然后,the pathname它是由一下部分组成:一个基于打开日志文件的目录, 前缀,当前日期,后缀。
try{
String pathname=dir.getAbsolutePath()+File.separator+
prefix+date+suffix;
接下来,该方法有构造了一个java.io.PrintWriter类实例(该类的构造函数参数是java.io.FileWriter对象(把pathname传给该对象)),The PrintWriter实例赋给了类成员变量writer. The Log方法使用writer写日志消息。
writer=new PrintWriter(new FileWriter(pathname,true),true);
九、The Close方法
The close方法清洗The PrinterWriter对象writer,清洗该对象的内容,关闭the PrinterWriter,设置The PrinterWriter为null,设置日期为空字符串。下面是the close方法代码:
private void close() {
if (writer == null)
return;
writer.flush();
writer.close();
writer = null;
date = "";
}
十、The Log方法
The log方法开始是通过创建一个java.sql.Timestamp类实例(继承了java.util.Date类)。在该方法中实例化The Timestamp类的目的的是能够非常容易的获得当前的时间,并且该方法构造的Timestamp类实例时,是把当前的时间作为参数传给构造函数。
Timestamp ts=new Timestamp(System.currentTimeMills());
使用The Timestamp类用了toString方法变成字符串,那你就能够得到当前日期的字符串形式。toString方法输出字符串格式是:
yyy-mm-dd hh:mm:SS.fffffffff
这个fffffffff代表十亿分之秒。为了仅仅得到时间和小时,该方法有调用了subString方法截取字符串:
String tsString=ts.toString().subString(0,19);
对于tsString字符串为了之得到日期部分那么the Log方法还需要调用subString方法:
String tsDate=tsString.subString(0,10);
The log方法就会用tsDate与String变量的值(初始化的时候只是一个空字符串)进行比较,如果他们不一样的话,那么就会关闭当前文件,把tsDate值赋给date,打开一个新的日志文件。
// If the date has changed, switch log files
if (!date.equals(tsDate)) {
synchronized (this) {
if (!date.equals(tsDate)) {
close();
date = tsDate;
open();
}
}
}