log4j日志文件输出错误的解决过程

Posted GISerliang与0和1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了log4j日志文件输出错误的解决过程相关的知识,希望对你有一定的参考价值。

起因:部门网站使用B/S架构请求,请求过程中需要将日志文件记录下来,以便出现问题进行查找,刚开始服务器上的日志文件能够正常输出,后来日志文件不能输出,部门领导让我查找原因并修改。

目的:使用log4j的DailyRollingFileAppender每天生成一个日志文件,并在生成的日志文件之后添加日期作为标识,如wmts_2015-12-21.log。

试验期:

1、小白入门

log4j.properties配置如下

log4j.appender.Info=org.apache.log4j.DailyRollingFileAppender

log4j.appender.Info.File = ${log4j.log.dir}/wmts_

log4j.appender.Info.DatePattern = yyyy-MM-dd'.log'

log4j.appender.Info.Append = false

log4j.appender.Info.Threshold = INFO

log4j.appender.Info.layout = org.apache.log4j.PatternLayout

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

原以为每次请求都会生成类似“wmts_2015-12-21.log”的文件,后来才知道当天的日志会先创建在“wmts_”文件中,第二天才会以前一天的日期生成日志文件。

但是经过多次的试验,一直没有生成正确命名的日志文件。


2、C/S尝试


(1)鉴于上面的试验一直没有成功,本人想到可能是本人的修炼还不够,一上手就用成型的项目可能有些问题不好发现,所以本人写了最简单的C/S的Demo来跟踪日志的生成。

log4j.properties的配置如下:

log4j.appender.R1=org.apache.log4j.RollingFileAppender

log4j.appender.R1.file=C:/demo.log

log4j.appender.R1.layout=org.apache.log4j.PatternLayout

log4j.appender.R1.layout.conversionPattern=%d %c (%M:%L) - %m%n

生成日志文件正常。


(2)更改log4j.properties为项目的配置:

log4j.appender.Info = org.apache.log4j.DailyRollingFileAppender

log4j.appender.Info.File = ${log4j.log.dir}/wmts_

log4j.appender.Info.DatePattern = yyyy-MM-dd'.log'

log4j.appender.Info.Append = true

log4j.appender.Info.Threshold = INFO

log4j.appender.Info.layout = org.apache.log4j.PatternLayout

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

再次生成日志文件,此时eclipse的console输出了错误代码***log4j:ERROR Failed to rename [D:/logs/wmts_] to [D:/logs/wmts_2015-12-21.log ]***.

这个错误提示帮我最后解决了问题。


3、问题解决


引起log4j:ERROR Failed to rename的条件(没错就是引发的条件)

通常都是在配置文件采用

log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender

或者

log4j.appender.A1=org.apache.log4j.RollingFileAppender

的情况下遇到"异常"提示。

原因:

File file = new File(fileName);

boolean result = file.renameTo(target);

if(result) {

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

} else {

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

}

源代码中使用renameTo将前一天的文件重命名为log4j.properties配置的文件名,但是有的时候该文件会被占用,导致无法进行重命名,才会报上一步的错误。

大神们的解决办法:在log4j中添加一个copy方法,在重命名前一天的日志文件时,将原文件拷贝一份,将拷贝的原文件命名为想要的文件名,来解决该问题。

copy方法的代码如下:

/**

* Copies src file to dst file. If the dst file does not exist, it is

* created.8KB cache

* @param src

* @param dst

* @throws IOException

*/

boolean copy(File src, File dst) throws IOException {

    try {

        InputStream in = new FileInputStream(src);

        OutputStream out = new FileOutputStream(dst);

        // Transfer bytes from in to out
          byte[] buf = new byte[8192];

        int len;

        while ((len = in.read(buf)) > 0) {

            out.write(buf, 0, len);

        }

        in.close();

        out.close();

        return true;

    } catch (FileNotFoundException e) {

        LogLog.error("源文件不存在,或者目标文件无法被识别." );

        return false;

    } catch (IOException e) {

        LogLog.error("文件读写错误.");

        return false;

    }

}


4、心得

问题解决之后回想之前的解决过程,删除每次的日志文件的时候系统提示文件正在占用,停止eclipse的server之后才能删除文件,当时如果认真思考这个问题可能就会发现日志输出不正常的问题。

以上是关于log4j日志文件输出错误的解决过程的主要内容,如果未能解决你的问题,请参考以下文章

log4j输出日志乱码(转)

log4j 日志信息的引入 — 解决项目运行过程中的日志信息

Log4j 日志信息的引入 ( 通用版 ) : 解决项目运行过程中的日志信息

log4j程序遇到错误打印日志到文件中

如何让log4j日志只输出错误信息

优雅记录log4j日志