SLF4J和Logback到底是什么?我们该怎么用它...

1 篇文章 0 订阅

SLF4J和Logback

SLF4J概念

简单日志门面,对应的英文为Simple Logging Facade,是存取日志的标准接口。

也就是说它仅仅是一个日志输出的接口,并不是一种具体的实现方案,就像 JDBC一样只是统一的接口。

想要使用必须搭配其他的日志实现方案,如:log4jlogbackJDK logging 等等。

可以看到 Logback 直接继承自 SLF4J,它比其它所有的日志系统更快并且更小,包含了许多独特并且有用的特性。

Logback概述

Logback 分成三个不同的模块,logback-corelogback-classiclogback-access

快速使用

添加依赖:

logback-classic 模块需要在 classpath 添加 slf4j-api.jar、logback-core.jar 以及 logback-classic.jar。

maven项目中,使用坐标:

<dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
</dependency>

该依赖会包含其他几个坐标,可以手动添加相同版本的依赖,也可以只添加这一个。

如果你安装了 Maven,你可以在 logback 的解压文件夹中运行 mvn install 来构建 logback 以及它所包含的模块。Maven 会自动下载 logback 需要的其它类库。

测试例子:

public class Test {

    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger("Test");
        logger.debug("hello world,this is a debug message...");
      
      	// 打印内部的状态
        LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory();
        StatusPrinter.print(loggerContext);
    }
}

控制台打印结果:

12:08:39.804 [main] DEBUG com.codesy.test.Test1 - hello world,this is a debug message…

12:08:39,639 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
12:08:39,640 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
12:08:39,640 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
12:08:39,656 |-INFO in ch.qos.logback.classic.BasicConfigurator@1af6ecc - Setting up default configuration.

LoggerLoggerFactory 时 SLF4J包中的类 , LoggerContext 获得内部状态信息。

得到 Logger 实例,通过它调用不同的方法 trace() ,debug()info()warn()error()来向指定的位置输出日志信息。

控制台显示的信息位没有找到配置文件 [logback-test.xml] [logback.groovy] [logback.xml]

从而 Setting up default configuration(设置默认配置

我们可以自己创建对应的配置文件,让日志信息采取我们想要的方式打印存储。也可以使用默认简单的配置,即不手写配置文件,使用默认配置类 ch.qos.logback.classic.BasicConfigurator,该类只有一个方法,里面设置了默认的配置方案。


基本的Logback组件

Logback 的构建重点是三个主要的类上:LoggerAppenderLayouts

组件Logger

每一个 Logger 实例都会依附在 LoggerContext 上,它管理所有 Logger实例,并且通过一个树状的层级结构来管理。

如果一个 Logger 实例的名字 A 加上一个 . 和另一个 Logger 实例名字 B ,那么 A 就是B的祖先,如果它们之间再无其他 Logger,A就是B的父级

例如 一个Logger实例名为 com.codesy 如果 另一个实例名为 com.codesy.test ,那么前者就是后者的父级。名称是大小写敏感的。

示例:获取一个 名为 com.codesy.test 的Logger实例,查看它所依附的 LoggerContext 的所有 Logger实例

public class Test {

    public static void main(String[] args) {
		//获取 com.codesy.test 实例
        Logger logger= LoggerFactory.getLogger("com.codesy.test");
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
		//getLoggerList()方法返回所有Logger实例
        List<ch.qos.logback.classic.Logger> loggerList = context.getLoggerList();
        for (ch.qos.logback.classic.Logger logger1 : loggerList) {
            System.out.println(logger1.getName());
        }
    }
}

输出结果:

ROOT
com
com.codesy
com.codesy.test

可以看到LoggerContext 中一共存在4个Logger实例,以 . 进行分割。获得 com.codesy.test 实例,其实同时得到了comcom.codesy实例,它们都是com.codesy.test的前缀,通过 . 相连。

还注意到一个最顶级的Logger实例 ROOT ,它是这棵树的最高层。

Logger的等级

Logger 实例被分成不同的 等级,不同的等级定义在 ch.qos.logback.classic.Level 类中。

等级分类有 (TRACE < DEBUG < INFO < WARN < ERROR)

每一个获取到的 Logger实例如果没有指定等级,那么它会继承离它最近的一个祖先的等级。

ROOT 实例默认等级为 DEBUG ,倘若其他Logger实例都没有指定等级,那么继承ROOT的DEBUG等级。

如果实例本身指定了等级,那么就直接用自身的等级,不用继承。

示例:

Logger的规则

每一个 Logger 实例都会有日志输出方法,例如:
trace(),debug(),info(),warn(),error() 等等。

每一条打印语句都表示这条日志的打印等级:debug("...") 表示这个日志等级为 DEBUG

Logger 实例有等级,通过调用的打印方法也有等级,那么它们之间有什么关系呢?

如果一条的日志的打印等级大于等于 Logger实例 的等级,该条日志才可以被打印出来。

各等级的排序为:TRACE < DEBUG < INFO < WARN < ERROR

示例:

public class Test {

    public static void main(String[] args) {
        Logger logger= LoggerFactory.getLogger("com.codesy.test");
        logger.debug("这是一条DEBUG等级的日志消息");
        logger.trace("这是一条TRACE等级的日志消息");
    }
}

控制台打印:

16:37:41.598 [main] DEBUG com.codesy.test - 这是一条DEBUG等级的日志消息

可以看到 logger.trace(“这是一条TRACE等级的日志消息”); 这条语句没有被输出到控制台,因为 logger 没有指定等级默认继承 ROOT 的等级 DEBUG。这条日志消息的等级为 TRACEDEBUG小,无法打印。

注意:

对于我们上述的 Logger 实例它是 org.slf4j.Logger 包下的,我们也可以获取 ch.qos.logback.classic.Logger 包下的 Logger实例。

public final class Logger implements org.slf4j.Logger	//实现了org.slf4j.Logger包下的Logger

该 Logger实例包含特有的方法,如设置Logger实例等级

logger.setLevel(TRACE);		//这样该Logger实例等级为 TRACE

另一点:

获取 Logger实例 通过 :

Logger logger = LoggerFactory.getLogger("com.codesy.test")

还有一种通过类的Class对象获得Logger实例,推荐使用 "com.codesy.test"这种形式,这个命名策略能够看出日志的来源是哪里。

组件Appender与Layout

上述的Logger等级规则可以使得低等级的日志不被打印出来,那么 Appender就是日志输出的位置,包console、file、remote socket server、MySQL、PostgreSQL、Oracle 或者其它的数据库、JMS、remote UNIX Syslog daemons 等位置。

一个Logger实例可以有多个 appender (多个输出位置)。

子级Logger实例会继承来自父级的 appender,例如 com.codesy 这个实例添加了 一个 console appender,那么 com.codesy.test 除了它本身的appender外 ,也会拥有console appender。当然前提是 additivity = true 这个属性设置为 true表示可以继承父级的appender,为 false则不能,默认为 true

Layout 它使用户可以自定义日志的输出格式

参数化日志

在以前的log4j时候,没有实现slf4j日志接口,打印语句是这样的

int num = 1;
logger.debug("The num is " + num + ".");

这样会带来效率成本,它会拼接字符串,并且需要把num转成String类型,消耗性能。

而在实现slf4j日志接口的logback里,这样打印会节省性能

int num = 1;
logger.debug("num is {}.",num);

将 ‘{}’ 替换成 num的字符串形式,{}是占位符。

它也支持对象数组形式的参数,如

Object[] array = {1,"Hello",true};
logger.debug("Integer is {}, String is {}, Boolean is {}.",array);

在代码中使用日志语句是十分麻烦的,因为一个中型项目也会有成千上万条日志语句。所以需要用配置文件来管理日志,日后再说。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值