首页 > 其他分享 >日志框架之日志门面SLF4J的使用

日志框架之日志门面SLF4J的使用

时间:2023-03-10 11:31:57浏览次数:44  
标签:框架 SLF4J slf4j 门面 org 日志 log4j

(日志框架之日志门面SLF4J的使用)

SLF4J概述

SLF4J (Simple Logging Facade for Java) 是一种 Java 编程语言的日志门面(logging facade)。它提供了一种将应用程序代码与特定日志记录(logging)实现(如 Log4j,java.util.logging 和 Apache commons-logging 等)分离的方式。

简单日志门面SLF4J主要是为了给Java日志访问提供一套标准、规范的API框架,其主要意义在于提供接口,具体的实现交由其他日志框架,例如log4j和logback等。

slf4j自己也提供了功能较为简单的实现,但是一般很少用到。

对于一般的Java项目而言,日志框架会选择slf4j-api作为门面,配上具体的实现框架(log4j、logback等),中间使用桥接器完成桥接。

SLF4J是目前市面上最流行的日志门面。现在的项目中,基本上都是使用SLF4J作为日志系统。

SLF4J日志门面主要提供两大功能:

日志框架的绑定: 将应用程序代码与具体的日志记录实现绑定,还可以在运行时切换不同的日志记录实现。

日志框架的桥接:将日志记录到一个共同的目标日志API中,可以维护更好的可读性和可维护性的应用程序

SLF4J的简单使用

        <!-- slf4j 日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>

        <!-- slf4j 内置的简单实现 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.21</version>
        </dependency>
public class Slf4j {

    public static final Logger LOGGER = LoggerFactory.getLogger(Slf4j.class);

    @Test
    public void test() {
        //日志输出
        LOGGER.error("error");
        LOGGER.warn("wring");
        LOGGER.info("info");
        LOGGER.debug("debug");
        LOGGER.trace("trace");

        //使用占位符输出日志信息
        String name = "hello slf4j";
        LOGGER.info("占位符输出日志信息:{}", name);

        //捕获异常,让日志输出,而非输出堆栈信息
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            // e.printStackTrace();
            LOGGER.error("异常输出:", e);

        }
    }
}
14:25:02.512 [main] ERROR cn.ybzy.Slf4j - error
14:25:02.520 [main] WARN cn.ybzy.Slf4j - wring
14:25:02.520 [main] INFO cn.ybzy.Slf4j - info
14:25:02.520 [main] INFO cn.ybzy.Slf4j - 占位符输出日志信息:hello slf4j
14:25:02.525 [main] ERROR cn.ybzy.Slf4j - 异常输出:
java.lang.ArithmeticException: / by zero
	at cn.ybzy.Slf4j.test(Slf4j.java:27)

SLF4J与日志框架的绑定

slf4j日志门面与日志实现框架的绑定关系如下: 在这里插入图片描述 日志框架出现的时间顺序:

log4j -->JUL-->JCL--> slf4j --> logback --> log4j2

因此,在实现日志框架的绑定/切换的时候,log4j与jul日志框架需要间接添加日志的适配器

日志框架的绑定过程

1.导入SLF4J库

需要将 SLF4J 库添加到应用程序的类路径中,以便应用程序可以使用 SLF4J 的 API。如添加slf4j-api的依赖

2.导入绑定具体的日志实现框架

需要导入支持 SLF4J 的日志框架库,如 Log4j、java.util.logging 或 Apache commons-logging

注意:

1.绑定已经实现了slf4j的日志框架,直接添加对应依赖

2.绑定没有实现slf4j的日志框架,先添加日志的适配器,再添加实现类的依赖

3.slf4j有且仅有一个日志实现框架的绑定(如果出现多个默认使用第一个依赖日志实现)

3.配置日志框架

需要配置日志框架,以便它可以与 SLF4J 协同工作。这通常涉及到在应用程序中进行配置文件的创建并在日志框架中启用 SLF4J

3.使用 SLF4J API 记录日志

在应用程序中,使用SLF4J的API在项目中进行统一的日志记录,达到了应用程序与绑定的日志框架解耦。

使用 SLF4J 中的 Logger 接口记录日志:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyClass {
    private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
    
  public void myMethod(){
      logger.info("info");
  }
}

slf4j+slf4j-simple

        <!-- slf4j 日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>

        <!-- slf4j 内置的简单实现 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.21</version>
        </dependency>

配置示例

slf4j-simple提供了一个默认的日志配置,将不同日志级别的日志信息打印到控制台上。也可在项目类路径下,创建名为simplelogger.properties的配置文件自定义一些配置

# 默认日志等级,当在源代码中未指定时使用
org.slf4j.simpleLogger.defaultLogLevel=debug

# 日志文件名,如果日志输出到文件中
# org.slf4j.simpleLogger.logFile=mylogfile.log

# 只显示Logger名称的最后一部分(最末尾的点之后的部分)
org.slf4j.simpleLogger.showShortLogName=true

# 显示每个日志信息的时间和日期
org.slf4j.simpleLogger.showDateTime=true

# 日志消息的日期和时间格式
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss.SSS

# 特定记录器的日志等级
# org.slf4j.simpleLogger.log.com.foo=warn

# 替换 WARN 级别输出的字符串
# org.slf4j.simpleLogger.warnLevelString=WARNING

slf4j+logback

        <!-- slf4j 日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>

        <!--logback 日志实现-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

配置示例

创建 Logback 配置文件 logback.xml,将其添加到 classpath 下

<configuration>

    <!-- 控制台输出的 appender -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
                %msg%n
            </pattern>
        </encoder>
    </appender>

    <!-- 日志文件输出的 appender -->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>logs/myLogFile.log</file>
        <append>false</append>
        <encoder>
            <pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} -
                %msg%n
            </pattern>
        </encoder>
    </appender>

    <!-- 各个包的日志级别 -->
    <logger name="com.example.myapp" level="INFO" />
    <logger name="org.springframework.data" level="DEBUG" />
    <logger name="org.hibernate" level="WARN" />

    <!-- 日志级别 root 日志级别 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>

</configuration>

slf4j+nop

引入slf4j-api且不引入具体实现或者引入slf4j-api+slf4j-nop将会关闭日志输出。

SLF4J NOP是一种特殊类型的SLF4J绑定,它不会记录日志。但是,在程序代码中还是可以使用完整的SLF4J API,因为SLF4J NOP绑定实现所有必需的SLF4J API方法,但它不执行任何实际的记录行为。

		<!-- slf4j 日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>
        
       <!-- nop日志开关-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.25</version>
        </dependency>

配置示例

不需要在代码中进行任何配置或初始化,因为SLF4J NOP是一个绑定,它允许您在您的代码中使用SLF4J API而不执行实际的日志记录。

slf4j+log4j

	     <!-- slf4j日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>
        
      <!--  绑定log4j日志实现,需要导入slf4j-log4j12适配器-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.12</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

配置示例

在src/main/resources文件夹下,创建一个名为log4j.properties的文件。在该文件中,可以指定要记录的级别、日志文件的输出位置、日志格式等。

#配置根日志级别
log4j.rootLogger=INFO, stdout, FILE

#配置控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

#配置日志文件输出
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=./logs/application.log
log4j.appender.FILE.MaxFileSize=10MB
log4j.appender.FILE.MaxBackupIndex=10
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

slf4j+jul

		 <!-- slf4j日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>
        
  	 	 <!-- 绑定jul日志实现,需要导入slf4j-jdk14适配器-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.7.25</version>
        </dependency>

配置示例

在src/main/resources文件夹下创建一个名为logging.properties的文

# 将JUL的日志委托给SLF4J API
handlers = org.slf4j.bridge.SLF4JBridgeHandler
# 配置的是日志级别
.level = FINEST
org.slf4j.bridge.SLF4JBridgeHandler.level = FINEST

SLF4J桥接旧的日志框架

SLF4J桥接旧的日志框架,就是使用SLF4J的桥接器,替换原有的日志框架。

SLF4J桥接的主要目的是将日志记录到一个共同的目标日志API中,可以维护更好的可读性和可维护性的应用程序。

SLF4J桥接旧的日志框架示意图: 在这里插入图片描述

SLF4J提供的桥接器

<!-- log4j-->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>log4j-over-slf4j</artifactId>
	<version>${version}</version>
</dependency>
<!-- jul -->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>jul-to-slf4j</artifactId>
	<version>${version}</version>
</dependency>
<!--jcl -->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>jcl-over-slf4j</artifactId>
	<version>${version}</version>
</dependency>

SLF4J桥接旧的日志框架流程:

1. 移除老的日志框架的依赖

2. 添加SLF4J提供的桥接组件

3. 添加SLF4J的具体实现

桥接旧的日志框架,如:将系统使用的logf4j日志框架切换到logback日志框架

旧的日志系统

  	 <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
public class Log4j {
    public static final Logger LOGGER = Logger.getLogger(Log4j.class);

    @Test
    public void test()throws Exception{
        LOGGER.info("hello lgo4j");
    }
}
INFO cn.ybzy.Log4j.test(Log4j.java:12) 2021-03-21 15:11:30,580 hello lgo4j

移除旧日志框架的依赖

当移除log4j的依赖时,项目中使用到的地方将报错 在这里插入图片描述

添加SLF4J提供的桥接组件

引入slf4j日志门面与log4j的桥接器,原来报错的地方全部恢复正常

   	<!-- slf4j日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>

         <!--配置log4j的桥接器-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>

加粗样式

添加SLF4J的具体实现

    <!--logback 日志实现-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

桥接旧的日志框架后测试:发现日志输出发生变法,桥接成功。

15:18:48.591 [main] INFO cn.ybzy.Log4j - hello lgo4j

标签:框架,SLF4J,slf4j,门面,org,日志,log4j
From: https://blog.51cto.com/chencoding/6112873

相关文章

  • vue (或者 javascript ) 打印彩色日志
    typeAny=any/***创建console所需的style样式*@parambgColor*@paramfontColor*/constcreateStyle=function(bgColor:string,fontColor='#fff......
  • java中的特殊文件、日志技术、多线程入门
    一,属性文件(.properties)1,特殊文件概述(必会)我们知道IO流是用来读数据,目的是为了获取其中的信息供我们使用,但是普通的txt文件是杂乱无章的,除非我们规定,自己写。虽然可以但......
  • Mybatis学习日志
    查询user表中所有数据1,创建user表,添加数据  2,创建模块,导入坐标 3,编写MyBatis核心配置文件-->替换链接信息解决编码问题4,编写SQL映射文件-->统一管理sql语句,解......
  • 自定义日志服务
     ///<summary>///日志服务///</summary>publicinterfaceILog{voidWrite(LogTypelogType,stringmessage=""......
  • kibana 展示日志信息携带k8s pod宿主机ip
    1、filbeat容器引入宿主机IP变量。2、配置文件引入环境变量。 pod引入pod信息的相关变量env:-name:MY_NODE_NAMEvalueFrom:fieldRef:fieldPa......
  • Python分析嵌入式日志小工具开发
    背景数据可度量,无人可值守,问题早发现功能点关键字分析自动压缩LOG自动发送邮件代码#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time    : 2022/8/2......
  • Android学习日志
    App工程分为两个层次,第一个层次是项目,另一个层次是模块模块依附于项目,每个项目至少有一个模块,也能拥有多个模块一般所言的“编译运行App”,是指运行某个模块,而非运行某个......
  • Python学习日志
    面对if语句,python和java和C不同的是,python更多的是if条件1语句:内容elif条件2语句:内容else:内容 #上面所有条件都不满足,则运行该条件语句下的。 0A=int(input()......
  • MySQL-binLog 日志开启
    MySQL的binlog(二进制日志)是一种记录MySQL服务器所有更改的二进制日志文件。开启binlog可以用于以下目的:数据复制:将binlog文件复制到另一个MySQL服务器,可以用于......
  • Python学习日志
    今天开始了第一次学习python,配置了python的所需环境完成了PythonCharm的编译器运行可视化界面。完成了“helloworld”的输出,了解了基本计算语句和规则  还有字符型......