本文接下来分析tomcat的日志记录器,日志记录器是用来记录消息的组件,在tomcat中,日志记录器需要与某个servlet容器相关连;在org.apache.catalina.logger包下,tomcat提供了几种不同类型的日志记录器。
tomcat中的日志记录器都必须实现org.apache.catalina.Logger接口
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);
}
通常,当传入的日志级别verbosity大于Logger被设置的级别时,message会被记录,否则被忽略
Logger接口共定义了五种日志级别,分别为FATAL ERROR WARNING INFORMATION DEBUG
Tomcat提供了三种类型的日志记录器,分别为SystemOutLogger、SystemErrLogger、FileLogger,在org.apache.catalina.logger包下,均继承自org.apache.catalina.logger.LoggerBase类
LoggerBase类实现了org.apache.catalina.Logger接口,在tomcat5中还实现了Lifecycle接口
LoggerBase类为抽象类,实现了Logger接口中除abstract void log(String msg)外的全部方法实现,所有的其他重载方法最终都会调用该方法(templet模式),我们还可以调用setVerbosity()方法设置日志级别
具体日志类都比较简单,下面是SystemOutLogger类的实现
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);
}
}
SystemErrLogger类
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);
}
}
FileLogger类稍微复杂一点,将从servlet容器中接收到的消息写入到一个文件中(在tomcat4中,FileLogger类实现了Lifecycle接口)
public
class
FileLogger
extends
LoggerBase
implements
Lifecycle {
protected
LifecycleSupport lifecycle =
new
LifecycleSupport(
this
);
private
StringManager sm =
StringManager.getManager(Constants.Package);
private
boolean
started =
false
;
private
String suffix = ".log"
;
private
boolean
timestamp =
false
;
private
PrintWriter writer =
null
;
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);
}
}
}
private
void
close() {
if
(writer ==
null
)
return
;
writer.flush();
writer.close();
writer
=
null
;
date
= ""
;
}
/**
* 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
;
}
}
public
void
addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
public
LifecycleListener[] findLifecycleListeners() {
return
lifecycle.findLifecycleListeners();
}
public
void
removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
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();
}
}
---------------------------------------------------------------------------
本系列How Tomcat Works系本人原创
转载请注明出处 博客园 刺猬的温驯
本人邮箱: chenying998179 # 163.com ( #改为@ )

