前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊logback的addtivity属性

聊聊logback的addtivity属性

原创
作者头像
code4it
发布2023-11-30 08:57:22
5090
发布2023-11-30 08:57:22
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下logback的addtivity属性

LoggerModel

ch/qos/logback/classic/model/LoggerModel.java

代码语言:javascript
复制
@PhaseIndicator(phase = ProcessingPhase.SECOND)
public class LoggerModel extends Model {

    private static final long serialVersionUID = 5326913660697375316L;

    String name;
    String level;
    String additivity;

    //......
}    

LoggerModel定义了additivity属性

LoggerAction

ch/qos/logback/classic/joran/action/LoggerAction.java

代码语言:javascript
复制
public class LoggerAction extends BaseModelAction {

    @Override
    protected boolean validPreconditions(SaxEventInterpretationContext ic, String name, Attributes attributes) {
        PreconditionValidator validator = new PreconditionValidator(this, ic, name, attributes);
        validator.validateNameAttribute();
        return validator.isValid();
    }

    @Override
    protected Model buildCurrentModel(SaxEventInterpretationContext interpretationContext, String name,
            Attributes attributes) {

        LoggerModel loggerModel = new LoggerModel();

        String nameStr = attributes.getValue(NAME_ATTRIBUTE);
        loggerModel.setName(nameStr);

        String levelStr = attributes.getValue(JoranConstants.LEVEL_ATTRIBUTE);
        loggerModel.setLevel(levelStr);

        String additivityStr = attributes.getValue(JoranConstants.ADDITIVITY_ATTRIBUTE);
        loggerModel.setAdditivity(additivityStr);

        return loggerModel;
    }
}

LoggerAction的buildCurrentModel方法会读取additivity属性,然后设置到loggerModel

LoggerModelHandler

ch/qos/logback/classic/model/processor/LoggerModelHandler.java

代码语言:javascript
复制
public class LoggerModelHandler extends ModelHandlerBase {

    Logger logger;
    boolean inError = false;

    //......

    @Override
    public void handle(ModelInterpretationContext mic, Model model) throws ModelHandlerException {
        inError = false;

        LoggerModel loggerModel = (LoggerModel) model;

        String finalLoggerName = mic.subst(loggerModel.getName());

        LoggerContext loggerContext = (LoggerContext) this.context;

        logger = loggerContext.getLogger(finalLoggerName);

        String levelStr = mic.subst(loggerModel.getLevel());
        if (!OptionHelper.isNullOrEmpty(levelStr)) {
            if (JoranConstants.INHERITED.equalsIgnoreCase(levelStr) || NULL.equalsIgnoreCase(levelStr)) {
                if(Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(finalLoggerName)) {
                    addError(ErrorCodes.ROOT_LEVEL_CANNOT_BE_SET_TO_NULL);
                } else {
                    addInfo("Setting level of logger [" + finalLoggerName + "] to null, i.e. INHERITED");
                    logger.setLevel(null);
                }
            } else {
                Level level = Level.toLevel(levelStr);
                addInfo("Setting level of logger [" + finalLoggerName + "] to " + level);
                logger.setLevel(level);
            }
        }

        String additivityStr = mic.subst(loggerModel.getAdditivity());
        if (!OptionHelper.isNullOrEmpty(additivityStr)) {
            boolean additive = OptionHelper.toBoolean(additivityStr, true);
            addInfo("Setting additivity of logger [" + finalLoggerName + "] to " + additive);
            logger.setAdditive(additive);
        }

        mic.pushObject(logger);
    }

    //......
}    

LoggerModelHandler的handle方法会读取additivityStr,然后设置到logger中

Logger

ch/qos/logback/classic/Logger.java

代码语言:javascript
复制
public final class Logger
        implements org.slf4j.Logger, LocationAwareLogger, LoggingEventAware, AppenderAttachable<ILoggingEvent>, Serializable {

    //......

    /**
     * The parent of this category. All categories have at least one ancestor which
     * is the root category.
     */
    transient private Logger parent;

    /**
     * Additivity is set to true by default, that is children inherit the appenders
     * of their ancestors by default. If this variable is set to <code>false</code>
     * then the appenders located in the ancestors of this logger will not be used.
     * However, the children of this logger will inherit its appenders, unless the
     * children have their additivity flag set to <code>false</code> too. See the
     * user manual for more details.
     */
    transient private boolean additive = true;

    //......

    public void callAppenders(ILoggingEvent event) {
        int writes = 0;
        for (Logger l = this; l != null; l = l.parent) {
            writes += l.appendLoopOnAppenders(event);
            if (!l.additive) {
                break;
            }
        }
        // No appenders in hierarchy
        if (writes == 0) {
            loggerContext.noAppenderDefinedWarning(this);
        }
    }

    void recursiveReset() {
        detachAndStopAllAppenders();
        localLevelReset();
        additive = true;
        if (childrenList == null) {
            return;
        }
        for (Logger childLogger : childrenList) {
            childLogger.recursiveReset();
        }
    }

    //......
}        

Logger的callAppenders方法会先打印自己的appender,然后逐层遍历parent进行打印,若additive为false则不通过parent的appender打印

小结

logback的Logger提供了addtivity属性,默认为true,即除了自己appender,还会通过parent的appender进行打印,设置为false则不通过parent的appender进行打印。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • LoggerModel
  • LoggerAction
  • LoggerModelHandler
  • Logger
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档