SpringBoot工具库:整合Logback、Log4j2

1、概念

  • log4j是apache实现的一个开源日志组件
  • logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现
  • Log4j2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活
  • slf4j:日志门面,服务于各种各样的日志系,是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如log4j、logback),使用接口的好处是当项目需要更换日志框架的时候,只需要更换jar和配置,不需要更改相关java代码

2、使用条件

        如果你开发的是类库或者嵌入式组件,那么就应该考虑采用SLF4J,因为不可能影响最终用户选择哪种日志系统。在另一方面,如果是一个简单或者独立的应用,确定只有一种日志系统,那么就没有使用SLF4J的必要。假设你打算将你使用log4j的产品卖给要求使用logback的用户时,面对成千上万的log4j调用的修改,相信这绝对不是一件轻松的事情。但是如果开始便使用SLF4J,那么这种转换将是非常轻松的事情。

        说白了,slf4j和common-logging一个意思,就是简单的日志门面,方便我们在不动代码的前提下随意切换我们的日志框架。在部署的时候,选择不同的日志系统包,就可自动转换到不同的日志系统上。

        比如:选择JDK自带的日志系统,则只需要将slf4j-api-1.5.10.jar和slf4j-jdk14-1.5.10.jar放置到classpath中即可,如果中途无法忍受JDK自带的日志系统了,想换成log4j的日志系统,仅需要用slf4j-log4j12-1.5.10.jar替换slf4j-jdk14-1.5.10.jar即可。(当然也需要log4j的jar及配置文件)。当然如果这个时候觉得log4j的性能不是太好,出于性能考虑想换成logback的日志系统的话,也只是需要将logback的core包和classic包替换原来的log4j包就OK(当然也需要logback的配置文件)。

结合各日志实现包使用时提供的jar包情况为:

  • SLF4J和logback结合使用时需要提供的jar:slf4j-api.jar,logback-classic.jar,logback-core.jar
  • SLF4J和log4j结合使用时需要提供的jar:slf4j-api.jar,slf4j-log412.jar,log4j.jar
  • SLF4J和JDK中java.util.logging结合使用时需要提供的jar:slf4j-api.jar,slf4j-jdk14.jar
  • SLF4J和simple(SLF4J本身提供的一个接口的简单实现)结合使用时需要提供的jar:slf4j-api.jar,slf4j-simple.jar

注意,以上slf4j和各日志实现包结合使用时最好只使用一种结合,不然的话会提示重复绑定日志,并且会导致日志无法输出。

3、依赖pom.xml

        log4j2默认会在classpath目录下寻找log4j2.xml、log4j.json、log4j.jsn等名称的文件,如果都没有找到,则会按默认配置输出,也就是输出到控制台,也可以对配置文件自定义位置 

国外的服务器下载速度感人,一般都是用公司内部地址或切换到国内。 修改maven安装目录下中的conf文件夹下的setting.xml文件内容,在<mirrors>节点下新增

<mirror>
  <id>alimaven</id> 
  <name>aliyun maven</name> 
  <url>http://maven.aliyun.com/nexus/content/groups/public/</url> 
  <mirrorOf>central</mirrorOf> 
</mirror>

4、SLF4J+log4j

Logback默认配置的步骤:
 1). 尝试在 classpath下查找文件logback-test.xml;
 2). 如果文件不存在,则查找文件logback.xml;
 3). 如果两个文件都不存在,logback用BasicConfigurator自动对自己进行配置,这会导致记录输出到控制台。

4.1.spring项目

本项目是基于spring项目集成logback日志

pom.xml

         <!-- slf4j依赖 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.12</version>
        </dependency>
        <!-- slf4j自带的简单日志 -->
        <!-- log4j依赖 -->
        <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>

4.2.Springboot项目

        springboot项目,直接引入spring-boot-starter-web依赖即可,因为spring-boot-starter-web包含了spring-boot-starter
spring-boot-starter包含了spring-boot-starter-logging,所以我们只需要引入 web 组件即可。

1)引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2)添加配置在application.yml

# 日志配置
logging:
  # 指定配置文件的路径
  config: classpath:logback-spring.xml
  level:
    # root表示整个项目,默认级别为info
    root: info

 3)logback-spring.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!--spirng boot 默认使用logback,默认会读取resources文件夹下的名为logback.xml的文件 -->
<configuration debug="true">
	<!-- 指定日志文件路径(与当前程序jar包同一目录下) -->
	<property name="LOG_HOME" value="logs/TokenUtils"/>

	<!-- 日志输出格式 -->
	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />

	<!-- 彩色日志格式 -->
	<property name="CONSOLE_LOG_PATTERN"
			  value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint}%clr(%-40.40logger{39}:%4line){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

	<!-- 控制台输出 -->
	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg  %n</pattern>
		</encoder>
	</appender>

	<!--按照每天生成日志文件 -->
	<appender name="DEBUG"  class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${LOG_HOME}/debug/debug.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!--	日志文件输出的文件名-->
			<FileNamePattern>${LOG_HOME}/debug/debug.log.%d{yyyy-MM-dd}_%i</FileNamePattern>
			<!--	日志文件保留天数-->
			<MaxHistory>7</MaxHistory>
			<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<MaxFileSize>1024MB</MaxFileSize>
			</TimeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>DEBUG</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>


	<appender name="ERROR"  class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${LOG_HOME}/order/error/error.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!--日志文件输出的文件名-->
			<FileNamePattern>${LOG_HOME}/error/error.log.%d{yyyy-MM-dd}_%i</FileNamePattern>
			<!--日志文件保留天数-->
			<MaxHistory>15</MaxHistory>
			<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<MaxFileSize>1024MB</MaxFileSize>
			</TimeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>ERROR</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>

	<appender name="INFO"  class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${LOG_HOME}/info.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!--日志文件输出的文件名-->
			<FileNamePattern>${LOG_HOME}/info/info.log.%d{yyyy-MM-dd}_%i</FileNamePattern>
			<!--日志文件保留天数-->
			<MaxHistory>7</MaxHistory>
			<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<MaxFileSize>1024MB</MaxFileSize>
			</TimeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>INFO</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>

    
	<!-- 日志输出级别: application.yml 中的配置会覆盖 logback-spring.xml 中的配置-->
	<!-- 打印INFO级别日志及以上级别日志 -->
	<root level="INFO">
		<appender-ref ref="CONSOLE" />
		<appender-ref ref="DEBUG" />
		<appender-ref ref="ERROR" />
		<appender-ref ref="INFO" />
	</root>

</configuration>
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
    小技巧: 在根pom里面设置统一存放路径,统一管理方便维护
    <properties>
        <log-path>/Users/xx</log-path>
    </properties>
    1. 其他模块加日志输出,直接copy本文件放在resources 目录即可
    2. 注意修改 <property name="${log-path}/log.path" value=""/> 的value模块
-->
<configuration debug="true">
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="log.path" value="logs/${project.artifactId}"/>
	<!-- 控制台输出 -->
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg  %n</pattern>
		</encoder>
	</appender>
	<!-- 按照每天生成日志文件 -->
	<appender name="DEBUG"  class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${log.path}/debug/debug.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!--日志文件输出的文件名-->
			<FileNamePattern>${LOG_HOME}/insurrance/debug/debug.log.%d{yyyy-MM-dd}_%i</FileNamePattern>
			<!--日志文件保留天数-->
			<MaxHistory>7</MaxHistory>
			<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<MaxFileSize>1024MB</MaxFileSize>
			</TimeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>DEBUG</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>


	<appender name="ERROR"  class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${log.path}/error/error.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!--日志文件输出的文件名-->
			<FileNamePattern>${LOG_HOME}/insurrance/error/error.log.%d{yyyy-MM-dd}_%i</FileNamePattern>
			<!--日志文件保留天数-->
			<MaxHistory>15</MaxHistory>
			<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<MaxFileSize>1024MB</MaxFileSize>
			</TimeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>ERROR</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>

	<appender name="INFO"  class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${log.path}/info/info.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!--日志文件输出的文件名-->
			<FileNamePattern>${LOG_HOME}/insurrance/info/info.log.%d{yyyy-MM-dd}_%i</FileNamePattern>
			<!--日志文件保留天数-->
			<MaxHistory>7</MaxHistory>
			<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<MaxFileSize>1024MB</MaxFileSize>
			</TimeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>INFO</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>


	<appender name="WARN"  class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${log.path}/warn/warn.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!--日志文件输出的文件名-->
			<FileNamePattern>${LOG_HOME}/insurrance/warn/warn.log.%d{yyyy-MM-dd}_%i</FileNamePattern>
			<!--日志文件保留天数-->
			<MaxHistory>7</MaxHistory>
			<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<MaxFileSize>1024MB</MaxFileSize>
			</TimeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>WARN</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>

	<!-- 日志输出级别 -->
	<root level="INFO">
		<appender-ref ref="DEBUG" />
		<appender-ref ref="ERROR" />
		<appender-ref ref="INFO" />
		<appender-ref ref="WARN" />
		<appender-ref ref="STDOUT" />
	</root>
</configuration>

${project.artifactId}读取的是项目下pom.xml文件中项目信息,通过变量方式,避免硬编码 

5、SLF4J+Log4j

SpringBoot整合Log4j2步骤:
1)删除spring-boot-starter-parent默认使用spring-boot-starter-logging依赖
2)在pom.xml中增加spring-boot-starter-log4j2依赖
3)创建log4j2.xml文件即可
4)执行,指定目录会生成相应的log文件

1)加入依赖

springboot默认使用的是logback

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions><!-- 去掉springboot默认配置 -->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency> <!-- 引入log4j2依赖 -->
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

2)log4j2.xml 

在src.java.main.resources目录下创建log4j2.xml文件 log4j2.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="fatal">
    <Properties>
        <!--配置日志文件夹的名称和生成路径,可以是D:\xx-logs,如果直接写 xx-logs 就是项目的根目录 -->
        <Property name="baseDir" value="dongrong-logs"/>
    </Properties>

<!--定义appender-->
<appenders>
    <!--控制台的输出配置-->
    <console name="Console" target="SYSTEM_OUT">
        <!-- 设置控制台只输出INFO及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
        <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
        <!--输出日志的格式-->
        <PatternLayout pattern="${log_pattern}"/>
    </console>

    <!-- 所有的日志信息会打印到此文件中,append=false每次启动程序会自动清空 -->
    <!-- <File name="all" fileName="${file_path}/all.log" append="true">
        <PatternLayout pattern="${log_pattern}"/>
    </File>-->
    <!--
    该RollingFile存储INFO级别的日志,
    默认存储到 fileName 文件中
    超过SizeBasedTriggeringPolicy的设定值,则存储到 filePattern 文件中
    -->
    <RollingFile name="RollingFileInfo" fileName="${file_path}/info.log" filePattern="${file_path}/${backup_folder}/info${backup_file_suffix}">
        <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
        <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
        <!-- 写入日志文件的模板 -->
        <PatternLayout pattern="${log_pattern}"/>
        <Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,超过该数量,会滚动删除前面的记录 -->
            <DefaultRolloverStrategy max="5">
				<Delete basePath="" maxDepth="">
					<IfFileName glob="*.log" />
					<IfLastModified age="*1d" />
				</Delete>
			</DefaultRolloverStrategy>
            <!--多长时间滚动一次-->
            <TimeBasedTriggeringPolicy interval="2 hour" />
            <!-- 一个日志文件的最大大小 -->
            <SizeBasedTriggeringPolicy size="${file_max_size}"/>
        </Policies>
    </RollingFile>
    <RollingFile name="RollingFileWarn" fileName="${file_path}/warn.log" filePattern="${file_path}/${backup_folder}/warn${backup_file_suffix}">
        <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
        <PatternLayout pattern="${log_pattern}"/>
        <Policies>
            <TimeBasedTriggeringPolicy/>
            <SizeBasedTriggeringPolicy size="${file_max_size}"/>
        </Policies>
    </RollingFile>
    <RollingFile name="RollingFileError" fileName="${file_path}/error.log" filePattern="${file_path}/${backup_folder}/error${backup_file_suffix}">
        <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
        <PatternLayout pattern="${log_pattern}"/>
        <Policies>
            <TimeBasedTriggeringPolicy/>
            <SizeBasedTriggeringPolicy size="${file_max_size}"/>
        </Policies>
    </RollingFile>
</appenders>
<!-- 只有定义了logger并使用appender-ref,appender才会生效 -->
<loggers>
    <!--过滤掉spring和hibernate的一些无用的debug信息-->
    <logger name="org.springframework" level="INFO"/>
    <logger name="org.mybatis" level="INFO">
        <!-- 添加如下设置,控制台会再打印一次 -->
        <AppenderRef ref="Console"/>
    </logger>
    <root level="INFO">
        <appender-ref ref="Console"/>
        <appender-ref ref="RollingFileInfo"/>
        <appender-ref ref="RollingFileWarn"/>
        <appender-ref ref="RollingFileError"/>
    </root>
</loggers>
</Configuration>

3)yml中设置配置文件路径

logging:
  config: classpath:log4j2.xml

配置参数详解 

1)输出源

  • CONSOLE(输出到控制台)

  • FILE(输出到文件

6、Java测试

6.1、使用方式

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class Slf4jTest
{
    private static Logger logger = LoggerFactory.getLogger(Slf4jTest.class);
 
    @Test
    public void test()
    {
        logger.debug("debug()方法,看下这里logger的实例是:{}", logger.getClass());
        logger.info("info()方法,看下这里logger的实例是:{}", logger.getClass());
        logger.error("error()方法,看下这里logger的实例是:{}", logger.getClass());
    }
}

6.2、验证

使用logback来输出日志:去掉pom文件中多余的日志框架的依赖,添加logback-core和logback-classic的依赖到pom中,运行上面的测试,控制台输出如下 

[main] INFO  com.ykx.insurance.Slf4jTest - info()方法:logger的实例:class ch.qos.logback.classic.Logger  
[main] ERROR com.ykx.insurance.Slf4jTest - error()方法:logger的实例:class ch.qos.logback.classic.Logger  

使用slf4j输出日志:slf4j也给我们提供了一个简单的simple日志框架。注释掉别的pom依赖,只打开slf4j-simple的依赖。运行上面的测试控制台输出如下:

[main] INFO org.linkinpark.commons.slf4j.Slf4jTest - info()方法:logger的实例是:class org.slf4j.impl.SimpleLogger
[main] ERROR org.linkinpark.commons.slf4j.Slf4jTest - error()方法:logger的实例是:class org.slf4j.impl.SimpleLogger

小结

        通过上面这个比较详细的例子,我们看到了,我们使用slf4j来统一管理的我们的代码,我们不停的切换了多种日志框架来作为我们的日志输出,但是我们的业务代码,Java类中的那些日志输出代码一点都不用去改,这也真是slf4j最迷人的地方。它完美的整合了自己的一个简单日志,JDK自带的日志,log4j,logback,common-logging。只不顾我们在转换日志输出的时候,可能会用到一些中间的桥接jar包。

当然,我仔细有看过这些桥接类的maven依赖,比如:

slf4j-log4j12:它本身就会依赖slf4j-api和log4j,maven依赖的jar包是可以传递的,所以也可以不用人工的去添加这些jar包的。
slf4j-jcl:它本身就会依赖slf4j-api和common-logging,maven依赖的jar包是可以传递的,所以也可以不用人工的去添加这些jar包的。
slf4j-jdk14:它本身就会依赖slf4j-api,maven依赖的jar包是可以传递的,所以也可以不用人工的去添加这些jar包的。

SLF4J还有一个比较直接的吸引人的地方就是Java代码中输出日志的Java写法,性能很好,如果配合logback使用据说是log4j性能的10倍,特别是有字符串连接的时候。

在使用Commons Logging时,我们经常会看到以下方法的写法:

例如:

if (logger.isDebugEnabled())
{
    logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}

        存在isDebugEnabled()的判断逻辑是为了在避免多余的字符串拼接,即如果不存在isDebugEnabled()判断,即使当前日志级别为ERROR时,在遇到logger.info()调用时,它还会先拼接日志消息的字符串,然后进入该方法内,才发现这个日志语句不用打印。而这种多余的拼接不仅浪费了多余的CPU操作,而且会增加GC的负担。SLF4J则提供以下的方式来解决这个问题:

logger.info("Loading XML bean definitions from {}", encodedResource.getResource());

总结如下:

1、slf4j是java的一个日志门面,实现了日志框架一些通用的api,log4j和logback是具体的日志框架。

2、他们可以单独的使用,也可以绑定slf4j一起使用。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 添加logback-spring.xml文件 在src/main/resources目录下创建一个名为logback-spring.xml的文件,将下面的代码复制并粘贴进去。 ``` <?xml version="1.0" encoding="utf-8" ?> <configuration> <!-- 确定打印的日志级别 --> <timestamp key="byDay" datePattern="yyyyMMdd" /> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} -%msg%n</pattern> </encoder> </appender> <!-- 输出到本地文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/springboot2.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/springboot2.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} -%msg%n</pattern> </encoder> </appender> <!-- root级别日志处理器 --> <root level="info"> <appender-ref ref="CONSOLE" /> <appender-ref ref="FILE" /> </root> <!-- 配置包日级别日志处理器 --> <logger name="com.example" level="debug" additivity="false"> <appender-ref ref="CONSOLE" /> <appender-ref ref="FILE" /> </logger> </configuration> ``` 2. 配置文件参数 在application.properties或application.yml文件中添加以下参数: - logging.config:指定logback-spring.xml配置文件路径,如果不指定将使用默认的日志配置。 - logging.path:指定日志文件存放路径,必须是一个相对目录。例如:logging.path=log 相当于在项目根目录下创建了一个log文件夹,日志将输出到该文件夹中。如果没有设置该参数,则日志将输出到控制台。 ``` #以配置文件的方式加载日志框架,默认使用logback-spring.xml作为配置文件 logging.config=classpath:logback-spring.xml #指定日志存放的相对路径 logging.path=log ``` 3. 在代码中使用日志输出 在需要输出日志的类中使用注入方式加载日志,在方法中使用对应的日志级别输出日志。 ``` @Component public class TestController { private static final Logger logger = LoggerFactory.getLogger(TestController.class); @RequestMapping("/test") public String test() { logger.debug("这是一条debug日志"); logger.info("这是一条info日志"); logger.warn("这是一条warn日志"); logger.error("这是一条error日志"); return "test"; } } ``` 运行项目,打开控制台或者查看日志文件,可以看到日志已经输出成功。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值