• 源码:
    1. logback-test.xml文件如下,有2个需要我们重点关注的参数:
      1. fileNamePattern:这里的日志文件名变动的部分是年月日时,外加1个文件分割自增变量,警告,年月日时的数值依赖于系统时间,自增变量依赖logback框架里运行时的内存变量。
      2. maxFileSize:这里日志文件分割的条件为日志文件大小达到1M。
        <?xml version="1.0" encoding="UTF-8"?>
        <configuration>
        <appender name="testLog"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- 我们的日志文件名变动的部分是年月日时,外加1个分割自增变量 -->
        <fileNamePattern>test-log.%d{yyyy-MM-dd-HH}.%i.log</fileNamePattern>
        <!-- 保存历史文件的个数 每产生一个日志文件,该日志文件的保存期限为 7天 -->
        <maxHistory>168</maxHistory>
        <timeBasedFileNamingAndTriggeringPolicy
        class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>1MB</maxFileSize><!-- 日志文件分割的条件为日志文件大小达到1M -->
        </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
        <!-- pattern节点,用来设置日志的输入格式 -->
        <pattern>
        %d{HH:mm:SSS} %p [%thread] (%file:%line\)- %m%n
        </pattern>
        <!-- 记录日志的编码 -->
        <charset>UTF-8</charset>
        </encoder>
        </appender> <root level="debug">
        <appender-ref ref="testLog" />
        </root>
        </configuration>
    2. 输出日志的源码如下,需要注意的是:
      1. 我们用while循环输出日志,比正常的日志输出强度高许多;
      2. 我们的日志内容是"Hello logback, line "+i。
        package demo.logback;
        
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory; public class LogFileCut { public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger("demo.logback.LogFileCut");
        int i = 0;
        while(i < 100000) {
        logger.debug("Hello logback, line ++++++ "+i);
        i++;
        }
        }
        }
  • 根据源码:
    1. 第一步,我们现在要输出10万条日志到日志文件当中,每个文件大小为1MB,如图:
      可以看到,实际的文件大小是不确定的1142KB,1152KB,都大于1MB,最后一个日志文件因为还没有填满而小于1MB。这是我们要弄明白的第一个问题,为什么日志文件大小实际上大于我们设定的上限值
    2. 第二步,因为我们是用main方法输出日志,我们再运行一遍就相当于服务器重启一遍,这个时候我们把日志输出内容换成,“Hello logback, line ++++++”+i。<br/运行结果如图:
      1. 先看文件数量,循环次数相同,新增的日志文件数量是6个,前面0~6个文件是第一步里运行得到的,后面的7~12是这次生成的。
      2. 对比两张图里前面7个文件0~6,6号分割文件大小发生变化我们容易理解,但是0~5这6个文件怎么都增加了,这是我们要回答的第二个问题?
  • logback日志分割问题分析:
    • 第一个问题:为什么日志分割实际大小大于设定的上限值?

      • 证据:如上图。
      • 原因分析:
        • 一个日志文件分割时,有两个操作:
          1. 比较当前日志文件与设定值的大小,判断是否分割
          2. 只要还未完成分割,持续向当前日志文件写入日志。
            当你还在比较的时候,我已经输出几百米了。。。行。。。。
        • 当判断出日志文件大小已经达到预定值的瞬间,日志文件还未进行分割,而此时日志文件仍然被写入日志。故正常情况下,日志文件的实际大小通常要大于设定值的大小。
        • 超出多少:日志文件实际超出预定值的大小size,基本上取决于判定出日志文件大小达到临界值的时间点zeroPoint以后,日志记录的写入相对于日志文件创建的速度。
        • 通常来说,日志在代码中的输出越频繁,超出临界值越多(我们这里的循环输出日志,强度是很大的)。
        • 诡谲:JIT在作祟?多次重复以上的单个步骤,观察日志分割文件大小,我们不难发现,日志文件列表的开头几个文件总是比后面的日志文件要小一些。换句话说,运行时的日志输出速度发生了变化,我猜想这里极有可能是因为while循环被JIT编译器检测到为热点代码,所以进行了再编译,从而使日志的输出速度变得更快,导致后面的日志文件更大些。
    • 第二个问题:为什么“重启”后,原本应该锁定的日志文件,再次被输入日志?
      • 证据:检查0~6号文件的末尾,我们都可以发现“Hello logback, line ++++++”+i,这段记录的存在。也就是说,“重启”之前的、按理说已经“满格”达到上限值日志文件,在“重启”后,发生了日志再次写入的问题。
      • 原因分析:
        • 日志名称:test-log.2018-08-14-13.0.log。文件名称精确到小时,我们“重启”前后,都是在同一天的13点!
          1. 日志名称的变化依赖于时间,以及分割序号,时间由操作系统决定,分割序号由logback框架决定。分割序号对应的变量值是没有持久化的!一旦重启,就只能重头开始,所以在同一个时间段(这里是同一天的同一个小时)里发生重启,不会新建日志文件,而是在原有的日志里追加记录;
          2. 第一个问题里已经说了,日所以志文件在比较的时候(还未比较完成时),仍然在进行日志输出,所以日志文件会变大。

logback框架之——日志分割所带来的潜在问题的更多相关文章

  1. java日志框架系列(2):logback框架详解

    1.logback介绍 1.什么是logback Logback 为取代 log4j 而生. Logback 由 log4j 的创立者 Ceki Gülcü设计.以十多年设计工业级记录系统的经验为基础 ...

  2. java日志框架系列(4):logback框架xml配置文件语法

    1.xml配置文件语法 由于logback配置文件语法特别灵活,因此无法用DTD或schema进行定义. 1.配置文件基本结构 配置文件基本结构:以<configuration>标签开头, ...

  3. java日志框架系列(3):logback框架配置详解

    1.Logback配置 1.配置步骤及默认配置 logback即可以通过编程式配置,也可以通过xml的形式配置. logback配置步骤: 1. 尝试在 classpath 下查找文件 logback ...

  4. java日志框架与日志系统

    日志框架:提供日志调用的接口,实际的日志输出委托给日志系统实现. JCL(Jakarta Commons Logging):比较流行的日志框架,很多框架都依赖JCL,例如Spring等. SLF4j: ...

  5. spring+mybatis+mina+logback框架搭建

    第一次接触spring,之前从来没有学过spring,所以算是赶鸭子上架,花了差不多一个星期来搭建,中间遇到各种各样的问题,一度觉得这个框架搭建非常麻烦,没有一点技术含量,纯粹就是配置,很低级!但随着 ...

  6. ELK+Logback进行业务日志分析查看

    第1章 Elasticsearch安装部署 1.1 下载软件包并创建工作目录 程序下载地址:https://artifacts.elastic.co/downloads/elasticsearch/e ...

  7. nginx 直接在配置文章中设置日志分割

    直接在nginx配置文件中,配置日志循环,而不需使用logrotate或配置cron任务.需要使用到$time_iso8601 内嵌变量来获取时间.$time_iso8601格式如下:2015-08- ...

  8. apache2.4配置访问日志分割并过滤图片CSS等无用内容

    相关信息 1.apache日志有访问日志和错误日志,错误日志根据日志级别来输出错误信息,而访问日志根据定义的日志格式来记录访问动作 2.访问日志格式在httpd.conf文件里面定义,在虚拟主机里面引 ...

  9. Nginx常用日志分割方法

    方式一: nginx cronolog日志分割配置文档,根据下面方法,每分钟分割一次NGINX访问日志. 1.nginx日志配置 access_log /var/log/nginx/access.lo ...

随机推荐

  1. [matlab] 4.M函数

    函数文件的编写 新建一个函数文件 函数的第一行的格式 :function [输出的参数] =函数名 (输入的参数) 输入和输出的参数可以有多个 保存函数文件的时候,注意文件名要和函数名一样 函数头和函 ...

  2. Spring Cloud Config(配置中心)

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 一.简介 Spring Cloud Config为分布式系统中的外部配置提供服务器和客 ...

  3. Python:Day16 闭包、装饰器

    def outer(): x = 10 def inner(): #条件一.inner就是一个内部函数 print(x) #条件二.引用外部作用域的一个变量,因为x在函数外部的,所以是外部作用域的变量 ...

  4. Python socket之tftp协议

    1. TFTP协议介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议) 是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文件传输的协议 特点: ...

  5. rman list 命令列举

    转 在使用RMAN备份.还原的过程中,我们经常需要查看备份的一些详细信息,例如,RMAN提供了LIST命令.关于LIST命令的详细信息 可以参考Oracle Database Backup and R ...

  6. python内建的命名空间研究

    python内建的命名空间研究 说明: python内置模块的命名空间.python在启动的时候会自动为我们载入很多内置的函数.类,比如 dict,list,type,print,这些都位于 __bu ...

  7. iOS开发简记(9):APPStore审核

    "觅知音"这个APP的第一个版本从提交审核到上架,历时三个星期,其中遇到一些审核上的问题,它的处理或许能帮助到遇到同样问题的小伙伴们,所以这里列举出来,这三个星期如何跟苹果的审核团 ...

  8. iOS开发简记(8):数据持久化

    数据持久化,也就是把数据保存到磁盘,以后可以再读取出来使用(也可以再次更改或删除).很多场景需要数据持久化,比如为了减轻服务器的访问与存储压力,客户端需要在本地做一些数据持久化的工作. iOS的数据持 ...

  9. WPF仿网易云音乐系列(序)

    1.简介 由于之前做了一个播放器,苦于不懂界面设计,只得去借鉴借鉴一些成功的作品,网易云音乐就甚合朕心,哈哈,最后做出来的效果如下: 本系列文章就来和大家讨论以下,如何用WPF去仿制一个网易云音乐来: ...

  10. 朱晔的互联网架构实践心得S1E2:屡试不爽的架构三马车

    朱晔的互联网架构实践心得S1E2:屡试不爽的架构三马车 [下载本文PDF进行阅读] 这里所说的三架马车是指微服务.消息队列和定时任务.如下图所示,这里是一个三驾马车共同驱动的一个立体的互联网项目的架构 ...