【SpringBoot】SpringBoot日志框架(四)
日志框架介绍
在开发过程中,我们经常使用到日志来进行排查问题,我们使用的日志框架都是由2部分组成(日志API + 日志实现)
日志API(及日志抽象层)有:SLF4j(Simple Logging Facade for Java)、JCL(Jakarta Commons Logging) 、jboss-logging
日志实现有:Log4j JUL(java.util.logging) Log4j2 Logback
其中slf4j 和 log4j 与 logback 是由同一个人开发。logback是log4j的升级扩展版本
SpringBoot:底层是Spring框架,Spring框架默认是用JCL;
当是SpringBoot选用 slf4j和 logback; logback的使用可以参考:【Log】logback实现每个类和包自定义级别输出
SLF4j使用
可以参考官网:http://www.slf4j.org
使用方法很简单,引入相关jar包,代码调用即可,参考:【Log】SLF4J简单入门
SLF4j + 日志实现
SLF4j + 日志实现 使用结构图如下:
绿色代表自己自己的应用,浅蓝色代表SLF4j接口,蓝色就是具体实现,灰色是jar包
第一列,应用使用slf4j接口,没有日志实现,那么是没有输出内容的
第二列,应用调用slf4j接口,slf4j接口具体实现是logback,实际工作就是有logback进行日志输出
第三列,应用调用slf4j接口,slf4j接口与log4j具体实现之间,多了一层适配层,实际工作是有log4j通过适配层实现的
SLF4j 实现统一日志记录
在实际开发中,我们可能会引用到很多jar包,某些组件依赖于SLF4J以外的日志API,可以通过SLF4j来实现统一日志记录
实现统一日志记录图例如下:
绿色代表自己自己的应用,浅蓝色代表SLF4j接口,蓝色就是具体实现,灰色是jar包
左上图1,应用调用slf4j接口,slf4j接口具体实现是logback,实际工作就是有logback进行日志输出,应用某些组件依赖于SLF4J以外的日志API(Commons loggin、log4j、java.util.loggin)
可以通过一个转换包(桥接包)将SLF4J以外的日志API转换成SLF4JAPI进行日志记录即可。
其他几图分别是slf4j与其他实现jar包的统一日志记录方法
SpringBoot日志
SpringBoot日志关系
SpringBoot启动依赖spring‐boot‐starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter</artifactId>
</dependency>
启动依赖spring‐boot‐starter又依赖了spring-boot-starter-logging
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
spring-boot-starter-logging
总结
1、SpringBoot底层也是使用slf4j+logback的方式进行日志记录
2、SpringBoot也把其他的日志都替换成了slf4j
3、中间替换包(桥接包),通过查看其中代码可以发现LogFactory使用的是SLF4JLogFactory
LogFactory logFactory = new SLF4JLogFactory();
4、如果要引入其他框架?一定要把这个框架的默认日志依赖移除掉
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring‐core</artifactId>
<exclusions>
<exclusion>
<groupId>commons‐logging</groupId>
<artifactId>commons‐logging</artifactId>
</exclusion>
</exclusions>
</dependency>
SpringBoot日志使用
1、简单测试示例
package com.test.springboot; import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner; /**
* SpringBoot单元测试
* <p>
* 可以在测试期间很方便的类似编码一样的自动注入
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestSpringbootApplicationTest { @Autowired
ApplicationContext context; //记录器
Logger logger = LoggerFactory.getLogger(getClass()); @Test
public void contextLoads() {
//System.out.println();
//日志的级别;
//由低到高 trace<debug<info<warn<error //可以调整输出的日志级别;日志就只会在这个级别以以后的高级别生效 logger.trace("这是trace日志...");
logger.debug("这是debug日志..."); //SpringBoot默认给我们使用的是info级别的,没有指定级别的就用SpringBoot默认规定的级别;root
logger.info("这是info日志...");
logger.warn("这是warn日志...");
logger.error("这是error日志...");
} }
运行:
2019-12-08 11:00:17.722 INFO 44381 --- [ main] c.t.s.TestSpringbootApplicationTest : Started TestSpringbootApplicationTest in 4.076 seconds (JVM running for 7.197)
2019-12-08 11:00:18.033 INFO 44381 --- [ main] c.t.s.TestSpringbootApplicationTest : 这是info日志...
2019-12-08 11:00:18.033 WARN 44381 --- [ main] c.t.s.TestSpringbootApplicationTest : 这是warn日志...
2019-12-08 11:00:18.033 ERROR 44381 --- [ main] c.t.s.TestSpringbootApplicationTest : 这是error日志...
2019-12-08 11:00:18.050 INFO 44381 --- [ Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
输出以下项目:
- 日期和时间:毫秒精度,易于排序。
- 日志级别:
ERROR
,WARN
,INFO
,DEBUG
,或TRACE
。 - 进程ID。
- 一个
---
分离器来区分实际日志消息的开始。 - 线程名称:用方括号括起来(对于控制台输出可能会被截断)。
- 记录器名称:这通常是源类名称(通常缩写)。
- 日志消息。
2、日志级别
通过使用TRACE,DEBUG,INFO,WARN,ERROR,FATAL或OFF中的其中之一,可以在Spring中设置所有记录器级别Environment
(例如,在中application.properties
)。该记录器可以通过使用被配置。logging.level.<logger-name>=<level>
level
root
logging.level.root
以下示例显示了中的潜在日志记录设置application.properties
:
logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
3、文件输出
默认情况下,Spring Boot仅记录到控制台,不写日志文件。如果除了控制台输出外还想写日志文件,则需要设置一个logging.file
或logging.path
属性(例如,在中application.properties
)。
下表显示了如何logging.*
一起使用这些属性:
logging.file |
logging.path |
例 | 描述 |
---|---|---|---|
(没有) |
(没有) |
仅控制台记录。 |
|
指定文件名 |
(没有)/有 |
|
写入指定的日志文件。名称可以是确切位置,也可以是相对于当前目录的位置。 |
(没有) |
具体目录 |
|
写入 |
日志文件达到10 MB时会压缩,并且与控制台输出一样,默认情况下会记录ERROR
-level,WARN
-level和INFO
-level消息。可以使用该logging.file.max-size
属性更改大小限制。除非logging.file.max-history
已设置属性,否则以前旋转的文件将无限期存档。
logging.level.com.test=debug #logging.path=
# 不指定路径在当前项目下生成springboot.log日志
# 可以指定完整的路径;
# logging.file=G:/springboot.log # 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
# logging.path=/Users/h__d/Desktop # 时间日志格式
logging.pattern.dateformat=yyyy‐MM # 在控制台输出的日志的格式
logging.pattern.console=%d{yyyy‐MM‐dd} [%thread] %level %logger{50} ‐ %msg%n
# 指定文件中日志输出的格式
logging.pattern.file=%d === [%thread] === %level === %logger{50} ==== %msg%n
Logging System | Customization |
---|---|
Logback |
|
Log4j2 |
|
JDK (Java Util Logging) |
|
logback.xml:直接就被日志框架识别了;
logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot 的高级Profile功能
高级Profile功能
<springProfilename="staging">
<!‐‐ configuration to be enabled when the "staging" profile is active ‐‐> 可以指定某段配置只在某个环境下生效
</springProfile>
使用方法,如在logback.xml中如下配置:
<appender name="stdout"class="ch.qos.logback.core.ConsoleAppender">
<!‐‐
日志输出格式: %d表示日期时间,
%thread表示线程名,
%level:级别
%logger{50} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息,
%n是换行符
‐‐>
<layout class="ch.qos.logback.classic.PatternLayout">
<springProfile name="dev">
<pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ‐‐‐‐> [%thread] ‐‐‐> %level %logger{50} ‐ %msg%n</pattern>
</springProfile>
<springProfile name="!dev">
<pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ==== [%thread] ==== %level %logger{50} ‐ %msg%n</pattern>
</springProfile>
</layout>
</appender>
完整的logback-spring.xml文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- scan="true" 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 -->
<!-- scanPeriod="30 seconds" 设置每30秒自动扫描,若没有指定具体单位则以milliseconds为标准(单位:milliseconds, seconds, minutes or hours) -->
<!-- debug="false"当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<configuration scan="false" scanPeriod="60 seconds" debug="false"> <!--
说明:
1. 文件的命名和加载顺序有关
logback.xml早于application.yml加载,logback-spring.xml晚于application.yml加载
如果logback配置需要使用application.yml中的属性,需要命名为logback-spring.xml
2. logback使用application.yml中的属性
使用springProperty才可使用application.yml中的值 可以设置默认值 -->
<!-- log base path -->
<springProperty scope="context" name="Log_Home" source="logging.path" defaultValue="logs"/>
<springProperty scope="context" name="Log_Level_Root" source="logging.level.root" defaultValue="info"/> <!-- 定义日志文件名称 -->
<property name="appName" value="test-springboot-logging"></property> <!-- ch.qos.logback.core.ConsoleAppender 控制台输出 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<springProfile name="dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
</springProfile>
<springProfile name="!dev">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
</springProfile>
</encoder>
</appender> <!-- DEBUG级别 -->
<appender name="debug—log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${Log_Home}/debug/debug.log</file> <!-- 级别过滤器 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 设置过滤级别 -->
<level>DEBUG</level>
<!-- 用于配置符合过滤条件的操作 -->
<onMatch>ACCEPT</onMatch>
<!-- 用于配置不符合过滤条件的操作 -->
<onMismatch>DENY</onMismatch>
</filter>
<!--
当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名
TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--
滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动
%i:当文件大小超过maxFileSize时,按照i进行文件滚动
-->
<fileNamePattern>${Log_Home}/debug/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--
可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,
且maxHistory是1,则只保存最近7天的文件,删除之前的旧文件。注意,删除旧文件是,
那些为了归档而创建的目录也会被删除。
logback的以时间滚动归档方式而言,按日打包还是按月打包,是根据<fileNamePattern>的内容决定的
-->
<maxHistory>7</maxHistory>
<!--
保持日志历史记录上限为1GB
当超过总大小上限时,最早的档案将被异步删除。该totalSizeCap属性要求maxHistory属性设置为好
-->
<totalSizeCap>1GB</totalSizeCap>
<!--
当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动
注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,
必须配置timeBasedFileNamingAndTriggeringPolicy
-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy> <!-- 日志输出格式: -->
<encoder>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</Pattern>
</encoder>
</appender> <!-- INFO级别 -->
<appender name="info—log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${Log_Home}/info/info.log</file> <filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 设置过滤级别 -->
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${Log_Home}/info/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>7</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</Pattern>
</encoder>
</appender> <!--
logger主要用于存放日志对象,也可以定义日志类型、级别
name:表示匹配的logger类型前缀,也就是包的前半部分
level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR
additivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出,
false:表示只用当前logger的appender-ref,true:
表示当前logger的appender-ref和rootLogger的appender-ref都有效
--> <!-- Spring framework logger -->
<logger name="org.springframework" level="info" additivity="false"></logger> <!--
root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,
要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。
-->
<root level="${Log_Level_Root}">
<appender-ref ref="stdout" />
<appender-ref ref="debug—log" />
<appender-ref ref="info—log" />
</root> </configuration>
4、切换日志框架
可以按照slf4j的日志适配图,进行相关的切换; slf4j+log4j的方式;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐web</artifactId>
<exclusions>
<exclusion>
<artifactId>logback‐classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>log4j‐over‐slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j‐log4j12</artifactId>
</dependency>
【SpringBoot】SpringBoot日志框架(四)的更多相关文章
- SpringBoot与日志框架1(基本使用)
一.日志框架 1.无论在什么系统,日志框架都是一个重要角色,所以理解和用好日志框架是相当重要的:像JDBC一样,日志框架分为接口层的门面和具体的实现组成. 2.市面上的产品: 2.1门面:SLF4J( ...
- SpringBoot与日志框架2(日志内斗)
一.SpringBoot如何引入slf4j+logback框架的呢? 在POM文件中 <dependency> <groupId>org.springframework.boo ...
- SpringBoot日记——日志框架篇
在项目的开发中,日志是必不可少的一个记录事件的组件,所以也会相应的在项目中实现和构建我们所需要的日志框架. 而市面上常见的日志框架有很多,比如:JCL.SLF4J.Jboss-logging.jUL. ...
- SpringBoot整合日志框架LogBack
日志可以记录我们应用程序的运行情况,我们可以通过日志信息去获取应用程序更多的信息.常用处理java日志的组件有:slf4j.log4j.logback.common-logging等.其中log4j是 ...
- Springboot入门-日志框架配置(转载)
默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台. Logback是log4j框架的作者开发的新一代日志框架,它效率更高.能够适应诸多的运行环境,同时天然支 ...
- springboot的日志框架slf4j (使用logback输出日志以及使用)
1.为什么使用logback? ——在开发中不建议使用System.out因为大量的使用会增加资源的消耗.因为使用System.out是在当前线程执行的,写入文件也是写入完毕之后才继续执行下面的程序. ...
- SpringBoot系列之日志框架介绍及其原理简介
SpringBoot系列之日志框架介绍及其原理简介 1.常用日志框架简介 市面上常用日志框架:JUL.JCL.jboss-logging.logback.log4j.log4j2.slf4j.etc. ...
- springboot+logback日志输出企业实践(上)
目录 1.引言 2.logback简介 3. springboot默认日志框架-logback 3.1 springboot示例工程搭建 3.2 日志输出与基本配置 3.2.1 日志默认输出 3.2. ...
- Spring Boot第四弹,一文教你如何无感知切换日志框架?
持续原创输出,点击上方蓝字关注我吧 目录 前言 Spring Boot 版本 什么是日志门面? 如何做到无感知切换? 如何切换? 引入依赖 指定配置文件 日志如何配置? 总结 前言 首先要感谢一下读者 ...
随机推荐
- 详解Linux操作系统的iptables原理及配置
linux网络防火墙 netfilter :内核中的框架,过滤框架,网络过滤器! iptables :实现数据过滤.net.mangle等规则生成的工具 防火墙:硬件.软件.规则(匹配规则.处理办法 ...
- PAT甲级1013题解——并查集+路径压缩
题目分析: 本题初步浏览题目就知道是并查集的模板题,数据输入范围N为1~1000,则M的范围为0~1000^2,通过结构体记录每一对连线的关系,p[]数组记录每个节点的跟,对于k次查询,每次都要重新维 ...
- Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrect date value
Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrect date value: '154 ...
- Spring Boot 之:接口参数校验
Spring Boot 之:接口参数校验,学习资料 网址 SpringBoot(八) JSR-303 数据验证(写的比较好) https://qq343509740.gitee.io/2018/07/ ...
- PHP memcache 环形队列
<?php /** * PHP memcache 环形队列类 * 因业务需要只保留的队列中的Pop和Push,修改过期时间为0即永久 */ class MQueue { pub ...
- Linux 系统结构,nglinx
Linux 系统结构 Linux系统一般有4个主要部分:内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用系统. N ...
- 用数据泵技术实现逻辑备份Oracle 11g R2 数据泵技术详解(expdp impdp)
用数据泵技术实现逻辑备份 from:https://blog.csdn.net/weixin_41078837/article/details/80618916 逻辑备份概述 逻辑备份时创建数据库对象 ...
- haproxy 2.0 dataplaneapi rest api 几个方便的问题排查接口
在使用haproxy 2.0 dataplaneapi的时候,刚开始的时候我们可能需要进行调试,保证我们的配置在我们的系统环境中 是可以使用的,以下是自己在当前学习中为了排查问题会使用的几个api 创 ...
- 重装了服务器,用的是centos/php微信小程序版,centos 命令大全
centos 命令大全 1.关机 (系统的关机.重启以及登出 ) 的命令 shutdown -h now 关闭系统(1) init 0 关闭系统(2) telinit 0 关闭系统(3) shutdo ...
- Excel中筛选两个表中相同的数据和快速填充一列的公式
将两个工作表放在一个文件中,使用if函数和countif函数判断 =if(判断条件countif(区域,条件),真值,[假值]) 实例 =if(countif(Sheet2!$A$1:$A$44,A2 ...