slf4j和log4j的区别与使用

slf4j和log4j的区别与使用

文章目录

1.简介

官网:https://www.slf4j.org/manual.html

(1)简单日记门面(simple logging Facade for Java)SLF4J是为各种loging APIs提供一个简单统一的接口。

(2)slf4j并不是一种具体的日志系统,而是一个用户日志系统的facade。

(3)在部署时,选择不同的日志系统包,即可自动转换到不同的日志系统上。

如:选择JDK自带的日志系统,则只需要将slf4j-api-XXX.jar和slf4j-jdkXXX.jar放置到classpath中即可,若想换成log4j的日志系统,仅需要用slf4j-log4jXXx.jar替换slf4j-jdkXXX.jar即可

(4)slf4j和log4j比较:

①log4j看成是一个完整的日志库;而slf4j是一个日志库的规范接口,可以根据不同的日志包使用不同的日志库。

②日志中需要传入参数时,log4j一般是使用字符串进行拼接的方式;

slf4j使用占位符,比字符串拼接更加高效。如logger.error("sql为 {} ",sql)。

(5)slf4j日志级别

Slf4j日志级别,级别由低到高,设置的级别约低,打印的日志越多

①trace: 一般不会使用,在日志里边也不会打印出来,最低的一个日志级别。

②debug: 一般放于程序的某个关键点的地方,用于打印一个变量值或者一个方法返回的信息之类的信息

③info 一般处理业务逻辑的时候使用,就跟 system.err打印一样,用于说明此处是干什么的。

④warn:警告,不会影响程序的运行,但是值得注意。

⑤error: 用户程序报错,必须解决的时候使用此级别打印日志。

2.使用教程

官网上最新稳定版是1.7.32,前阵子log4j出重大漏洞了,这里我们配合logback(log4j的改良版,性能更好)使用。

(1)在pom.xml引入依赖

复制代码
  <!--slf4j依赖-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version>
        </dependency>
        <!-- logback 依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

(2)在springBoot项目中添加一段controller代码

复制代码
package com.example.springb_web.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class VisualController {

    private Logger logger = LoggerFactory.getLogger(VisualController.class);

    @RequestMapping(value="/test")
    @ResponseBody
    public String test(){
        String msg = "fucking good";
        logger.info("slf4j print info msg:{}",msg);
        logger.debug("slf4j print debug msg:{}",msg);
        return msg;
    }

}

这里通过http://localhost:8080/test访问可以看到控制台输出如下,可以看到info的输出了,debug没有,因为springboot内部集成了slf4j,默认是info级别:

(3)只在控制台打印,application.yml文件配置如下:

复制代码
# slf4j日志配置
logging:
  # 配置级别
  level:
    root: info
    #分包配置级别,即不同的目录下可以使用不同的级别
    com.example.springb_web.controller: debug

改完之后发现输出如下:

(4)把日志输出到文件,application.yml配置:

复制代码
# slf4j日志配置
logging:
  config: classpath:logback.xml

在resource下新建logback.xml:

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

	<!--info日志文件-->
	<appender name="INFO_FILE"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<!--日志文件相对路径和名称-->
		<file>./apilogs/info/xxxx_-${HOSTNAME}.log</file>
		<append>true</append>
		<!--根据日志文件的大小来滚动(即创建新的)日志文件-->
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>./apilogs/info/archive/xxxx_-${HOSTNAME}-%d.%i.log</fileNamePattern>
			<!--只保留最近30天的日志-->
			<maxHistory>30</maxHistory>
			<timeBasedFileNamingAndTriggeringPolicy
				class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<!--超过10MB便会滚动日志文件-->
				<maxFileSize>10MB</maxFileSize>
			</timeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<!-- 配置日志的输出格式 -->
		<encoder>
			<pattern>%date %level [%thread] %logger{10} %msg%n</pattern>
			<charset>UTF-8</charset>
		</encoder>
	</appender>

	<!--异步处理-->
	<appender name="ASYNC_INFO_FILE" class="ch.qos.logback.classic.AsyncAppender">
		<queueSize>512</queueSize>
		<appender-ref ref="INFO_FILE" />
	</appender>

	<!--debug日志文件-->
	<appender name="DEBUG_FILE"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<!--日志文件相对路径和名称-->
		<file>./apilogs/debug/xxxx_-${HOSTNAME}.log</file>
		<append>true</append>
		<!--根据日志文件的大小来滚动(即创建新的)日志文件-->
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>./apilogs/debug/archive/xxxx_-${HOSTNAME}-%d.%i.log</fileNamePattern>
			<!--只保留最近30天的日志-->
			<maxHistory>30</maxHistory>
			<timeBasedFileNamingAndTriggeringPolicy
				class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<!--超过10MB便会滚动日志文件-->
				<maxFileSize>10MB</maxFileSize>
			</timeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<!-- 配置日志的输出格式 -->
		<encoder>
			<pattern>%date %level [%thread] %logger{10} %msg%n</pattern>
			<charset>UTF-8</charset>
		</encoder>
	</appender>

	<!--异步处理-->
	<appender name="ASYNC_DEBUG_FILE" class="ch.qos.logback.classic.AsyncAppender">
		<queueSize>512</queueSize>
		<appender-ref ref="DEBUG_FILE" />
	</appender>

	<!--控制台输出-->
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<!--输出格式-->
			<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
			<charset>UTF-8</charset>
		</encoder>
	</appender>

	<!--异步处理-->
	<appender name="ASYNC-STDOUT" class="ch.qos.logback.classic.AsyncAppender">
		<queueSize>512</queueSize>
		<appender-ref ref="STDOUT" />
	</appender>

	<!--在info级别下,将包名所在org.springframework的日志全部打印到控制台-->
	<!--additivity被设置为'false',这意味着日志事件不会传递给父级记录器-->
	<logger name="org.springframework" level="info" additivity="false">
		<appender-ref ref="ASYNC-STDOUT" />
	</logger>

	<!--在debug级别下,会打印记录sql的相关日志,将包名为org.apache.ibatis下的日志输出到debug日志文件-->
	<logger name="org.apache.ibatis" level="debug" additivity="false">
		<appender-ref ref="ASYNC_DEBUG_FILE" />
	</logger>

	<!--所有业务相关的info日志,打印到控制台,并输出到info日志文件-->
	<root level="info">
		<appender-ref ref="ASYNC-STDOUT" />
		<appender-ref ref="ASYNC_INFO_FILE" />
	</root>
</configuration>

可以看到控制台和日志文件都成功输出了:

3.常见报错解决(持续更新)

(1)yml配置报错如:

"Failed to bind properties under 'logging.level'"

可能跟版本有关,参考yml配置上面的使用教程的第(3)步

(2)启动时报错:

"class path contains multiple slf4j bindings

found binding in ..."

不要忽视这种警告,若有多个jar包类冲突,需要把加载jar包顺序调整,正确的那个,比如slf4j-log4j12jar包放在最上面。

相关推荐
2601_954706496 分钟前
云手机技术详解+Python实战调用|2026高稳云手机平台推荐
开发语言·python·智能手机
chushiyunen7 分钟前
java中的路径处理、左右斜杠
java·开发语言·python
jay神32 分钟前
基于 FastAPI + Vue 的宠物领养管理系统
前端·vue.js·python·毕业设计·fastapi·宠物
程序员小远1 小时前
自动化测试基础知识总结
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
GEO优化小助手1 小时前
2026临沂GEO优化公司实测解析:3家本土机构适配性参考
大数据·人工智能·python
砚底藏山河2 小时前
沪深A股:如何获取基金持股数据
java·python·数据分析·maven
goldenrolan2 小时前
学习型红外控制系统稳定性挂测工装专项总结
软件测试·python·stm32·嵌入式·红外
小小龙学IT2 小时前
Apache Airflow 2.x 深度指南:用 Python 编排一切的现代化工作流引擎
开发语言·python·apache
HappyAcmen3 小时前
7.faiss-cpu向量库安装
python·faiss
你是个什么橙3 小时前
Python入门学习2:Python 基础语法全解析——从代码结构到输入输出
开发语言·python·学习