zoukankan      html  css  js  c++  java
  • logback1.11的一个bug:有线程持续不断写入log文件,log文件就不会按设定以日期切换。

    此Bug的解决方案请见:https://www.cnblogs.com/xiandedanteng/p/12205422.html

    logback是log4j的后继者,作者也是同一人,但其中的bug不可不知。

    其中一个bug就是:当设定FileNamePattern为${LOG_HOME}/XXXX.%d{yyyy-MM-dd}.log后,如果有线程不断写log,即使过了零点,文件也不会更换到以新日期命名的新文件,而还是会在昨天命名的文件中不断写入。即使有新线程在零点之后启动写log,内容依旧会写入以昨天命名的文件里。简短来说就是有线程持续不断写入log文件,log文件就不会按设定以日期切换。

    目前这个bug确认发生在logback1.11(logback-classic1.11.jar,logback-core1.11.jar,slf4j-api-1.7.22.jar)版本里,其它版本未知。下面结果在win10和linux中都可重现。

    下面是我的logback配置文件,红字部分就是设定log按日期切换:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration debug="false">
        <!-- Where are log files -->
        <property name="LOG_HOME" value="d:/logs" />
        
        <!-- Output to Console -->
        <appender name="STDOUT"
            class="ch.qos.logback.core.ConsoleAppender">
            <encoder
                class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <!--%d:date,%thread:thread,%-5level:error/debug/info... %msg:message,%n:new line -->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -%msg%n</pattern>
            </encoder>
        </appender>
        
        <!-- Output to File -->
        <appender name="FILE"
            class="ch.qos.logback.core.rolling.RollingFileAppender">
            <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--log file pathname -->
                <FileNamePattern>${LOG_HOME}/logbackCfg.log.%d{yyyy-MM-dd}.log
                </FileNamePattern>
                <!--days log files will be kept -->
                <MaxHistory>30</MaxHistory>
            </rollingPolicy>
            <encoder
                class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <!--%d:date,%thread:thread,%-5level:error/debug/info... %msg:message,%n:new line -->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -%msg%n</pattern>
            </encoder>
            <!--size -->
            <triggeringPolicy
                class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                <MaxFileSize>10MB</MaxFileSize>
            </triggeringPolicy>
        </appender>
    
        <!-- log level TRACE, DEBUG, INFO, WARN, ERROR, ALL and OFF,default:DEBUG。-->
        <root level="ALL">
            <appender-ref ref="STDOUT" /> <!-- show log on console -->
            <appender-ref ref="FILE" /> <!-- show log in file -->
        </root>
    </configuration>

    我用来启动线程不断写log两个线程之一如下:

    package logbackCfg;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.io.PrintWriter;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    class Runner extends Thread {
        private String file;
        
        public Runner(String file) {
            this.file=file;
        }
        
        public void run() {
            while(true) {
                try {
                    Thread.sleep(5000);
                    Thread.currentThread().interrupt();
                    
                    File f=new File(file);
                    FileWriter fw = new FileWriter(f, true);
                    
                    PrintWriter pw = new PrintWriter(fw);
                    pw.println("追加内容");
                    pw.println("落霞与孤鹜齐飞");
                    pw.println("秋水共长天一色");
                    pw.println("滕王阁序 唐.王勃");
                    pw.flush();
    
    
                    pw.close();
                    fw.close();
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    public class App {
        private final static Logger logger = LoggerFactory.getLogger(App.class);
    
        public static void main(String[] args) throws InterruptedException {
            //Runner r=new Runner("D:\logs\logbackCfg.log.2020-01-15.log");
            //r.start();
            
            while(true) {
                Thread.sleep(5000);
                logger.info("秦时明月汉时关");
                logger.error("万里长征人未还");
                logger.debug("但使龙城飞将在");
                logger.trace("不教胡马度阴山");
            }
        }
    }

    不断写入之二:

    package logbackCfg;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    
    
    
    
    public class App2 {
        private final static Logger logger = LoggerFactory.getLogger(App2.class);
    
        public static void main(String[] args) throws InterruptedException {
            
            while(true) {
                Thread.sleep(8000);
                logger.info("九里山前作战场");
                logger.error("牧童拾得旧刀枪");
                logger.debug("微风吹皱乌江水");
                logger.trace("恰似虞姬别霸王");
            }
        }
    }

    过了零点启动写log的线程如下:

    package logbackCfg;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class NewDayThread {
        private final static Logger logger = LoggerFactory.getLogger(NewDayThread.class);
    
        public static void main(String[] args) throws InterruptedException {
            
            while(true) {
                Date currentTime = new Date();
                
                if(currentTime.compareTo(fixedDate())>0) {
                    Thread.sleep(8000);
                    logger.info("万里赴戎机,关山度若飞。");
                    logger.error("朔气传金柝,寒光照铁衣。");
                    logger.debug("将军百战死,壮士十年归。");
                }
            }
        }
        
        private static Date fixedDate() {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                return formatter.parse("2020-01-17 00:00:00");
            } catch (ParseException e) {
                return new Date();
            }
        }
    }

    结果到了17日,log依旧在往16日的log中不断写入,下面是证据:

    以上实现并不复杂,大家可以本地配置实验一下,看看情况如何,如果不想写代码,也可以从这里https://files.cnblogs.com/files/xiandedanteng/logbackCfg2020-01-17.zip下载。

    --END-- 2020-01-1709:37

  • 相关阅读:
    IIS中使用URL重写工具进行rewrite的规则示例
    施文钧:值得看的文化类节目
    泉州校区/院区分布趋势
    IIS安装SSL证书-轻松实现HTTPS
    [小结]定时任务/作业
    技术或运营的妥协/退让场景
    Windows下开发PHP的准备事项
    移动端之封装个tap()事件
    注解
    Intellij IDEA run coverage之覆盖率测试
  • 原文地址:https://www.cnblogs.com/heyang78/p/12204103.html
Copyright © 2011-2022 走看看