当前位置:编程学习 > JAVA >>

深入Log4J源码之Appender

Appender负责定义日志输出的目的地,它可以是控制台(ConsoleAppender)、文件(FileAppender)、JMS服务器(JmsLogAppender)、以Email的形式发送出去(SMTPAppender)等。Appender是一个命名的实体,另外它还包含了对Layout、ErrorHandler、Filter等引用:

 1 public interface Appender {
 2     void addFilter(Filter newFilter);
 3     public Filter getFilter();
 4     public void clearFilters();
 5     public void close();
 6     public void doAppend(LoggingEvent event);
 7     public String getName();
 8     public void setErrorHandler(ErrorHandler errorHandler);
 9     public ErrorHandler getErrorHandler();
10     public void setLayout(Layout layout);
11     public Layout getLayout();
12     public void setName(String name);
13     public boolean requiresLayout();
14 }

简单的,在配置文件中,Appender会注册到Logger中,Logger在写日志时,通过继承机制遍历所有注册到它本身和其父节点的Appender(在additivity为true的情况下),调用doAppend()方法,实现日志的写入。在doAppend方法中,若当前Appender注册了Filter,则doAppend还会判断当前日志时候通过了Filter的过滤,通过了Filter的过滤后,如果当前Appender继承自SkeletonAppender,还会检查当前日志级别时候要比当前Appender本身的日志级别阀门要打,所有这些都通过后,才会将LoggingEvent实例传递给Layout实例以格式化成一行日志信息,最后写入相应的目的地,在这些操作中,任何出现的错误都由ErrorHandler字段来处理。

Log4J中的Appender类图结构:

 

在Log4J Core一小节中已经简单的介绍过了AppenderSkeleton、WriterAppender、ConsoleAppender以及 Filter,因小节将直接介绍具体的几个常用的Appender。

FileAppender类

FileAppender继承自WriterAppender,它将日志写入文件。主要的日志写入逻辑已经在WriterAppender中处理,FileAppender主要处理的逻辑主要在于将设置日志输出文件名,并通过设置的文件构建WriterAppender中的QuiteWriter字段实例。如果Log文件的目录没有创建,在setFile()方法中会先创建目录,再设置日志文件。另外,所有FileAppender字段在调用activateOptions()方法中生效。

 1     protected boolean fileAppend = true;
 2     protected String fileName = null;
 3     protected boolean bufferedIO = false;
 4     protected int bufferSize = 8 * 1024;
 5
 6     public void activateOptions() {
 7         if (fileName != null) {
 8             try {
 9                 setFile(fileName, fileAppend, bufferedIO, bufferSize);
10             } catch (java.io.IOException e) {
11                 errorHandler.error("setFile(" + fileName + "," + fileAppend
12                         + ") call failed.", e, ErrorCode.FILE_OPEN_FAILURE);
13             }
14         } else {
15             LogLog.warn("File option not set for appender [" + name + "].");
16             LogLog.warn("Are you using FileAppender instead of ConsoleAppender?");
17         }
18     }
19
20     public synchronized void setFile(String fileName, boolean append,
21             boolean bufferedIO, int bufferSize) throws IOException {
22         LogLog.debug("setFile called: " + fileName + ", " + append);
23         if (bufferedIO) {
24             setImmediateFlush(false);
25         }
26         reset();
27         FileOutputStream ostream = null;
28         try {
29             ostream = new FileOutputStream(fileName, append);
30         } catch (FileNotFoundException ex) {
31             String parentName = new File(fileName).getParent();
32             if (parentName != null) {
33                 File parentDir = new File(parentName);
34                 if (!parentDir.exists() && parentDir.mkdirs()) {
35                     ostream = new FileOutputStream(fileName, append);
36                 } else {
37                     throw ex;
38                 }
39             } else {
40                 throw ex;
41             }
42         }
43         Writer fw = createWriter(ostream);
44         if (bufferedIO) {
45             fw = new BufferedWriter(fw, bufferSize);
46         }
47         this.setQWForFiles(fw);
48         this.fileName = fileName;
49         this.fileAppend = append;
50         this.bufferedIO = bufferedIO;
51         this.bufferSize = bufferSize;
52         writeHeader();
53         LogLog.debug("setFile ended");
54     }
 

DailyRollingFileAppender类

DailyRollingFileAppender继承自FileAppender,不过这个名字感觉有点不靠谱,事实上,DailyRollingFileAppender会在每隔一段时间可以生成一个新的日志文件,不过这个时间间隔是可以设置的,不仅仅只是每隔一天。时间间隔通过setDatePattern()方法设置,datePattern必须遵循SimpleDateFormat中的格式。支持的时间间隔有:

1. 

补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,