此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按日期切换:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration debug="false">
  3. <!-- Where are log files -->
  4. <property name="LOG_HOME" value="d:/logs" />
  5.  
  6. <!-- Output to Console -->
  7. <appender name="STDOUT"
  8. class="ch.qos.logback.core.ConsoleAppender">
  9. <encoder
  10. class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  11. <!--%d:date,%thread:thread,%-5level:error/debug/info... %msg:message,%n:new line -->
  12. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -%msg%n</pattern>
  13. </encoder>
  14. </appender>
  15.  
  16. <!-- Output to File -->
  17. <appender name="FILE"
  18. class="ch.qos.logback.core.rolling.RollingFileAppender">
  19. <rollingPolicy
  20. class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  21. <!--log file pathname -->
  22. <FileNamePattern>${LOG_HOME}/logbackCfg.log.%d{yyyy-MM-dd}.log
  23. </FileNamePattern>
  24. <!--days log files will be kept -->
  25. <MaxHistory>30</MaxHistory>
  26. </rollingPolicy>
  27. <encoder
  28. class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  29. <!--%d:date,%thread:thread,%-5level:error/debug/info... %msg:message,%n:new line -->
  30. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -%msg%n</pattern>
  31. </encoder>
  32. <!--size -->
  33. <triggeringPolicy
  34. class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
  35. <MaxFileSize>10MB</MaxFileSize>
  36. </triggeringPolicy>
  37. </appender>
  38.  
  39. <!-- log level TRACE, DEBUG, INFO, WARN, ERROR, ALL and OFF,default:DEBUG。-->
  40. <root level="ALL">
  41. <appender-ref ref="STDOUT" /> <!-- show log on console -->
  42. <appender-ref ref="FILE" /> <!-- show log in file -->
  43. </root>
  44. </configuration>

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

  1. package logbackCfg;
  2.  
  3. import java.io.File;
  4. import java.io.FileWriter;
  5. import java.io.PrintWriter;
  6.  
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9.  
  10. class Runner extends Thread {
  11. private String file;
  12.  
  13. public Runner(String file) {
  14. this.file=file;
  15. }
  16.  
  17. public void run() {
  18. while(true) {
  19. try {
  20. Thread.sleep(5000);
  21. Thread.currentThread().interrupt();
  22.  
  23. File f=new File(file);
  24. FileWriter fw = new FileWriter(f, true);
  25.  
  26. PrintWriter pw = new PrintWriter(fw);
  27. pw.println("追加内容");
  28. pw.println("落霞与孤鹜齐飞");
  29. pw.println("秋水共长天一色");
  30. pw.println("滕王阁序 唐.王勃");
  31. pw.flush();
  32.  
  33. pw.close();
  34. fw.close();
  35.  
  36. } catch (Exception e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. }
  41. }
  42.  
  43. public class App {
  44. private final static Logger logger = LoggerFactory.getLogger(App.class);
  45.  
  46. public static void main(String[] args) throws InterruptedException {
  47. //Runner r=new Runner("D:\\logs\\logbackCfg.log.2020-01-15.log");
  48. //r.start();
  49.  
  50. while(true) {
  51. Thread.sleep(5000);
  52. logger.info("秦时明月汉时关");
  53. logger.error("万里长征人未还");
  54. logger.debug("但使龙城飞将在");
  55. logger.trace("不教胡马度阴山");
  56. }
  57. }
  58. }

不断写入之二:

  1. package logbackCfg;
  2.  
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5.  
  6. public class App2 {
  7. private final static Logger logger = LoggerFactory.getLogger(App2.class);
  8.  
  9. public static void main(String[] args) throws InterruptedException {
  10.  
  11. while(true) {
  12. Thread.sleep(8000);
  13. logger.info("九里山前作战场");
  14. logger.error("牧童拾得旧刀枪");
  15. logger.debug("微风吹皱乌江水");
  16. logger.trace("恰似虞姬别霸王");
  17. }
  18. }
  19. }

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

  1. package logbackCfg;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6.  
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9.  
  10. public class NewDayThread {
  11. private final static Logger logger = LoggerFactory.getLogger(NewDayThread.class);
  12.  
  13. public static void main(String[] args) throws InterruptedException {
  14.  
  15. while(true) {
  16. Date currentTime = new Date();
  17.  
  18. if(currentTime.compareTo(fixedDate())>0) {
  19. Thread.sleep(8000);
  20. logger.info("万里赴戎机,关山度若飞。");
  21. logger.error("朔气传金柝,寒光照铁衣。");
  22. logger.debug("将军百战死,壮士十年归。");
  23. }
  24. }
  25. }
  26.  
  27. private static Date fixedDate() {
  28. SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  29. try {
  30. return formatter.parse("2020-01-17 00:00:00");
  31. } catch (ParseException e) {
  32. return new Date();
  33. }
  34. }
  35. }

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

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

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

logback1.11的一个bug:有线程持续不断写入log文件,log文件就不会按设定以日期切换。的更多相关文章

  1. 同样是logback1.11,更换了log配置后,无论是否有线程持续不断写入log文件,log文件会按设定以日期序号轮换

    上次发现了logback1.11的一个bug,即有线程持续写入log,则log文件不会按设定模式进行轮换. 但发现同样采用logback1.11的另外一个工程,它的日志文件就没有错误,于是参照其配置文 ...

  2. 医生加号页改版,就一个Bug, 看医生工作台一期需求

    8/8日报 分级埋点:     [MobClick event:UmengPagePlusDoctor attributes:@{@"page":@"plusPage&q ...

  3. AIX6.1/11.2.0.3在有关数据库SWAP一个BUG

    昨天南京到客户服务数据库的优化调整,其中新上线,经过审查alert.log当日志现在是在过去一段时间内取得,每隔几个小时的时间滞后,班会报似的内容: Thu Aug 21 09:01:26 2014 ...

  4. 使用C++11实现一个半同步半异步线程池

    前言 C++11之前我们使用线程需要系统提供API.posix线程库或者使用boost提供的线程库,C++11后就加入了跨平台的线程类std::thread,线程同步相关类std::mutex.std ...

  5. C++11中一个使用for+auto时容易发生的bug

    C++11中一个使用for+auto时容易发生的bug 一个小坑,那就是忘记在for循环中使用auto时加引用. 例如: for(auto num : nums){ // do some thing ...

  6. 一个代价11万的bug

    这个bug不是技术bug或者是程序bug,是典型的业务操作bug. 开发人员混淆了线上数据和本地测试数据,把线上数据切换到本地的数据做测试,结果对这些客户进行了资金调整...就导致了这个悲剧发生 早在 ...

  7. 我是一个Bug, 终极大Bug

    我是一个Bug ,在这个系统中潜伏很久了,历经多轮测试的严酷考验而屹立不倒,如果Bug界按难度分类的话,我绝对属于地狱模式. 现在,我就等待一个倒霉蛋来触发, 可是他老是不来. 其实不能叫倒霉蛋 , ...

  8. 《一个 Go 程序系统线程暴涨的问题》结论

    原文地址:https://zhuanlan.zhihu.com/p/22474724 作者的结论没写好,我来说两句.. 结论: Docker swarm自己有个函数,叫setTcpUserTimeou ...

  9. 关于MySQL count(distinct) 逻辑的一个bug【转】

    本文来自:http://dinglin.iteye.com/blog/1976026#comments 背景 客户报告了一个count(distinct)语句返回结果错误,实际结果存在值,但是用cou ...

随机推荐

  1. C++ 的字符串反转

    C++ 的字符串反转 方法一: 使用 algorithm 中的 reverse 函数: // reverse 函数的定义(在 std 名称空间中) template<class BidirIt& ...

  2. C#LeetCode刷题-设计

    设计篇 # 题名 刷题 通过率 难度 146 LRU缓存机制   33.1% 困难 155 最小栈 C#LeetCode刷题之#155-最小栈(Min Stack) 44.9% 简单 173 二叉搜索 ...

  3. noip复习——逆元

    逆元,即对给定\(a,p\ (a \perp p)\),求\(x\)使得\(ax \equiv 1 \ (\bmod p)\) 逆元可以看做\(a\)在模\(p\)意义下的\(a^{-1}\).因此, ...

  4. .netcore tif文件转jpg,并通过webapi返回

    网上能搜到很多关于c# tif转jpg的代码.最简单的就是下面这段获得转换后的图片图片对象.在netcore 中使用这段代码时由于netcore框架已经不自带System.Drawing命名空间了所有 ...

  5. 浏览器自动化的一些体会6 增强的webBrowser控件

    这里谈两点 1.支持代理服务器切换 一种方法是修改注册表,不是太好的做法,而且,只能改全局设置,不能改局部(比如只让当前的webBrowser控件使用代理,而其他应用不用代理) 另外一个较好的方法,示 ...

  6. Scala中的Map集合

    1. Map集合 1.1 Scala中的Map介绍 Scala中的Map 和Java类似,也是一个散列表,它存储的内容也是键值对(key-value)映射,Scala中不可变的Map是有序的,可变的M ...

  7. 什么?Java9这些史诗级更新你都不知道?Java9特性一文打尽!

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  8. HMM隐马尔可夫模型来龙去脉(一)

    目录 隐马尔可夫模型HMM学习导航 一.认识贝叶斯网络 1.概念原理介绍 2.举例解析 二.马尔可夫模型 1.概念原理介绍 2.举例解析 三.隐马尔可夫模型 1.概念原理介绍 2.举例解析 四.隐马尔 ...

  9. cannot find package "cloud.google.com/go/compute/metadata"

    问题: cannot find package "cloud.google.com/go/compute/metadata" 解决: mkdir $GOPATH/src/cloud ...

  10. cinder migrate基础内容-1

    一.卷迁移rest api接口 POST /v2/{project_id}/volumes/{volume_id}/action 迁移一个卷到特定的主机,在请求体中指定 os-migrate_volu ...