logback源码阅读-获取Logger(二)
类图
前面代码看出来 最终返回的是LoggerContext这个类实现了LogFactory
成员变量
//表示根logger final Logger root = new Logger("ROOT", (Logger)null, this); //标识创建了多少个logger private int size; //未知 private int noAppenderWarning = 0; //<1>接口的实例能监听 logger context 上发生的事件,比如说日志级别的变化 private final List<LoggerContextListener> loggerContextListenerList = new ArrayList(); //logger缓存 get一次会存入缓存同时size++下次直接从缓存拿 private Map<String, Logger> loggerCache = new ConcurrentHashMap(); //loggerContextVO对象 private LoggerContextVO loggerContextRemoteView = new LoggerContextVO(this); private final TurboFilterList turboFilterList = new TurboFilterList(); private boolean packagingDataEnabled = false; private int maxCallerDataDepth = 8; //记录LoggerContext调用了几次方法 int resetCount = 0; private List<String> frameworkPackages;
<1>配置方式
<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<contextListener class="com.midea.jr.credit.accounting.utils.LoggerStartupListener" />
</configuration>
LoggerFactory
getILoggerFactory
摘自:《logback源码阅读-集成slf4j初始化过程(一)》
复制代码 public static ILoggerFactory getILoggerFactory() { /** * 0:未初始化 * 1:准备初始化 * 2:类没有实现LoggerFactoryBinder 相关方法 * 3:获取binder成功 * 4:没有找到相关类 */ static volatile int INITIALIZATION_STATE = 0; //这个工厂创建NOPLogger实例 是个空实现 static final NOPLoggerFactory NOP_FALLBACK_FACTORY = new NOPLoggerFactory(); public static ILoggerFactory getILoggerFactory() { /** * 判断是否初始化 */ if (INITIALIZATION_STATE == 0) { Class var0 = LoggerFactory.class; //加锁并判断 防止初始化后释放锁 等待的进来重复加载 synchronized(LoggerFactory.class) { if (INITIALIZATION_STATE == 0) { //标识正在初始化 INITIALIZATION_STATE = 1; //<4>执行初始化化绑定 performInitialization(); } } } switch(INITIALIZATION_STATE) { case 1: return SUBST_FACTORY; case 2: throw new IllegalStateException("org.slf4j.LoggerFactory in failed state. Original exception was thrown EARLIER. See also http://www.slf4j.org/codes.html#unsuccessfulInit"); case 3: //<1>可以看到此处是根据StaticLoggerBinder 这是一个slf4j继承点 为logback实现 下面会讲 return StaticLoggerBinder.getSingleton().getLoggerFactory(); case 4: return NOP_FALLBACK_FACTORY; default: throw new IllegalStateException("Unreachable code"); } } }
StaticLoggerBinder
<1>getLoggerFactory
org.slf4j.impl.StaticLoggerBinder#getILoggerFactory
private LoggerContext defaultLoggerContext = new LoggerContext(); public ILoggerFactory getLoggerFactory() { if (!this.initialized) { return this.defaultLoggerContext; } else if (this.contextSelectorBinder.getContextSelector() == null) { throw new IllegalStateException("contextSelector cannot be null. See also http://logback.qos.ch/codes.html#null_CS"); } else { return this.contextSelectorBinder.getContextSelector().getLoggerContext(); } }
LoggerContext
getLogger
ch.qos.logback.classic.LoggerContext#getLogger(java.lang.String)
public final Logger getLogger(String name) { //如果name为空抛出异常 正常不会出现 if (name == null) { throw new IllegalArgumentException("name argument cannot be null"); //如果传入的是root直接返回root Logger } else if ("ROOT".equalsIgnoreCase(name)) { return this.root; } else { int i = 0; Logger logger = this.root; //从缓存中获取Logger如果没有则 Logger childLogger = (Logger)this.loggerCache.get(name); if (childLogger != null) { return childLogger; } else { int h; do { //<1>这里根据,号分割依次连续截取 从最顶级开始获取 比如org.flowable.model 则依次是org->org.flowable->org.flowable.model h = LoggerNameUtil.getSeparatorIndexOf(name, i); String childName; if (h == -1) { childName = name; } else { childName = name.substring(0, h); } i = h + 1; synchronized(logger) { //<2>判断是否有初始化 没有则创建 childLogger = logger.getChildByName(childName); if (childLogger == null) { childLogger = logger.createChildByName(childName); this.loggerCache.put(childName, childLogger); //每次创建count++ this.incSize(); } } logger = childLogger; } while(h != -1); return childLogger; } } }
<1>处会依次截取创建logger并放入cache 同时维护父子关系
cache数据
总结
1.通过LogFactory获取Logger是根据类的全名称 分段初始化Logger有父子级关系
2.当我们调用log.isDebuger()等相关方法 会看当前级有没有设置没有则往复级查找
3.可以通过Logger标签指定某一级的相关参数设置如:
<!--自定义log打印flowable下的相关sql--> <logger name="org.flowable" level="debug"> </logger> <logger name="com.biaoguoworks.flowable.center" level="debug">
标签:
logback源码阅读
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
2017-01-07 使用XHR2或Jsonp实现跨域以及实现原理
2017-01-07 html5拖拽事件 xhr2 实现文件上传 含进度条