《第二节》聊一聊日志系统 Logback

作者: Ceki Gülcü,和log4j作者是同一个人,logback的性能和使用都提升了很多,如果没有特殊要求,项目中直接使用logback吧。

上一篇《项目中日志框架的正确使用方式slf4j+logback》介绍了起源和大概的原理,至少应该了解以下内容:

  • logback无缝衔接SLF4J(也是Ceki Gülcü的作品,日志门面)
  • 项目中需要包含对slf4j-api-*.jar的依赖
  • 项目中需要包含对logback-core.jarlogback-classic.jar的依赖
    使用方法还是千篇一律的写法:

package chapters.introduction;
// 这里并没有引入logback相关文件,在记录日志时也是只使用SLF4j提供的接口
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld1 {
  public static void main(String[] args) {
    // 这句话会根据classpath下的引用查找SLF4j的具体实现类,可参照上一篇
    Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld1");
    logger.debug("Hello world.");
  }
}

由三大组件构成

  • logback-core:核心组件,为其他两个提供支撑
  • logback-classic:扩展Logback-core,而且是日志功能的真实实现,可理解为log4j的进阶版本
  • logback-access:可结合logback-core用于http容器的日志功能,如tomcat,不常用

由三大主类构成

  • Logger:在logback-classic中实现,日志记录器
  • Appender :在logback-core中实现,打印到什么地方
  • Layout.:在logback-core中实现,设置打印格式

Logger介绍

获取Logger

通过LoggerFactory.getLogger(A)获取Logger,如果A相同,Logger始终是同一个对象

Logger aLogger = LoggerFactory.getLogger("com.foo");
Logger bLogger = LoggerFactory.getLogger("com.foo");
那么:aLogger和bLogger引用完全相同的Logger对象。

日志记录等级及关系:TRACE< DEBUG<INFO< WARN <ERROR

日志记录等级有2个用处:

  • 在代码逻辑中输出日志时,需要明确等级,如logger.info("打印普通日志"),明确了等级=info
  • 日志全局配置中需要指定真实打印日志的等级,如logging.level=warn,只有大于>warn的日志等级才会真实被打印,上面的info不会被打印
Logger的继承关系

为什么会存在继承关系?
比如在使用logger的时候并没有配置level,怎么办?
这时候就是根据继承关系向上查找,直到找到后生效。
如果都没有设置怎么办?
不会发生这种情况,因为根记录器提供一个默认的level,并设为debug,也就是保底的配置。
如何继承?看一个示例:

//ROOT_LOGGER_NAME固定为ROOT,是所有日志记录器的根(Root)
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
Logger faLogger = LoggerFactory.getLogger("com.foo");
Logger chLogger = LoggerFactory.getLogger("com.foo.bar");
继承
继承
chLogger
faLogger
rootLogger
rootLogger
faLogger
chLogger

只要缺省了某一个配置,就会沿着继承关系逐级向上查找,直到找到为止!

  • Level的继承关系:如果自身设置了level,则使用自身的生效;否则向上查找;
  • Appender的继承关系:默认是累加的,即自身和父级的都会生效(这种累加会一直向上查找,直到遇到附加flag=false的为止),当然可以设置flag=false禁用累加方式,Appender比较复杂,见下表:
Logger设置Appender附加Flag最终输出目标备注
rootA1不适用A1根日志记录器不需要设置Flag
xA-x1, A-x2trueA1, A-x1, A-x2其中A1是继承了root
x.ynonetrueA1, A-x1, A-x2继承了root和x
x.y.zA-xyz1trueA1, A-x1, A-x2, A-xyz1继承了root、x和x.y
securityA-secfalseA-sec不继承父级
security.accessnonetrueA-sec只继承security,因为security设置了false,所以不再继续继承祖先

Appender

一个Logger可以被打印到多个Appender指定的位置,如同时打印到文件或console。

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]));

无论该日志是否打印,日志内容中的+都会执行解析,增加了开销,所以更推荐以下写法:

Object entry = new SomeObject(); 
//只有需要打印`debug`级别的日志时,才会解析日志内容,平时无开销
logger.debug("The entry is {}.", entry);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值