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
logback1.11的一个bug:有线程持续不断写入log文件,log文件就不会按设定以日期切换。的更多相关文章
- 同样是logback1.11,更换了log配置后,无论是否有线程持续不断写入log文件,log文件会按设定以日期序号轮换
上次发现了logback1.11的一个bug,即有线程持续写入log,则log文件不会按设定模式进行轮换. 但发现同样采用logback1.11的另外一个工程,它的日志文件就没有错误,于是参照其配置文 ...
- 医生加号页改版,就一个Bug, 看医生工作台一期需求
8/8日报 分级埋点: [MobClick event:UmengPagePlusDoctor attributes:@{@"page":@"plusPage&q ...
- AIX6.1/11.2.0.3在有关数据库SWAP一个BUG
昨天南京到客户服务数据库的优化调整,其中新上线,经过审查alert.log当日志现在是在过去一段时间内取得,每隔几个小时的时间滞后,班会报似的内容: Thu Aug 21 09:01:26 2014 ...
- 使用C++11实现一个半同步半异步线程池
前言 C++11之前我们使用线程需要系统提供API.posix线程库或者使用boost提供的线程库,C++11后就加入了跨平台的线程类std::thread,线程同步相关类std::mutex.std ...
- C++11中一个使用for+auto时容易发生的bug
C++11中一个使用for+auto时容易发生的bug 一个小坑,那就是忘记在for循环中使用auto时加引用. 例如: for(auto num : nums){ // do some thing ...
- 一个代价11万的bug
这个bug不是技术bug或者是程序bug,是典型的业务操作bug. 开发人员混淆了线上数据和本地测试数据,把线上数据切换到本地的数据做测试,结果对这些客户进行了资金调整...就导致了这个悲剧发生 早在 ...
- 我是一个Bug, 终极大Bug
我是一个Bug ,在这个系统中潜伏很久了,历经多轮测试的严酷考验而屹立不倒,如果Bug界按难度分类的话,我绝对属于地狱模式. 现在,我就等待一个倒霉蛋来触发, 可是他老是不来. 其实不能叫倒霉蛋 , ...
- 《一个 Go 程序系统线程暴涨的问题》结论
原文地址:https://zhuanlan.zhihu.com/p/22474724 作者的结论没写好,我来说两句.. 结论: Docker swarm自己有个函数,叫setTcpUserTimeou ...
- 关于MySQL count(distinct) 逻辑的一个bug【转】
本文来自:http://dinglin.iteye.com/blog/1976026#comments 背景 客户报告了一个count(distinct)语句返回结果错误,实际结果存在值,但是用cou ...
随机推荐
- C++ 的字符串反转
C++ 的字符串反转 方法一: 使用 algorithm 中的 reverse 函数: // reverse 函数的定义(在 std 名称空间中) template<class BidirIt& ...
- C#LeetCode刷题-设计
设计篇 # 题名 刷题 通过率 难度 146 LRU缓存机制 33.1% 困难 155 最小栈 C#LeetCode刷题之#155-最小栈(Min Stack) 44.9% 简单 173 二叉搜索 ...
- noip复习——逆元
逆元,即对给定\(a,p\ (a \perp p)\),求\(x\)使得\(ax \equiv 1 \ (\bmod p)\) 逆元可以看做\(a\)在模\(p\)意义下的\(a^{-1}\).因此, ...
- .netcore tif文件转jpg,并通过webapi返回
网上能搜到很多关于c# tif转jpg的代码.最简单的就是下面这段获得转换后的图片图片对象.在netcore 中使用这段代码时由于netcore框架已经不自带System.Drawing命名空间了所有 ...
- 浏览器自动化的一些体会6 增强的webBrowser控件
这里谈两点 1.支持代理服务器切换 一种方法是修改注册表,不是太好的做法,而且,只能改全局设置,不能改局部(比如只让当前的webBrowser控件使用代理,而其他应用不用代理) 另外一个较好的方法,示 ...
- Scala中的Map集合
1. Map集合 1.1 Scala中的Map介绍 Scala中的Map 和Java类似,也是一个散列表,它存储的内容也是键值对(key-value)映射,Scala中不可变的Map是有序的,可变的M ...
- 什么?Java9这些史诗级更新你都不知道?Java9特性一文打尽!
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- HMM隐马尔可夫模型来龙去脉(一)
目录 隐马尔可夫模型HMM学习导航 一.认识贝叶斯网络 1.概念原理介绍 2.举例解析 二.马尔可夫模型 1.概念原理介绍 2.举例解析 三.隐马尔可夫模型 1.概念原理介绍 2.举例解析 四.隐马尔 ...
- cannot find package "cloud.google.com/go/compute/metadata"
问题: cannot find package "cloud.google.com/go/compute/metadata" 解决: mkdir $GOPATH/src/cloud ...
- cinder migrate基础内容-1
一.卷迁移rest api接口 POST /v2/{project_id}/volumes/{volume_id}/action 迁移一个卷到特定的主机,在请求体中指定 os-migrate_volu ...