一、logger的命名与层级
在说日志级别的层级关系前,一定要说说logger的命名,这两者是紧密关联的。
LoggerContext
logger是被LoggerContext
对象以树形层级结构组织起来的。LoggerContext
实现了org.slf4j.ILoggerFactory
接口,那这个上下文对象我们就可以把它理解为logback的logger工厂。
LoggerContext
里使用
this.loggerCache = new ConcurrentHashMap<String, >Logger>();
来缓存logger;
logger名称
logger在这个工厂里面是以名字来区分的,logger的名字就是他的key,我们通常可以通过传入一个String对象或者Class对象来获取logger,实际上Factory在获取到了传入Class对象的时候,会调用Class的getName()
方法获取类的全路径名,然后再调用getLogger(String name)
方法在缓存里获取Logger。
从上面我们可以看出,logger的名字是大小写敏感的(获取根logger除外)。
logger层级结构
而logger的层级关系也是以名字为依据来组织的。其关键就是名字中的”.”符号。用”.”将logger名字切开,最后一个”.”之前的字符串就是这个logger的父logger名称。
举例来说,一个logger名称为com.test.loggerdes.a
。那他的父logger的名称就是com.test.loggerdes
,而com.test.loggerdes
的父logger名称为com.test
。
以此类推,那根logger是名称为com
的logger么,当然不是。在LoggerContext
初始化的时候会发现这段代码:
this.root = new Logger(Logger.ROOT_LOGGER_NAME, null, this);
...
loggerCache.put(Logger.ROOT_LOGGER_NAME, root);
也就是说,根logger是一个以Logger.ROOT_LOGGER_NAME
命名的logger,而Logger.ROOT_LOGGER_NAME
的值是字符串"ROOT"
。研究代码进一步可以得知,路径只有一级的logger他的父logger都是根logger。
这个例子里涉及到的logger我们从根logger排出来就是下面这个造型,其中上一行是下一行的父logger:
ROOT
com
com.test
com.test.loggerdes
com.test.loggerdes.a
二、日志level与层级继承
第一节讲那么多东西,到底有什么用呢?当然是很重要,命名层级与日志配置和行为有直接关系。
日志level
日志级别用来区分日志的重要性,我们把不同重要性的日志归类到不同级别里,我们可以此来针对不同重要等级的日志制定不同管理策略。而logback里ch.qos.logback.classic.Level
类定义了level。
日志级别按重要性从小到大依次为:
TRACE < DEBUG < INFO < WARN < ERROR
logger日志级别的设置与继承
在logback中,日志级别是配置给logger的,负责设定一个logger记录的日志等级。当我们没有为一个logger设置日志级别时,系统会沿着logger数朝着根节点方向查找,寻找最近一个设置了日志级别的父logger或先人logger。查找到最上面当然就是上文提到的root logger,而root logger的默认日志等级是debug级。
下面几个例子用来说明在logger上设置日志级别以及级别的继承:
例1:设置root logger为level,或不设置(root默认为debug)
logger名 | 设置level | 生效level |
---|---|---|
root | debug | debug |
x | 未设置 | debug |
x.y | 未设置 | debug |
x.y.z | 未设置 | debug |
例2:每个logger都设置对应级别
logger名 | 设置level | 生效level |
---|---|---|
root | debug | debug |
x | info | info |
x.y | error | error |
x.y.z | warn | warn |
例3:
logger名 | 设置level | 生效level |
---|---|---|
root | debug | debug |
x | info | info |
x.y | 未设置 | info |
x.y.z | warn | warn |
例4:
logger名 | 设置level | 生效level |
---|---|---|
root | debug | debug |
x | info | info |
x.y | 未设置 | info |
x.y.z | 未设置 | info |
从上面几个例子可以得出结论:一个logger的日志级别会被他的子logger继承,直到子logger也被单独设置日志级别。
根据level记录日志
如果我们的logger设定的日志级别是debug,在默认情况下,这个logger会记录哪些级别的日志呢?这时候,该logger会记录所有日志级别大于等于debug的日志,也就是从DEBUG级别到ERROR级别的所有日志。
规则:如果logger生效日志级别为q,这个logger会记录的日志等级为x,那么x>=q。