模块划分

当前logback被分为了三个模块

  • logback-core,为其他两个模块提供基础功能
  • logback-classic,是一个相对于log4j的显著改进版本,实现了slf4j的api,所以可以轻松的切换其他日志框架,比如jul
  • logback-access.提供了servlet容器的http访问日志记录的功能

Logger,Appenders和Layouts

这个logback建立在这三个主要的类上面,这三个组件提供了,允许开发着在选择何种等级的日志(Appenders) 、控制日志的格式(Layouts)、和在哪里打日志(logger)

Logger是在logback-classic中的、Appenders和Layouts是在logback-core中的。

Logger

名称继承

通常情况下,我们给Logger命名都是通过类的全限定类名。

LoggerContext负责创建Logger,并且按照树一样的格式来进行管理,所以Logger也是分等级的,root logger就是顶端,分级规则也很简单,就是通过一个英文点来进行分,比如 com.unclezs.log,名字为com.unclezs的Logger就比名字为com.unclezs.log的Logger等级高。

获取root logger:

Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

日志级别与继承的关系

slf4j提供的日志级别TRACE, DEBUG, INFO, WARN 和 ERROR

TRACE < DEBUG < INFO < WARN < ERROR.

获取日志的有效等级,当一个log.xx方法执行时,如果当前命名空间没有对应Level,就会根去查找祖先节点的日志级别,直到找到为止

判断日志是否会被打印:

摘自官方文档:

A log request of level p issued to a logger having an effective level q, is enabled if p >= q.

比如com.unclezs.a 配置的logger日志级别为info
com.unclezs.a.b 配置的logger日志级别为error
在com.unclezs.a.b调用log.warn

得到有效日志等级为error,请求日志等级为warn,warn < error
则不打印

检索Logger

通常情况下我们都是通过Clazz.class来获取Logger,但是也可以传入他的全限定类名。

当然这个名字都是自己定义的,你可以命名为abc,bcd之类的,但是没有什么意义,安装全限定类名进行命名可以很好的利用日志级别按照名称继承等级的好处。

Appender

Appender允许我们将日志打到各种地方,可以是控制台,可以是文件,也可以是数据库、JML等等

一个logger可以拥有多个Appender,并且都会执行,所以你可以通过一个logger就能把日志打到控制台和文件。

Appender也是有累加性质的,也就是会查看父及logger有没有Appender ,如果有,则一起执行。可以在logger上配置additivity=false来关闭这个特性。

Layout

Appender的子节点,定义日志的格式。

%-4relative [%thread] %-5level %logger{32} - %msg%n

输出

176  [main] DEBUG manual.architecture.HelloWorld2 - Hello world.

第一个参数代表程序启动后所过时间。

参数化打印日志

下面这种方式会引起 不论是否启用日志记录,都会有构造消息参数的消耗(类型转换)

logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));

通常情况下通过下面这种防止来防止消息参数的构造消耗,但是通过这种方法如果日志是开启的情况下,还是会出现同样的情况,甚至还多了个boolean类型的判断消耗

if(logger.isDebugEnabled()) { 
  logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}

更好的方案,这样的操作的好处就是,在不进行日志打印的时候,不会进行消息参数构造,也就不会有类型转换的消耗。

logger.debug("The new entry is {}.", entry);
logger.debug("Value {} was inserted between {} and {}.", paramArray);

从一次log.info()的过程

参考

Chapter 2: Architecture

博客
分类
标签
归档
关于