下面,我们来看一个更为复杂和更有配置代表性的ErrorHandler:FallbackErrorHandler。
首先来简单介绍一下FallbackErrorHandler,其实这个ErrorHandler就完整了实现了刚才我们考虑的那种出错情况,当某个Appender失效之后,使用配置给ErrorHandler的另一个备用的ErrorHandler来处理日志输出。在Log4j中,ErrorHandler的配置只能使用XML的方式来配置(在Log4J中的PropertyConfigurator中其实是实现了解析ErrorHandler的逻辑,但是确实没有办法解决一些问题,所以这些代码是没有任何用处的)。
在具体配置之前,还是回顾一下我们的需求,我们要求先使用FileAppender来记录日志,如果FileAppender报错,则使用替换的ConsoleAppender来做日志。
<log4j:configuration>
<appender name="file" class="org.apache.log4j.FileAppender">
<errorHandler class="org.apache.log4j.varia.FallbackErrorHandler">
<root-ref/>
<appender-ref ref="console"/>
</errorHandler>
<param name="file" value="log.log"/>
<layout class="org.apache.log4j.SimpleLayout" />
</appender>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="conversionPattern" value="%r [%t] %p %c %x - %m%n"/>
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="file"/>
</root>
</log4j:configuration>
黑体字中的配置配置了一个ErrorHandler。我们来看看有些什么要求。首先ErrorHandler是直接声明在一个Appender里面的,所以ErrorHandler是没有名字,并且不能引用的。其次,得定义ErrorHandler的类型;再次,有一个root-ref这样的空元素,这个元素什么意思呢?还记得ErrorHandler接口上有一个setLogger么?可以为这个ErrorHandler配置需要控制的Logger,这个root-ref就是一个非常特殊的元素,相当于errorHandler.setLogger(Logger.getRootLogger());再次,配置了一个appender-ref,这个appender-ref指向了另外一个consoleAppender,那么这个consoleAppender其实就会被作为参数传给ErrorHandler的setBackupErrorHandler方法;最后,ErrorHandler本身被申明的Appender,即这里的file会作为参数传给ErrorHandler的setHandler方法。此外,在ErrorHandler的配置中还有一个元素叫<logger-ref>,可以通过名字引用到一个或多个Logger,使用多次<logger-ref>即可。这些被引用到的logger都会被作为参数依次通过setLogger方法传给ErrorHandler。
来写一个测试:
@Test
public void testFallbackErrorHandler(){
Logger logger=Logger.getLogger("cd.itcast");
logger.warn("logger warn");
logger.warn("logger warn");
logger.warn("logger warn");
}
同样,创建log.log文件并设置为只读,再次运行:
0 [main] WARN cd.itcast - logger warn
16 [main] WARN cd.itcast - logger warn
16 [main] WARN cd.itcast - logger warn
可以看到,ErrorHandler在fileAppender出错的时候,已经正确的把Appender切换到了ConsoleAppender上。并在控制台输出的日志。
首先来简单介绍一下FallbackErrorHandler,其实这个ErrorHandler就完整了实现了刚才我们考虑的那种出错情况,当某个Appender失效之后,使用配置给ErrorHandler的另一个备用的ErrorHandler来处理日志输出。在Log4j中,ErrorHandler的配置只能使用XML的方式来配置(在Log4J中的PropertyConfigurator中其实是实现了解析ErrorHandler的逻辑,但是确实没有办法解决一些问题,所以这些代码是没有任何用处的)。
在具体配置之前,还是回顾一下我们的需求,我们要求先使用FileAppender来记录日志,如果FileAppender报错,则使用替换的ConsoleAppender来做日志。
<log4j:configuration>
<appender name="file" class="org.apache.log4j.FileAppender">
<errorHandler class="org.apache.log4j.varia.FallbackErrorHandler">
<root-ref/>
<appender-ref ref="console"/>
</errorHandler>
<param name="file" value="log.log"/>
<layout class="org.apache.log4j.SimpleLayout" />
</appender>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="conversionPattern" value="%r [%t] %p %c %x - %m%n"/>
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="file"/>
</root>
</log4j:configuration>
黑体字中的配置配置了一个ErrorHandler。我们来看看有些什么要求。首先ErrorHandler是直接声明在一个Appender里面的,所以ErrorHandler是没有名字,并且不能引用的。其次,得定义ErrorHandler的类型;再次,有一个root-ref这样的空元素,这个元素什么意思呢?还记得ErrorHandler接口上有一个setLogger么?可以为这个ErrorHandler配置需要控制的Logger,这个root-ref就是一个非常特殊的元素,相当于errorHandler.setLogger(Logger.getRootLogger());再次,配置了一个appender-ref,这个appender-ref指向了另外一个consoleAppender,那么这个consoleAppender其实就会被作为参数传给ErrorHandler的setBackupErrorHandler方法;最后,ErrorHandler本身被申明的Appender,即这里的file会作为参数传给ErrorHandler的setHandler方法。此外,在ErrorHandler的配置中还有一个元素叫<logger-ref>,可以通过名字引用到一个或多个Logger,使用多次<logger-ref>即可。这些被引用到的logger都会被作为参数依次通过setLogger方法传给ErrorHandler。
来写一个测试:
@Test
public void testFallbackErrorHandler(){
Logger logger=Logger.getLogger("cd.itcast");
logger.warn("logger warn");
logger.warn("logger warn");
logger.warn("logger warn");
}
同样,创建log.log文件并设置为只读,再次运行:
0 [main] WARN cd.itcast - logger warn
16 [main] WARN cd.itcast - logger warn
16 [main] WARN cd.itcast - logger warn
可以看到,ErrorHandler在fileAppender出错的时候,已经正确的把Appender切换到了ConsoleAppender上。并在控制台输出的日志。