3

Java 日志包 LOGBack 简介

 2 years ago
source link: https://blog.triplez.cn/posts/java-logback-intro/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

初学 LOGBack,内容来自 LOGBack Chapter2: Architecture

包粒度级别继承#

下级的包若无特定设定日志级别,则会继承上层包的日志级别。

如下表所示:

日志器(包名) 分配日志级别 生效日志级别

root WARN WARN

cn.triplez none WARN

cn.triplez.demo DEBUG DEBUG

日志级别优先级#

TRACE < DEBUG < INFO < WARN < ERROR

获取日志器#

多次获取相同名称的日志器则会返回相同对象的引用。

Appenders and Layouts#

在日志中插入变量值#

假如你想写一条调试日志,如下:

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

这样的代码运行效率是很低的,因为该语句会先拼接日志字符串,再进行是否符合 DEBUG 层级的判断。因此,你可以写成如下形式以提高运行速度:

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

更好地方法#

事实上,在 LOGBack 中提供了更好的拼接方法,其能够基于模板填充变量。需要填充的变量只需在模板中用 {} 代替即可,而且该方法有很好的性能1,它能够先判断日志层级再进行字符串的处理。举个栗子:

logger.debug("Hello, {}!", name);

也可以写多个变量:

logger.debug("Hello, {}! I'm {}.", name, yourName);

如果有很多个变量,也可以使用 Object[] 来整合:

Object[] paramArray = {val1, val2, val3};
logger.debug("Value 1: {}, Value 2: {}, Value 3: {}", paramArray);

一瞥内部原理#

sequence diagram

性能#

完全关闭日志记录功能#

当日志功能在设置文件中被设置为 Level.OFF, 日志功能会被关闭。但是,写在程序中的 log 语句仍会产生一定的开销,主要是方法调用和整数比较。不过这个开销非常之小,我们完全不用担心。

不过,在某些写法之下,方法调用会产生隐藏的变量构建的开销,这一点在前面已经提过,举个栗子:

x.debug("Entryu number: " + i + "is " + entry[i]);

如上的写法会产生额外的字符串拼接成本,其需要将 ientry[i] 都转换成为字符串,并将四个字符串对象拼接起来。而这个过程是与有效层级无关的,也就是说,无论是否满足输出该条日志的条件,都会进行字符串的拼接操作。

为了避免产生这种额外的运行开销,提高程序运行效率,我们可以使用 SLF4J 的变量化日志记录接口:

x.debug("Entry number: {} is {}", i, entry[i]);

这种变体写法不会产生额外的变量构建成本,日志信息只有该日志请求被发送到追加器(即满足记录要求及输出层级)之后才会被格式化,并且该方法经过了优化处理,能够很大程度提高运行效率。

不建议在循环中使用日志记录,即使不记录日志也会产生额外的开销,记录了日志也会输出大量的重复无用信息。

日志器在检查日志层级的性能#

在 LOGBack 中,日志器不需要根据继承关系去寻找自己真正所对应的记录层级,在日志器被创建之后,继承关系就会确定并且确定了该日志器自身的记录层级。并且更改了某个父记录器的记录层级之后,相对应的子记录器都会被发送请求以更改记录层级。因此,在比较日志层级时,日志器能够做到准即时的决策,而不需要在此处去请求父记录器才能做出决策。

日志输出#

日志真正被输出到文件或流中是开销最大越是最为费时的操作。从日志开始记录到写入文件系统中的典型开销是 9 到 12 毫秒,若为写到远端数据库或服务器会再增加几毫秒的延时。尽管 LOGBack 的功能非常丰富,但是 LOGBack 的核心依然是保证运行效率,开发者们已多次为了得到更好地性能重构 LOGBack 组件。


  1. 官方指出对比直接拼接字符串的方法能够至少提高 30% 的性能。 ↩︎


知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK