动态替换logback FileAppender/RollingFileAppender 配置- Programmatically configure logback FileAppender/RollingBackAppender

一、本文实际解决的问题

如何在代码中修改logback的RollingFileAppender配置(本文代码实例为修改日志文件路径)

二、针对的场景:

本文解决的问题属于一个大需求的一部分,需求为:需要特殊处理的请求的相关日志,需要与正常日志分开打印;同时不能去推动全公司应用修改代码,这样成本过高,尽量通过引入二方包解决问题

本文主要介绍获取Logger之后如何修改Logger配置,实现日志输出到别的路径

三、logback logger结构简述

动态替换logback FileAppender/RollingFileAppender 配置- Programmatically configure logback FileAppender/RollingBackAppender

四、实现流程

1、获取Logger

private static Logger logger = LoggerFactory.getLogger(TaskHistoryService.class);

2、获取所有Appender

// 获取从logger到RootLogger的所有appenders
    public static ArrayList<Appender> getAppendersTraversal(Logger logger){
        Logger parent = logger;
        ArrayList<Appender> result = new ArrayList<>();
        while(parent != null){
            ArrayList<Appender> tempResult = getAppenders(parent);
            if (tempResult != null){
                result.addAll(tempResult);
            }

            parent = getParent(parent);
        }
        return result;
    }

// 获取logger中的appenders
    public static ArrayList<Appender> getAppenders(Logger logger){
        AppenderAttachableImpl<ILoggingEvent> aai;
        ArrayList<Appender> fileAppenders = new ArrayList<>();
        try {
            Class<?> clazz = ch.qos.logback.classic.Logger.class;
            Field aaiField = clazz.getDeclaredField("aai");
            aaiField.setAccessible(true);
            AppenderAttachableImpl<ILoggingEvent> markedAai;
            aai =  (AppenderAttachableImpl<ILoggingEvent>)aaiField.get(logger);
            if (aai == null){
                return null;
            }
            Iterator<Appender<ILoggingEvent>> aaiIterator = aai.iteratorForAppenders();
            while (aaiIterator.hasNext()){
                Appender<ch.qos.logback.classic.spi.ILoggingEvent> appender = aaiIterator.next();
                fileAppenders.add(appender);
            }
            return fileAppenders;
        } catch (NoSuchFieldException e){
            e.printStackTrace();
            return fileAppenders;
        } catch (IllegalAccessException e){
            e.printStackTrace();
            return fileAppenders;
        }
    }
    
// 获取logger的parent logger
    public static Logger getParent(Logger logger) {
        Class<?> clazz = ch.qos.logback.classic.Logger.class;
        try {
            Field parentField = clazz.getDeclaredField("parent");
            parentField.setAccessible(true);
            Logger parent = (Logger)parentField.get(logger);
            return parent;
        } catch (NoSuchFieldException e){
            e.printStackTrace();
            return null;
        } catch (IllegalAccessException e){
            e.printStackTrace();
            return null;
        }
    }

3、获取RollingFileAppender

public static RollingFileAppender getRollingFileAppender(Appender appender){
        if (appender instanceof RollingFileAppender){
            return (RollingFileAppender)appender;
        }
        return null;
    }

4、更新Policy

private static RollingFileAppender updateRollingPolicyToMark(RollingFileAppender rollingFileAppender, String newFile, String newPattern){
        RollingPolicy rollingPolicy = rollingFileAppender.getRollingPolicy();
        TriggeringPolicy triggeringPolicy = rollingFileAppender.getTriggeringPolicy();
        RollingPolicyBase rollingPolicyBase = (RollingPolicyBase)rollingPolicy;
        rollingPolicyBase.setFileNamePattern(newPattern);

        // stop all:appender + policy
        stopRollingFileAppender(rollingFileAppender);
        // set fileName
        setFileName(rollingFileAppender, newFile);
        // start
        startRollingFileAppender(rollingFileAppender);

        return rollingFileAppender;
    }

    private static void stopRollingFileAppender(RollingFileAppender rollingFileAppender){
        rollingFileAppender.stop();
    }

    private static void startRollingFileAppender(RollingFileAppender rollingFileAppender){
        rollingFileAppender.getTriggeringPolicy().start();
        rollingFileAppender.getRollingPolicy().start();
        rollingFileAppender.start();
    }

    private static void setFileName(RollingFileAppender rollingFileAppender, String fileName){
        RollingPolicy rollingPolicy = rollingFileAppender.getRollingPolicy();
        TriggeringPolicy triggeringPolicy = rollingFileAppender.getTriggeringPolicy();
        // remove policy
        rollingFileAppender.setRollingPolicy(null);
        rollingFileAppender.setTriggeringPolicy(null);

        // set fileName
        rollingFileAppender.setFile(fileName);

        // set policy
        rollingFileAppender.setRollingPolicy(rollingPolicy);
        rollingFileAppender.setTriggeringPolicy(triggeringPolicy);
    }

动态替换logback FileAppender/RollingFileAppender 配置- Programmatically configure logback FileAppender/RollingBackAppender

上一篇:读写App.config配置文件的方法


下一篇:2018-2019-2 20175311 实验四《Android开发基础》实验报告