日志库包含日志系统和日志门面。
【资料图】
日志库的使用, 包含配置与API使用;配置侧重于日志系统的配置,API使用侧重于日志门面。
日志系统指的是具体的日志框架,这里我们只说一下最常用的log4j2、logback,而JUL、log4j现阶段基本不常见了。
Log4j2是Log4j 的升级版,Log4j2 和 Log4j1.x 并不兼容,设计上很大程度上模仿了 SLF4J/Logback,性能上也获得了很大的提升。Log4j2 也做了 Facade/Implementation 分离的设计,分成了 log4j-api 和 log4j-core。
Logback 是springBoot默认的日志处理框架,同时它和log4j都是出自同一作者之手,提供了性能更好的实现,异步 logger,Filter等更多的特性。
logback 当前分成三个模块:logback-core、logback-classic 和 logback-access。
logback-core - 是其它两个模块的基础模块。
logback-classic - 是 log4j 的一个 改良版本。此外 logback-classic 完整实现 SLF4J API 使你可以很方便地更换成其它日志系统如 log4j 或 JDK14 Logging。
logback-access - 访问模块与 Servlet 容器集成提供通过 Http 来访问日志的功能。
log4j2比logback更新:log4j2的GA版在2014年底才推出,比logback晚了好几年,这期间log4j2确实吸收了slf4j和logback的一些优点(比如日志模板),同时应用了不少的新技术。
由于采用了更先进的锁机制和LMAX Disruptor库,log4j2的性能优于logback,特别是在多线程环境下和使用异步日志的环境下。
二者都支持Filter(应该说是log4j2借鉴了logback的Filter),能够实现灵活的日志记录规则(例如仅对一部分用户记录debug级别的日志)。
二者都支持对配置文件的动态更新。
二者都能够适配slf4j,logback与slf4j的适配应该会更好一些,毕竟省掉了一层适配库。
logback能够自动压缩/删除旧日志。
logback提供了对日志的HTTP访问功能。
log4j2实现了“无垃圾”和“低垃圾”模式。简单地说,log4j2在记录日志时,能够重用对象(如String等),尽可能避免实例化新的临时对象,减少因日志记录产生的垃圾对象,减少垃圾回收带来的性能下降。
log4j2和logback各有长处,总体来说,如果对性能要求比较高的话,log4j2相对还是较优的选择。
为什么有了日志系统之后我们直接用不就好了,为什么还要弄一个日志门面呢?
这其中做重要的一点就是解耦合,slf4j和Commons-Logging都是提供日志门面的,用户可以选择第三方的日志组件来作为具体实现。提供日志的接口和获取具体日志对象的方法。这样就避免了我们的应用和日志方案的直接耦合,如果需要有改动日志方案时,我们可以直接修改日志实现。因为日志门面一般都兼容大多数的日志框架。
总结下日志门面的作用:
面向接口开发,不再依赖具体的实现类,减少代码的耦合;
项目通过导入不同的日志实现类,可以灵活的切换日志框架;
统一API,方便开发者学习和使用;
统一配置便于项目日志的管理。
common-logging 的功能是提供日志功能的 API 接口,本身并不提供日志的具体实现(当然,common-logging 内部有一个 Simple logger 的简单实现,但是功能很弱,直接忽略),而是在运行时动态的绑定日志实现组件来工作(如 log4j、java.util.loggin)。
简单日志门面(Simple Logging Facade For Java) SLF4J主要是为了给Java日志访问提供一套标准、规范的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如log4j和logback等。
对于一般的Java项目而言,日志框架会选择slf4j-api作为门面,配上具体的实现框架(log4j、logback等),中间使用桥接器完成桥接。
注意:启用slf4j库意味着添加一个强制的依赖,即slf4j-api.jar。如果在类路径上找不到绑定/提供程序,那么slf4j将默认为无操作实现。
两者区别不大,slf4j 一大亮点是提供了更方便的日志记录方式,common-logging日志输出内容需要拼接字符串,而slf4j 的方式是使用{}作为字符串替换符,实际项目中基本都会使用slf4j作为日志门面。
// common-logginglog.debug("time: " + time + ", name: " + name);// slf4jlogger.debug("time: {}, name: {} ", time, name);
标签:
滚动