首先来看WriterAppender,WriterAppender是一个非常基础的Appender,他可以将LoggingEvent合成的结果直接交给一个Writer对象去处理。通过这个描述,其实我们也能很简单的想到,WriterAppender是不能通过配置脚本来完成配置的,只能允许通过代码的方式指定要输出的Writer。那为什么我们还要学习WriterAppender呢?其实很简单,因为他是后面要讲到的ConsoleAppender,FileAppender等的父类。在这个Appender中提供了几个比较有意思的参数。要看到这些参数,第一个方式就是直接看API文档,第二个方式我们之前已经知道,一个Appender能够配置哪些参数,其实都是由这个Appender对应的setter方法规定的,有哪些setter方法,就有哪些参数可以配置,所以我们也能够直接通过查看代码的方式来看到这些参数。
第一个参数:encoding,用来规定了输出String的编码格式,如果没有设置编码格式,那么按照系统的默认编码格式输出;
第二个参数:immediateFlush,用来确定是否需要立刻记录。默认情况下,这个选项为true,代表每一次日志请求之后,立刻把这次日志的内容输出到Writer上,如果设置这个选项为false,则在一次日志请求之后,不会立刻的把内容输出到writer上,而会先把日志请求缓存一下,过段时间再发送到Writer上输出。这样做可以提高20%左右的程序性能,但随之而来的问题是,有可能有一小部分的日志请求会丢失。这个需要根据实际应用的综合考察了,一般情况下,把immediateFlush设置为true是没有问题的,因为在产品环境下,一般也不会设置过低的日志输出级别,所以,在普通情况下,日志的输出频率其实是比较低的,采用立刻刷新对IO的消耗也不会太多。我们来写个测试看看immediateFlush:
@Test
public void testWriterAppender() {
Logger.getRootLogger().setLevel(Level.INFO);
WriterAppender wa=new WriterAppender(new SimpleLayout(),System.out);
// wa.setImmediateFlush(false);
Logger.getRootLogger().addAppender(wa);
Logger logger = Logger.getLogger("cd.itcast");
Logger barLogger = Logger.getLogger("cd.itcast.log");
logger.warn("logger warn");
logger.debug("logger debug");
barLogger.info("bar logger info");
barLogger.debug("bar logger debug");
}
这里,我们直接创建了一个WriterAppender,并且将System.out作为输出流传给了WriterAppender,相当于内容会直接输出到Console中(当然,这不是ConsoleAppender的实现方式,ConsoleAppender的实现方式会更复杂一点)。我们首先使用默认的immediateFlush值,即true。运行测试:
WARN - logger warn
INFO - bar logger info
立刻输出日志内容,不用多讲,这时候,我们把注释打开,即设置immediateFlush(false),再次运行测试。很可惜,这次什么东西都没有输出了,原因前面已经说的很明白了,在这种情况下,Appender不会立刻把日志内容输出,而会先暂时缓存一下,再输出,但是缓存的过程当中,测试执行完成,那么日志就再也不会被输出了。
前面已经说到,WriterAppender不能直接配置使用,所以大部分情况下,也都不会直接使用WriterAppender,而会选择使用其子类。比如ConsoleAppender。
第一个参数:encoding,用来规定了输出String的编码格式,如果没有设置编码格式,那么按照系统的默认编码格式输出;
第二个参数:immediateFlush,用来确定是否需要立刻记录。默认情况下,这个选项为true,代表每一次日志请求之后,立刻把这次日志的内容输出到Writer上,如果设置这个选项为false,则在一次日志请求之后,不会立刻的把内容输出到writer上,而会先把日志请求缓存一下,过段时间再发送到Writer上输出。这样做可以提高20%左右的程序性能,但随之而来的问题是,有可能有一小部分的日志请求会丢失。这个需要根据实际应用的综合考察了,一般情况下,把immediateFlush设置为true是没有问题的,因为在产品环境下,一般也不会设置过低的日志输出级别,所以,在普通情况下,日志的输出频率其实是比较低的,采用立刻刷新对IO的消耗也不会太多。我们来写个测试看看immediateFlush:
@Test
public void testWriterAppender() {
Logger.getRootLogger().setLevel(Level.INFO);
WriterAppender wa=new WriterAppender(new SimpleLayout(),System.out);
// wa.setImmediateFlush(false);
Logger.getRootLogger().addAppender(wa);
Logger logger = Logger.getLogger("cd.itcast");
Logger barLogger = Logger.getLogger("cd.itcast.log");
logger.warn("logger warn");
logger.debug("logger debug");
barLogger.info("bar logger info");
barLogger.debug("bar logger debug");
}
这里,我们直接创建了一个WriterAppender,并且将System.out作为输出流传给了WriterAppender,相当于内容会直接输出到Console中(当然,这不是ConsoleAppender的实现方式,ConsoleAppender的实现方式会更复杂一点)。我们首先使用默认的immediateFlush值,即true。运行测试:
WARN - logger warn
INFO - bar logger info
立刻输出日志内容,不用多讲,这时候,我们把注释打开,即设置immediateFlush(false),再次运行测试。很可惜,这次什么东西都没有输出了,原因前面已经说的很明白了,在这种情况下,Appender不会立刻把日志内容输出,而会先暂时缓存一下,再输出,但是缓存的过程当中,测试执行完成,那么日志就再也不会被输出了。
前面已经说到,WriterAppender不能直接配置使用,所以大部分情况下,也都不会直接使用WriterAppender,而会选择使用其子类。比如ConsoleAppender。