本文接下来分析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 (#改为@)

本文链接http://www.cnblogs.com/chenying99/p/3237388.html

How Tomcat Works(十)的更多相关文章

  1. How Tomcat Works(十四)补充

    在How Tomcat Works(十四)中,本人并没有对javax.servlet.Filter及javax.servlet.FilterChain做详细的描述,本文在这里做一下补充 FilterC ...

  2. How Tomcat Works(十四)

    我们已经知道,在tomcat中有四种类型的servlet容器,分别为Engine.Host.Context 和Wrapper,本文接下来对tomcat中Wrapper接口的标准实现进行说明. 对于每个 ...

  3. How Tomcat Works(二十)

    要使用一个web应用程序,必须要将表示该应用程序的Context实例部署到一个host实例中.在tomcat中,context实例可以用war文件的形式来部署,也可以将整个web应用拷贝到Tomcat ...

  4. How Tomcat Works(十八)

    在前面的文章中,如果我们要启动tomcat容器,我们需要使用Bootstrap类来实例化连接器.servlet容器.Wrapper实例和其他组件,然后调用各个对象的set方法将它们关联起来:这种配置应 ...

  5. How Tomcat Works(十六)

    本文接下来会介绍Host容器和Engine容器,在tomcat的实际部署中,总是会使用一个Host容器:本文介绍Host接口和Engine接口及其相关类 Host容器是org.apache.catal ...

  6. How Tomcat Works(十五)

    本文接下来分析Context容器,Context容器实例表示一个具体的Web应用程序,其中包括一个或多个Wrapper实例:不过Context容器还需要其他的组件支持,典型的如载入器和Session管 ...

  7. How Tomcat Works(十二)

    tomcat容器通过一个称为Session管理器的组件来管理建立的Session对象,该组件由org.apache.catalina.Manager接口表示:Session管理器必须与一个Contex ...

  8. How Tomcat Works(十九)

    本文重点关注启动tomcat时会用到的两个类,分别为Catalina类和Bootstrap类,它们都位于org.apachae.catalina.startup包下:Catalina类用于启动或关闭S ...

  9. 攻城狮在路上(肆)How tomcat works(零) 前言说明

    最近几篇是关于How tomcat works一书的读书笔记. 通过数个章节逐渐实现一个tomcat的功能. 源码下载地址:http://zhidao.baidu.com/share/7007af0f ...

随机推荐

  1. 850 USB 烧录模式

    /************************************************************************* * 850 USB 烧录模式 * 说明: * 本文 ...

  2. 【J2EE性能分析篇】JVM参数对J2EE性能优化的影响

    一切J2EE应用都是基于JVM的,那么对于JVM的设置和监控,成为J2EE应用程序性能分析和性能优化的必然手段.今天Sincky和大家交流该话题.这里以Tomcat环境为例,其它WEB服务器如Jbos ...

  3. margin collapse 之父子关系的DIV

    打算花点时间将知识整理一下,虽然平时现用现查都能完成工作,可是当遇到面试这种事情的时候,临时查就来不及了... 关于margin,整理若干知识点如下: 一:父子关系的DIV标签以及未加margin时的 ...

  4. 10g中HASH GROUP BY引起的临时表空间不足

    原本在9i上可以顺利完成的CTAS脚本,迁移到10g后运行总是报“ORA-1652: unable to extend temp segment by 128 in tablespace TS_HQY ...

  5. Spring中WebApplicationContext的研究

    Spring中WebApplicationContext的研究 ApplicationContext是Spring的核 心,Context我们通常解释为上下文环境,我想用“容器”来表述它更容易理解一些 ...

  6. Java自动装箱拆箱

    一.装箱.拆箱定义 如果一个int型量被传递到需要一个Integer对象的地方,那么,编译器将在幕后插入一个对Integer构造方法的调用,这就叫做自动装箱.而如果一个Integer对象被放到需要in ...

  7. 【原创】搭建Nginx(负载均衡)+Redis(Session共享)+Tomcat集群

    为什么移除首页?哪里不符合要求?倒是回我邮件啊! 一.环境搭建 Linux下Vagrant搭建Tomcat7.Java7 二.Nginx的安装配置与测试 *虚拟机下转至root sudo -i 1)下 ...

  8. RAC实例 表空间 维护

    先配置一下监听,这样我们就可以从客户端进行连接了. 我这里写了三种连接. 第一种是正常方式,一般都采用这种方式,后面的rac1和rac2 是方便测试.因为如果用第一种方式的话,客户端连哪个实例是随机的 ...

  9. delete archivelog all 无法彻底删除归档日志?

    最近在因归档日志暴增,使用delete archivelog all貌似无法清除所有的归档日志,到底是什么原因呢? 1.演示环境 SQL> select * from v$version whe ...

  10. windows xp 安装mysql5.6.17-ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password

    .zip解压后没有setup 没有my.ini 1.安装方法 bin目录下执行以下: E:\mysql-5.6.17-win32\bin>mysqld install MySQL --defau ...