logback的addtivity屬性定義源碼解讀
序
本文主要研究一下logback的addtivity屬性
LoggerModel
ch/qos/logback/classic/model/LoggerModel.java
@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
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屬性,然后設(shè)置到loggerModel
LoggerModelHandler
ch/qos/logback/classic/model/processor/LoggerModelHandler.java
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,然后設(shè)置到logger中
Logger
ch/qos/logback/classic/Logger.java
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進(jìn)行打印,若additive為false則不通過parent的appender打印
小結(jié)
logback的Logger提供了addtivity屬性,默認(rèn)為true,即除了自己appender,還會通過parent的appender進(jìn)行打印,設(shè)置為false則不通過parent的appender進(jìn)行打印。
以上就是logback的addtivity屬性源碼解讀的詳細(xì)內(nèi)容,更多關(guān)于logback addtivity屬性的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot HikariCP連接池監(jiān)控實現(xiàn)方案
文章介紹了五種監(jiān)控SpringBoot應(yīng)用程序中HikariCP連接池狀態(tài)和性能的工具和技術(shù),包括SpringBootActuator、Micrometer、Prometheus+Grafana、HikariCP自帶的Metrics以及NewRelic/Datadog等第三方服務(wù),每種方法都有其特點和配置步驟2025-01-01
SpringBoot訪問web中的靜態(tài)資源的方式小結(jié)
這篇文章主要介紹了SpringBoot訪問web中的靜態(tài)資源的方式,本文給大家介紹了兩種方式,通過代碼示例和圖文講解的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2024-10-10
SpringBoot執(zhí)行有返回值的異步任務(wù)問題
這篇文章主要介紹了SpringBoot執(zhí)行有返回值的異步任務(wù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
Spring boot按日切分spring boot的nohup.out日志文件的方法
過大的日志文件維護(hù)起來存在諸多問題,所以最好是能夠按日或按大小切分日志文件,下面小編給大家?guī)砹薙pring boot按日切分spring boot的nohup.out日志文件的方法,一起看看吧2018-08-08
springboot默認(rèn)文件緩存(easy-captcha?驗證碼)
這篇文章主要介紹了springboot的文件緩存(easy-captcha?驗證碼),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-06-06

