• 聊聊logback的DuplicateMessageFilter


    本文主要研究一下logback的DuplicateMessageFilter

    TurboFilter

    ch/qos/logback/classic/turbo/TurboFilter.java

    public abstract class TurboFilter extends ContextAwareBase implements LifeCycle {
    
        private String name;
        boolean start = false;
    
        /**
         * Make a decision based on the multiple parameters passed as arguments. The
         * returned value should be one of {@link FilterReply#DENY},
         * {@link FilterReply#NEUTRAL}, or
         * {@link FilterReply#ACCEPT}.
         * 
         * @param marker
         * @param logger
         * @param level
         * @param format
         * @param params
         * @param t
         * @return
         */
        public abstract FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params,
                Throwable t);
    
        public void start() {
            this.start = true;
        }
    
        public boolean isStarted() {
            return this.start;
        }
    
        public void stop() {
            this.start = false;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    • 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

    TurboFilter继承了ContextAwareBase,声明实现LifeCycle接口,它定义了decide方法由子类实现

    DuplicateMessageFilter

    ch/qos/logback/classic/turbo/DuplicateMessageFilter.java

    public class DuplicateMessageFilter extends TurboFilter {
    
        /**
         * The default cache size.
         */
        public static final int DEFAULT_CACHE_SIZE = 100;
        /**
         * The default number of allows repetitions.
         */
        public static final int DEFAULT_ALLOWED_REPETITIONS = 5;
    
        public int allowedRepetitions = DEFAULT_ALLOWED_REPETITIONS;
        public int cacheSize = DEFAULT_CACHE_SIZE;
    
        private LRUMessageCache msgCache;
    
        @Override
        public void start() {
            msgCache = new LRUMessageCache(cacheSize);
            super.start();
        }
    
        @Override
        public void stop() {
            msgCache.clear();
            msgCache = null;
            super.stop();
        }
    
        @Override
        public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
            int count = msgCache.getMessageCountAndThenIncrement(format);
            if (count <= allowedRepetitions) {
                return FilterReply.NEUTRAL;
            } else {
                return FilterReply.DENY;
            }
        }
    
        public int getAllowedRepetitions() {
            return allowedRepetitions;
        }
    
        /**
         * The allowed number of repetitions before
         * 
         * @param allowedRepetitions
         */
        public void setAllowedRepetitions(int allowedRepetitions) {
            this.allowedRepetitions = allowedRepetitions;
        }
    
        public int getCacheSize() {
            return cacheSize;
        }
    
        public void setCacheSize(int cacheSize) {
            this.cacheSize = cacheSize;
        }
    
    }
    
    • 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
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    DuplicateMessageFilter继承了TurboFilter,它使用了LRUMessageCache(默认大小100)来缓存format,decide方法会执行getMessageCountAndThenIncrement,若超出allowedRepetitions(默认5)则返回FilterReply.DENY,否则返回FilterReply.NEUTRAL

    LRUMessageCache

    ch/qos/logback/classic/turbo/LRUMessageCache.java

    class LRUMessageCache extends LinkedHashMap {
    
        private static final long serialVersionUID = 1L;
        final int cacheSize;
    
        LRUMessageCache(int cacheSize) {
            super((int) (cacheSize * (4.0f / 3)), 0.75f, true);
            if (cacheSize < 1) {
                throw new IllegalArgumentException("Cache size cannot be smaller than 1");
            }
            this.cacheSize = cacheSize;
        }
    
        int getMessageCountAndThenIncrement(String msg) {
            // don't insert null elements
            if (msg == null) {
                return 0;
            }
    
            Integer i;
            // LinkedHashMap is not LinkedHashMap. See also LBCLASSIC-255
            synchronized (this) {
                i = super.get(msg);
                if (i == null) {
                    i = 0;
                } else {
                    i = i + 1;
                }
                super.put(msg, i);
            }
            return i;
        }
    
        // called indirectly by get() or put() which are already supposed to be
        // called from within a synchronized block
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return (size() > cacheSize);
        }
    
        @Override
        synchronized public void clear() {
            super.clear();
        }
    }
    
    • 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

    LRUMessageCache继承了LinkedHashMap,其初始size为cacheSize * (4.0f / 3),getMessageCountAndThenIncrement方法内部通过synchronized加锁获取指定msg的次数,不存在则设置为0,存在则递增;其removeEldestEntry方法判断size() > cacheSize

    小结

    DuplicateMessageFilter继承了TurboFilter,它使用了LRUMessageCache(默认大小100)来缓存format,decide方法会执行getMessageCountAndThenIncrement,若超出allowedRepetitions(默认5)则返回FilterReply.DENY,否则返回FilterReply.NEUTRAL。

  • 相关阅读:
    android 记录Activity和Fragment生命周期顺序
    Java常用17个工具类方法,提升开发效率的“轮子”,避免重复造轮子
    【计算机网络】数据链路层(四)—— 局域网的基本概念和体系结构
    融云直播 SDK 玩法翻新,入围信通院「实时互动创新应用优秀案例」
    文献速递:GAN医学影像合成--用生成对抗网络生成 3D TOF-MRA 体积和分割标签
    linux服务器基本操作
    电阻值的优先值
    学习笔记【Java 虚拟机③】类加载与字节码技术
    彻底删除的文件如何恢复?一个方案,解决烦恼
    Matlab中Jet 的HeatMap的 color值分别都是多少?
  • 原文地址:https://blog.csdn.net/hello_ejb3/article/details/134369797