• logback 指定每隔一段时间创建一个日志文件


    我使用的logback版本是1.2.3

    目前logback支持根据时间来配置产生日志文件,但是只支持每周,每天,每个小时,每分钟等创建一个文件,配置如下:

    <appender name="SYSTEM"
            class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${log.home}/system.log</file>
    
            <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- daily rollover ,每天生成一份日志文件-->
                <fileNamePattern>${log.home}/system.%d{yyyy-MM-dd}.log
                </fileNamePattern>
                <maxHistory>7</maxHistory>
            </rollingPolicy>
    
            <encoder>
                <pattern>%d{HH:mm:ss} %-5level [%thread][%file:%line] : %msg%n
                </pattern>
            </encoder>
        </appender>

    但是需求是无法想象的,像突然又要求每隔一段时间之后生成一个配置文件,比如logback每隔10分钟生成一个日志文件,或每隔30分钟生成一份日志文件,每隔2个小时生成一个日志配置文件等。

    下面以每隔10分钟生成一个日志文件,首先看一个每分钟生成一个配置文件 的配置

    <appender name="SYSTEM"
            class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${log.home}/system.log</file>
    
            <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- daily rollover ,每天分钟生成一份日志文件-->
                <fileNamePattern>${log.home}/system.%d{yyyy-MM-dd-HH-mm}.log
                </fileNamePattern>
                <maxHistory>7</maxHistory>
            </rollingPolicy>
    
            <encoder>
                <pattern>%d{HH:mm:ss} %-5level [%thread][%file:%line] : %msg%n
                </pattern>
            </encoder>
        </appender>

    但是发现在配置中,没有指定每隔多长时间来生成一个配置文件,没办法,只能看源码,加百度了。首先看配置里面的

    <rollingPolicy  class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    TimeBasedRollingPolicy 这个类就是日志文件生成的策略类,看它的源码

    再看这个timeBasedFileNamingAndTriggeringPolicy触发策略,在ch.qos.logback.core.rolling.TimeBasedRollingPolicy类的start方法中有这样一段代码

            if (timeBasedFileNamingAndTriggeringPolicy == null) {
                timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<E>();
            }

    这说明timeBasedFileNamingAndTriggeringPolicy是可以被外部设置的,如果没有设置刚使用默认的实现。我们再看DefaultTimeBasedFileNamingAndTriggeringPolicy,这里面的判断是否触发 写日志的方法:

     public boolean isTriggeringEvent(File activeFile, final E event) {
            long time = getCurrentTime();
            if (time >= nextCheck) {
                Date dateOfElapsedPeriod = dateInCurrentPeriod;
                addInfo("Elapsed period: " + dateOfElapsedPeriod);
                elapsedPeriodsFileName = tbrp.fileNamePatternWithoutCompSuffix.convert(dateOfElapsedPeriod);
                setDateInCurrentPeriod(time);
                computeNextCheck();
                return true;
            } else {
                return false;
            }
        }

    这里面有一个比较即time> nextCheck,如果当前时间大于下一个判断时间,则触 发生成日志,这里面有一个计算NextCheck时间的方法:computeNextCheck();

        protected void computeNextCheck() {
            nextCheck = rc.getNextTriggeringDate(dateInCurrentPeriod).getTime();
        }

    再看这个方法:rc.getNextTriggeringDate,根据它最终可以找到:

     public Date getEndOfNextNthPeriod(Date now, int periods) {
            return innerGetEndOfNextNthPeriod(this, this.periodicityType, now, periods);
        }
    
        public Date getNextTriggeringDate(Date now) {
            return getEndOfNextNthPeriod(now, 1);
        }

    它最终还是调用的 public Date getEndOfNextNthPeriod(Date now, int periods)方法,我们可以看到之前说的每小时,每分钟,都是这里调用的是

    getEndOfNextNthPeriod(now, 1); 如果我们想实现每2小时,每10分钟的话,只需要调用
    getEndOfNextNthPeriod(now, 2); 或getEndOfNextNthPeriod(now, 10);至于是小时还是分钟,是由这个innerGetEndOfNextNthPeriod方法时里面判断的,是根据你的配置文件生成的PeriodicityType决定的。那我们要实现自己的每隔n段时间之后生成一个配置文件,只需要实现一个自己的类即可

    package com.common.log;
    
    import ch.qos.logback.core.joran.spi.NoAutoStart;
    import ch.qos.logback.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy;
    
    @NoAutoStart
    public class MyTimeBasedFileNamingAndTriggeringPolicy<E> extends DefaultTimeBasedFileNamingAndTriggeringPolicy<E> {
       //这个用来指定时间间隔 
    private Integer multiple = 1; @Override protected void computeNextCheck() { nextCheck = rc.getEndOfNextNthPeriod(dateInCurrentPeriod, multiple).getTime(); } public Integer getMultiple() { return multiple; } public void setMultiple(Integer multiple) { if (multiple > 1) { this.multiple = multiple; } } }

    对应的配置如下:

    <appender name="SYSTEM"
            class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${log.home}/system.log</file>
    
            <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- daily rollover ,每10分钟生成一份日志文件-->
                <fileNamePattern>${log.home}/system.%d{yyyy-MM-dd-HH-mm}.log
                </fileNamePattern>

                  <timeBasedFileNamingAndTriggeringPolicy

                   class="com.common.log.MyTimeBasedFileNamingAndTriggeringPolicy">

                   <multiple>10</multiple>

                    </timeBasedFileNamingAndTriggeringPolicy>

                <maxHistory>7</maxHistory>
            </rollingPolicy>
    
            <encoder>
                <pattern>%d{HH:mm:ss} %-5level [%thread][%file:%line] : %msg%n
                </pattern>
            </encoder>
        </appender>

     儿童三轮车1--3童车,送给孩子的礼物


    以上配置即可实现每隔10分钟创建一个日志文件。需要注意的是,日志文件只有在有日志写入时才会判断是否创建一个新的日志文件,如果只是启动服务器,会创建一个当前时间的日志文件 ,如果一直没有日志写入,10分钟之后也不会自动创建日志文件。只有在日志数据写入时才创建。

  • 相关阅读:
    Thrift安装编译指南
    Linux磁盘与文件系统管理
    你懂得C,所以C++也不在话下
    加速NFV(网络功能虚拟化)数据面:SR-IOV和DPDK[原文意译]
    十张图看懂SDN与NFV的区别与联系?
    Lambda表达式用法
    论文写作+gnuplot制图
    私钥、公钥、数字签名和数字证书
    synchronized和Lock的异同
    介绍HTTP协议的传输过程
  • 原文地址:https://www.cnblogs.com/wgslucky/p/10026322.html
Copyright © 2020-2023  润新知