聊聊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 <code>{@link FilterReply#DENY}</code>,
     * <code>{@link FilterReply#NEUTRAL}</code>, or
     * <code>{@link FilterReply#ACCEPT}</code>.
     * 
     * @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;
    }
}

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;
    }

}

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<String, Integer> {

    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<String, Integer> eldest) {
        return (size() > cacheSize);
    }

    @Override
    synchronized public void clear() {
        super.clear();
    }
}

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。

相关推荐
枫叶v.19 分钟前
Agent 分层存储架构设计:从记忆方法到中间件选型
开发语言·python
sleven fung2 小时前
MinerU与BabelDOC与KTransformers与OpenAI API库
开发语言·python·ai·langchain
萤萤七悬2 小时前
【Python笔记】AI帮实现CLI工具-使用argparse.ArgumentParser接收命令参数
开发语言·笔记·python
iCxhust2 小时前
C# 命令行指令 查看二进制文件
开发语言·单片机·嵌入式硬件·c#·proteus·微机原理·8088单板机
csdn_aspnet2 小时前
Java 霍尔分区算法(Hoare‘s Partition Algorithm)
java·开发语言·算法
诸葛务农2 小时前
道路行驶条件下电动汽车永磁电机的有效使用寿命及永磁体的失效和回收再利用(下)
java·开发语言·算法
oort1232 小时前
VLStream:全开源决策式AI视频平台,赋能企业构建自主可控、降本增效的智能视觉应用介绍
大数据·开发语言·人工智能·开源·音视频·数据库架构
c238563 小时前
c/c++中的多态(上)
开发语言·c++
彷徨而立3 小时前
【C++】介绍 std::ifstream 输入文件流
开发语言·c++
罗超驿3 小时前
13.JavaScript 新手入门指南:语法、变量、流程控制全解析
开发语言·javascript