how tomcat works读书笔记 七 日志记录器
大家可以松一口气了,这个组件比较简单,这一节和前面几节想比,也简单的多。
Logger接口
Tomcat中的日志记录器都必须实现org.apache.catalina.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);
}
Logger定义了五种日志记录基本,当我们在调用log(String message, int verbosity)方法记录日志的时候,只有传进来的verbosity小于等于系统的默认值才会记录。话说大家知道Integer.MIN_VALUE等于多少吗?大概负的21亿左右吧。setVerbosity与getVerbosity是干什么的还需要我说么?
Tomcat的日志记录器
LoggerBase类(抽象类)
它实现了Logger接口中除log(String message)方法外的其余方法;
在类中默认了日志记录级别为
protected int verbosity = ERROR;
但是我们可以通过setVerbosity(int 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);
}
SystemOutLogger类
看名字就知道,信息最后输出到控制台。
SysteErrLogger类
看名字就知道,它是错误输出,信息仍在控制台,不过是红色的。
FileLogger类
看名字就知道,它是吧信息输出的文件里。
不过具体的来说,里面还是有点说头的,慢慢来。
首先FileLogger还实现了Lifecycle接口,因此它可以像其他组件一样被父组件所启动。
在本节中FileLogger的start与stop方法其实只是改变了布尔值started而已,没有做其他的,另一方面,FileLogger的start与stop方法也并没有被调用!
现在我们就看看怎么给文件里写信息。
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);
System.out.println("tsString "+tsString); //tsString 2014-10-20 15:25:27
System.out.println("ts "+ts); //ts 2014-10-20 15:25:27.406
System.out.println("tsDate "+tsDate); //tsDate 2014-10-20
// 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);
}
}
}
File默认是每一天一个新的文件,文件内格式就是日期+具体信息(如果timestamp为true的话);
那close(),open()方法和writer属性又是什么呢?
private void open() {
// Create the directory if necessary
File dir = new File(directory);
if (!dir.isAbsolute())
dir = new File(System.getProperty("catalina.base"), directory); //至于catalina.base是什么 一会再说
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;
}
}
先检查给定的目录是否存在,如果不存在新建一个;接着根据前缀,时间,后缀设定文件名;根据文件名填充writer对象。
private void close() {
if (writer == null)
return;
writer.flush();
writer.close();
writer = null;
date = "";
}
FileLogger中的date代表的就是当前的时间,当然关闭后为空。
应用程序
Bootstrap类
...
System.setProperty("catalina.base", System.getProperty("user.dir"));
FileLogger logger = new FileLogger();
logger.setPrefix("FileLog_");
logger.setSuffix(".txt");
logger.setTimestamp(true);
logger.setDirectory("webroot");
context.setLogger(logger);
....
SimpleContext类
public synchronized void start() throws LifecycleException {
log("starting Context");
........
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
log("Context started");
}
private void log(String message) {
Logger logger = this.getLogger();
if (logger!=null)
logger.log(message);
}
运行后在项目的webroot目录下就可以看到FileLog_2014-10-20.txt文件;
每次运行,在文件中都会多出如下的内容
2014-10-20 14:34:21 HttpConnector Opening server socket on all host IP addresses
2014-10-20 14:34:22 HttpConnector[8080] Starting background thread
2014-10-20 14:34:22 HttpProcessor[8080][0] Starting background thread
2014-10-20 14:34:22 HttpProcessor[8080][1] Starting background thread
2014-10-20 14:34:22 HttpProcessor[8080][2] Starting background thread
2014-10-20 14:34:22 HttpProcessor[8080][3] Starting background thread
2014-10-20 14:34:22 HttpProcessor[8080][4] Starting background thread
2014-10-20 14:34:22 starting Context
2014-10-20 14:34:22 Context started
how tomcat works读书笔记 七 日志记录器的更多相关文章
- how tomcat works 读书笔记(二)----------一个简单的servlet容器
app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...
- how tomcat works 读书笔记四 tomcat的默认连接器
事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...
- how tomcat works 读书笔记(一)----------一个简单的webserver
http协议 若是两个人能正常的说话交流,那么他们间必然有一套统一的语言规则<在网络上server与client能交流也依赖与一套规则,它就是我们说的http规则(超文本传输协议Hypertex ...
- how tomcat works 读书笔记(一)----------一个简单的web服务器
http协议 若是两个人能正常的说话交流,那么他们间必定有一套统一的语言规则<在网络上服务器与客户端能交流也依赖与一套规则,它就是我们说的http规则(超文本传输协议Hypertext tran ...
- How Tomcat Works读书笔记三-------连接器
几个概念 HttpServlet,Servlet Servlet是一个接口,定义了一种网络服务,我们所有的servlet都要实现它(或它的子类) HttpServlet是一个抽象类,它针对的就是htt ...
- How Tomcat Works 读书笔记 八 载入器 上
Java的类载入器 详细资料见 http://blog.csdn.net/dlf123321/article/details/39957175 http://blog.csdn.net/dlf1233 ...
- How tomcat works 读书笔记十七 启动tomcat 下
在上一节中,我们程序的起始位置还是Bootstrap,现在我们通过bat文件来启动这个类. 在分析catalina.bat之前,我们先看看几个简单的我们能用到的dos命令. 基础知识 1 rem 注释 ...
- How tomcat works 读书笔记十七 启动tomcat 上
一路跋山涉水,这是最后一章了. 关于tomcat的启动,有两个类,一个是Catalina类,一个是Bootstrap类. 理论上,两个类可以和到一起,但是为了支持多种运行模式,又把他们分开了. 为了让 ...
- How tomcat works 读书笔记十五 Digester库 下
在这一节里我们说说ContextConfig这个类. 这个类在很早的时候我们就已经使用了(之前那个叫SimpleContextConfig),但是在之前它干的事情都很简单,就是吧context里的co ...
随机推荐
- 剑指Offer——小米+小红书笔试题+知识点总结
剑指Offer--小米+小红书笔试题+知识点总结 情景回顾 时间:2016.9.23 19:00-21:00 2016.9.24 15:00-17:00 地点:山东省网络环境智能计算技术重点实验室 事 ...
- tomcat启动批处理——catalina.bat
这个批处理才是tomcat服务器启动跟关闭的核心脚本.其中包括....(各种变量),此节将详细讲解这个批处理的逻辑. 先看看第一部分脚本: ****************************** ...
- Android动态换肤(一、应用内置多套皮肤)
动态换肤在很多android应用中都有使用,用户根据自己的喜好设置皮肤主题,可以增强用户使用应用的舒适度. Android换肤可以分为很多种,它们从使用方式,用户体验以及项目框架设计上体现了明显的差异 ...
- 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法
注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...
- SSH深度历险(二) Jboss+EJB的第一个实例
学习感悟:每次学习新的知识,都会通过第一个小的实例入手,获得成就感,经典的Hello Workd实例奠定了我们成功的大门哈,这些经典的实例虽小但是五脏俱全呢,很好的理解了,Ejb的核心. 今天主要以这 ...
- Android开发学习之路--Activity之Intent
窗外再次飘起了小雪,还有1周就过年了,2016年即将到来,来年不知道自己将身处何处,船到桥头自然直吧.还是继续学习吧,上次学习了Activity,那么如果是两个Activity之间,怎么从一个Acti ...
- Android的事件处理-android学习之旅(四十四)
androd事件处理简介 控制飞机移动的简单实例 package peng.liu.test; import android.app.ActionBar; import android.app.Act ...
- SDL2源代码分析4:纹理(SDL_Texture)
===================================================== SDL源代码分析系列文章列表: SDL2源代码分析1:初始化(SDL_Init()) SDL ...
- ADO.NET之Parameter属性
在ADO.NET中, public SqlParameterCollection Parameters {get;}会得到一个SqlParameter属性.下面通过一个例子进行详细的认识吧. //例如 ...
- Andoird Crash的跟踪方法,使用腾讯Bugly来捕捉一些疑难杂症,让我们APP稳定上线
Andoird Crash的跟踪方法,使用腾讯Bugly来捕捉一些疑难杂症,让我们APP稳定上线 我们在开发中常常会注意到一些Crash,这正是很头疼的,而且Crash会带来很多意想不到的状态,很恶心 ...