讨论log4j记录日志失败的错误处理

讨论log4j记录日志失败的异常处理本帖最后由 lg_asus 于 2012-12-08 14:18:52 编辑http://stackoverflow.c

讨论log4j记录日志失败的异常处理
本帖最后由 lg_asus 于 2012-12-08 14:18:52 编辑 http://stackoverflow.com/questions/13758735/how-can-i-get-notified-when-log4j-fails

下面是demo code:


package test;

import java.lang.Thread.UncaughtExceptionHandler;

import org.apache.log4j.Logger;

public class Test2
{

    public static void main(String...args){
       Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){
           @Override
           public void uncaughtException(Thread t, Throwable e)
           {
              System.out.println(t);
              e.printStackTrace();
           }
       });
       Logger logger = null;
       try{
           logger = Logger.getLogger(Test2.class);
       }catch(Exception e){
           e.printStackTrace();
//         switch to other appender
//         logger = Logger.getLogger("hell");
       }
       logger.info("Hello");
    }
}




my log4j.properties is:

log4j.rootLogger = error, DYNADS

log4j.logger.test= info, DYNADS

log4j.appender.DYNADS = org.apache.log4j.DailyRollingFileAppender   
log4j.appender.DYNADS.File = Z:/log/app-log.txt  
log4j.appender.DYNADS.Append = true  
log4j.appender.DYNADS.layout = org.apache.log4j.PatternLayout  
log4j.appender.DYNADS.layout.ConversionPattern = %d{HH:mm:ss,SSS} [%-5p] %m%n


the result of code is :

log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: Z:\log\app-log.txt (系统找不到指定的路径。)
    at java.io.FileOutputStream.openAppend(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:177)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:102)
    at org.apache.log4j.FileAppender.setFile(FileAppender.java:290)
    at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:164)
    at org.apache.log4j.DailyRollingFileAppender.activateOptions(DailyRollingFileAppender.java:216)
    at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:257)
    at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:133)
    at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:97)
    at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:689)
    at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:647)


    at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:544)
    at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:440)
    at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:476)
    at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:471)
    at org.apache.log4j.LogManager.<clinit>(LogManager.java:125)
    at org.apache.log4j.Logger.getLogger(Logger.java:118)
    at test.Test2.main(Test2.java:25)
log4j:ERROR Either File or DatePattern options are not set for appender [DYNADS].



在代码中捕捉不到这个异常,因此如果log4j在记录日志失败的时候,我想采取一些额外的措施,现在问题是:好像没有方法得知log4j是否失败?
[最优解释]
FallbackErrorHandler
[其他解释]
引用:
引用:如果需要抛出异常,那只能重写log4j中的相应方法了

对,log4j自己把异常捕捉了,造成我捕捉不到这个异常。

估计只能自己重写了,不明白log4j为什么自己把异常吃了,怎么不向外抛呢?



因为log4j只是一个日志工具,有没有这个工具都不应该都业务造成影响
[其他解释]
如果需要抛出异常,那只能重写log4j中的相应方法了
[其他解释]
FallbackErrorHandler
[其他解释]
把你的log4j的配置文件贴出来看看。
[其他解释]
引用:
把你的log4j的配置文件贴出来看看。


log4j.properties已经贴出来了,你仔细看下
[其他解释]
log4j.appender.DYNADS.File = Z:/log/app-log.txt 有没有Z盘啊
[其他解释]
引用:
log4j.appender.DYNADS.File = Z:/log/app-log.txt 有没有Z盘啊


+1
[其他解释]
是log4j已经将该异常捕获。所以应用程序可以继续运行,但是日志没有打印出来
[其他解释]
引用:
log4j.appender.DYNADS.File = Z:/log/app-log.txt 有没有Z盘啊


没有Z盘。
但是现在我自己catch不到这个异常
[其他解释]
引用:
如果需要抛出异常,那只能重写log4j中的相应方法了


对,log4j自己把异常捕捉了,造成我捕捉不到这个异常。

估计只能自己重写了,不明白log4j为什么自己把异常吃了,怎么不向外抛呢?
[其他解释]
引用:
FallbackErrorHandler


嗯,你说的方法可行。
整理一下,方便后来人:





代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %c - %m%n"/>


</layout>
</appender>

<appender name="file" class="org.apache.log4j.DailyRollingFileAppender">
<errorHandler class="org.apache.log4j.varia.FallbackErrorHandler">
<root-ref/>
<appender-ref ref="console"/>
</errorHandler>
<param name="File" value="C:/temp/test.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c - %m%n"/>
</layout>
</appender>

<root>
<level value="INFO"/>
<appender-ref ref="file"/>
</root>
</log4j:configuration>




import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

public class Test2
{

public static void main(String...args){
DOMConfigurator.configure("log4j.xml");
Logger logger = Logger.getLogger(Test2.class);
System.out.println(logger.getAppender("file"));
logger.info("HelloWorld");
}
}



把log文件改成只读后,日志就会被记录到console了。

还有一点:图片中说的:turn log4j debug on,我想知道怎么才能把log4j的debug打开,哪个参数?
知道的告诉我下
[其他解释]
知道了,是log4j.debug这个参数。。。

多谢tank大牛 and各们兄弟们。。。
[其他解释]
对了,用PropertiesConfigurator的话,我配置了errorHandler报错,说not such element。 建议大家采用xml格式配置吧。 这也是tank兄推荐的方式~ hoho~~~~