• 聊聊logback的FixedWindowRollingPolicy


    本文主要研究一下logback的FixedWindowRollingPolicy

    RollingPolicy

    ch/qos/logback/core/rolling/RollingPolicy.java

    /**
     * A RollingPolicy is responsible for performing the rolling over
     * of the active log file. The RollingPolicy is also responsible
     * for providing the active log file, that is the live file where
     * logging output will be directed.
     * 
     * @author Ceki Gülcü
     */
    public interface RollingPolicy extends LifeCycle {
    
        /**
         * Rolls over log files according to implementation policy.
         * 
         * 

    * This method is invoked by {@link RollingFileAppender}, usually at the behest * of its {@link TriggeringPolicy}. * * @throws RolloverFailure Thrown if the rollover operation fails for any * reason. */ void rollover() throws RolloverFailure; /** * Get the name of the active log file. * *

    * With implementations such as {@link TimeBasedRollingPolicy}, this method * returns a new file name, where the actual output will be sent. * *

    * On other implementations, this method might return the FileAppender's file * property. */ String getActiveFileName(); /** * The compression mode for this policy. * * @return */ CompressionMode getCompressionMode(); /** * This method allows RollingPolicy implementations to be aware of their * containing appender. * * @param appender */ void setParent(FileAppender appender); }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    RollingPolicy接口定义了rollover、getActiveFileName、getCompressionMode、setParent方法

    RollingPolicyBase

    ch/qos/logback/core/rolling/RollingPolicyBase.java

    /**
     * Implements methods common to most, it not all, rolling policies. Currently
     * such methods are limited to a compression mode getter/setter.
     * 
     * @author Ceki Gülcü
     */
    public abstract class RollingPolicyBase extends ContextAwareBase implements RollingPolicy {
        protected CompressionMode compressionMode = CompressionMode.NONE;
    
        FileNamePattern fileNamePattern;
        // fileNamePatternStr is always slashified, see setter
        protected String fileNamePatternStr;
    
        private FileAppender parent;
    
        // use to name files within zip file, i.e. the zipEntry
        FileNamePattern zipEntryFileNamePattern;
        private boolean started;
    
        /**
         * Given the FileNamePattern string, this method determines the compression mode
         * depending on last letters of the fileNamePatternStr. Patterns ending with .gz
         * imply GZIP compression, endings with '.zip' imply ZIP compression. Otherwise
         * and by default, there is no compression.
         * 
         */
        protected void determineCompressionMode() {
            if (fileNamePatternStr.endsWith(".gz")) {
                addInfo("Will use gz compression");
                compressionMode = CompressionMode.GZ;
            } else if (fileNamePatternStr.endsWith(".zip")) {
                addInfo("Will use zip compression");
                compressionMode = CompressionMode.ZIP;
            } else {
                addInfo("No compression will be used");
                compressionMode = CompressionMode.NONE;
            }
        }
    
        //......
    }    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    RollingPolicyBase定义了compressionMode、fileNamePattern、fileNamePatternStr、parent、zipEntryFileNamePattern、started;
    determineCompressionMode方法会根据fileNamePatternStr的后缀来判断,默认支持gz、zip

    FixedWindowRollingPolicy

    ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java

    public class FixedWindowRollingPolicy extends RollingPolicyBase {
        static final String FNP_NOT_SET = "The \"FileNamePattern\" property must be set before using FixedWindowRollingPolicy. ";
        static final String PRUDENT_MODE_UNSUPPORTED = "See also " + CODES_URL + "#tbr_fnp_prudent_unsupported";
        static final String SEE_PARENT_FN_NOT_SET = "Please refer to " + CODES_URL + "#fwrp_parentFileName_not_set";
        int maxIndex;
        int minIndex;
        RenameUtil util = new RenameUtil();
        Compressor compressor;
    
        public static final String ZIP_ENTRY_DATE_PATTERN = "yyyy-MM-dd_HHmm";
    
        /**
         * It's almost always a bad idea to have a large window size, say over 20.
         */
        private static int MAX_WINDOW_SIZE = 20;
    
        public FixedWindowRollingPolicy() {
            minIndex = 1;
            maxIndex = 7;
        }
    
        //......
    }    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    FixedWindowRollingPolicy继承了RollingPolicyBase,他定义了minIndex、maxIndex、compressor属性

    start

        public void start() {
            util.setContext(this.context);
    
            if (fileNamePatternStr != null) {
                fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
                determineCompressionMode();
            } else {
                addError(FNP_NOT_SET);
                addError(CoreConstants.SEE_FNP_NOT_SET);
                throw new IllegalStateException(FNP_NOT_SET + CoreConstants.SEE_FNP_NOT_SET);
            }
    
            if (isParentPrudent()) {
                addError("Prudent mode is not supported with FixedWindowRollingPolicy.");
                addError(PRUDENT_MODE_UNSUPPORTED);
                throw new IllegalStateException("Prudent mode is not supported.");
            }
    
            if (getParentsRawFileProperty() == null) {
                addError("The File name property must be set before using this rolling policy.");
                addError(SEE_PARENT_FN_NOT_SET);
                throw new IllegalStateException("The \"File\" option must be set.");
            }
    
            if (maxIndex < minIndex) {
                addWarn("MaxIndex (" + maxIndex + ") cannot be smaller than MinIndex (" + minIndex + ").");
                addWarn("Setting maxIndex to equal minIndex.");
                maxIndex = minIndex;
            }
    
            final int maxWindowSize = getMaxWindowSize();
            if ((maxIndex - minIndex) > maxWindowSize) {
                addWarn("Large window sizes are not allowed.");
                maxIndex = minIndex + maxWindowSize;
                addWarn("MaxIndex reduced to " + maxIndex);
            }
    
            IntegerTokenConverter itc = fileNamePattern.getIntegerTokenConverter();
    
            if (itc == null) {
                throw new IllegalStateException(
                        "FileNamePattern [" + fileNamePattern.getPattern() + "] does not contain a valid IntegerToken");
            }
    
            if (compressionMode == CompressionMode.ZIP) {
                String zipEntryFileNamePatternStr = transformFileNamePatternFromInt2Date(fileNamePatternStr);
                zipEntryFileNamePattern = new FileNamePattern(zipEntryFileNamePatternStr, context);
            }
            compressor = new Compressor(compressionMode);
            compressor.setContext(this.context);
            super.start();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    start方法先根据fileNamePattern来创建FileNamePattern,然后判断压缩模式,然后校验minIndex及maxIndex,要求相差不能超过MAX_WINDOW_SIZE(默认值为20),之后判断如果是zip模式的则创建zipEntryFileNamePattern,最后根据压缩模式创建compressor

    rollover

        public void rollover() throws RolloverFailure {
    
            // Inside this method it is guaranteed that the hereto active log file is
            // closed.
            // If maxIndex <= 0, then there is no file renaming to be done.
            if (maxIndex >= 0) {
                // Delete the oldest file, to keep Windows happy.
                File file = new File(fileNamePattern.convertInt(maxIndex));
    
                if (file.exists()) {
                    file.delete();
                }
    
                // Map {(maxIndex - 1), ..., minIndex} to {maxIndex, ..., minIndex+1}
                for (int i = maxIndex - 1; i >= minIndex; i--) {
                    String toRenameStr = fileNamePattern.convertInt(i);
                    File toRename = new File(toRenameStr);
                    // no point in trying to rename a nonexistent file
                    if (toRename.exists()) {
                        util.rename(toRenameStr, fileNamePattern.convertInt(i + 1));
                    } else {
                        addInfo("Skipping roll-over for inexistent file " + toRenameStr);
                    }
                }
    
                // move active file name to min
                switch (compressionMode) {
                case NONE:
                    util.rename(getActiveFileName(), fileNamePattern.convertInt(minIndex));
                    break;
                case GZ:
                    compressor.compress(getActiveFileName(), fileNamePattern.convertInt(minIndex), null);
                    break;
                case ZIP:
                    compressor.compress(getActiveFileName(), fileNamePattern.convertInt(minIndex),
                            zipEntryFileNamePattern.convert(new Date()));
                    break;
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    rollover方法从maxIndex-1开始到minIndex,把这些文件名的序号加1,之后根据压缩模式判断,如果不压缩则把当前文件名重名为minIndex,若是gz压缩则把当前文件压缩然后命名为minIndex,若是zip压缩则把当前文件压缩然后命名为minIndex加上日期

    小结

    logback的FixedWindowRollingPolicy继承了RollingPolicyBase,实现了RollingPolicy接口,该接口定义了rollover、getActiveFileName、getCompressionMode、setParent方法,其中FixedWindowRollingPolicy的rollover的实现是根据minIndex及maxIndex来的,要求maxIndex及minIndex相差不能超过20,rollover的时候从maxIndex-1开始到minIndex,把这些文件名的序号加1,然后当前文件重命名为minIndex,其中还配合压缩模式进行压缩处理。

  • 相关阅读:
    SSM之spring注解式缓存redis
    初始化 List<List<String>>
    前端初学日记 (四) VUE指令
    Java未分类面试知识
    使用Kubectl管理kubernetes集群
    金融计量学实验报告一
    Docker 数据管理
    DDT数据驱动
    好用移动APP自动化测试框架哪里找?收藏这份清单就好了!
    超图WMTS服务的几个关键参数
  • 原文地址:https://blog.csdn.net/hello_ejb3/article/details/134303044