使用Log4j记录日志,遇到一个烦心的问题,就是每天创建新日志文件时(日志文件设置为:org.apache.log4j.DailyRollingFileAppender)报:log4j:ERROR Failed to rename错误; 

      经过一翻查找,最终知道导致这一错误的罪魁祸首是在Tomcat server.xml中所设置的<Context docBase="xxxx" path="/" reloadable="true"/>所导致的,由于加了这一设置,日志文件始终被其占有,所以当log4j对日志文件进行rename时,就发生了Failed to rename错误 。

 

     由于log4j在实现日志文件备份时使用的是file.renameTo(File)方法:

Java代码  log4j:ERROR Failed to rename错误_log4j:ERROR Failed t

  1. File file = new File(fileName);     

  2.     boolean result = file.renameTo(target);  

  3.   

  4.     if(result) {     

  5.       LogLog.debug(fileName +" -> "+ scheduledFilename);     

  6.     } else {     

  7.       LogLog.error("Failed to rename ["+fileName+"] to ["+scheduledFilename+"].");     

  8.     }    

 

 

     而File类的renameTo方法的作用是:”改名或者移动文件作用;在同一个目录下renameTo是改名,在不同目录下是移动",所以在对一个被其他线程所锁定的文件进行改名时,肯定是会报错的。

 

    为解决这一错误, 想来想去最终还是采用了http://duanni.iteye.com/blog/177271 的解决方案,修改了log4j源码,把file.renameTo(File)方法更改成copy文件了,算是解决了问题。不过还是有点担心,就像icefox_wjx 所说的一样,仍然无法预料操作系统会不会出现什么样的情况,如不允许文件copy等等;最终希望能有高人给出更好的解决方案。


修改后的jar如下:http://down.51cto.com/data/2232166



log4j.properties配置:

  1.  ### set log levels ###  

  2. log4j.rootLogger = debug , stdout , D , E  

  3.   

  4. ### 输出到控制台 ###  

  5. log4j.appender.stdout = org.apache.log4j.ConsoleAppender  

  6. log4j.appender.stdout.Target = System.out  

  7. log4j.appender.stdout.layout = org.apache.log4j.PatternLayout  

  8. log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n  

  9.   

  10. ### 输出到日志文件 ###  

  11. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender  

  12. log4j.appender.D.File = logs/log.log  

  13. log4j.appender.D.Append = true  

  14. log4j.appender.D.Threshold = DEBUG ## 输出DEBUG级别以上的日志  

  15. log4j.appender.D.layout = org.apache.log4j.PatternLayout  

  16. log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n  

  17.   

  18. ### 保存异常信息到单独文件 ###  

  19. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender  

  20. log4j.appender.D.File = logs/error.log ## 异常日志文件名  

  21. log4j.appender.D.Append = true  

  22. log4j.appender.D.Threshold = ERROR ## 只输出ERROR级别以上的日志!!!  

  23. log4j.appender.D.layout = org.apache.log4j.PatternLayout  

  24. log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n


  1. ### 保存异常信息到单独文件,并且日志文件每天滚动一次 ###  

  2. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender  

  3. log4j.appender.D.File = logs/error.log ## 异常日志文件名  

  4. log4j.appender.D.DatePattern='_'yyyy-MM-dd-HH-mm

  5. log4j.appender.D.Threshold = ERROR ## 只输出ERROR级别以上的日志!!!  

  6. log4j.appender.D.layout = org.apache.log4j.PatternLayout  

  7. log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

ConversionPattern:

  1. %p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。
    %d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。
    %r:输出自应用程序启动到输出该log信息耗费的毫秒数。
    %t:输出产生该日志事件的线程名。
    %l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.Java:10)。
    %c:输出日志信息所属的类目,通常就是所在类的全名。
    %M:输出产生日志信息的方法名。
    %F:输出日志消息产生时所在的文件名称。
    %L::输出代码中的行号。
    %m::输出代码中指定的具体日志信息。
    %n:输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"。
    %x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
    %%:输出一个"%"字符。