日志框架介绍

  在开发过程中,我们经常使用到日志来进行排查问题,我们使用的日志框架都是由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'  

  输出以下项目:

  • 日期和时间:毫秒精度,易于排序。
  • 日志级别:ERRORWARNINFODEBUG,或TRACE
  • 进程ID。
  • 一个---分离器来区分实际日志消息的开始。
  • 线程名称:用方括号括起来(对于控制台输出可能会被截断)。
  • 记录器名称:这通常是源类名称(通常缩写)。
  • 日志消息。

  2、日志级别

    通过使用TRACE,DEBUG,INFO,WARN,ERROR,FATAL或OFF中的其中之一,可以在Spring中设置所有记录器级别Environment(例如,在中application.properties)。该记录器可以通过使用被配置。logging.level.<logger-name>=<level>levelrootlogging.level.root

    以下示例显示了中的潜在日志记录设置application.properties

 logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error 

  3、文件输出

  默认情况下,Spring Boot仅记录到控制台,不写日志文件。如果除了控制台输出外还想写日志文件,则需要设置一个logging.filelogging.path属性(例如,在中application.properties)。

  下表显示了如何logging.*一起使用这些属性:  

logging.file logging.path 描述

(没有)

(没有)

 

仅控制台记录。

指定文件名

(没有)/有

my.log

写入指定的日志文件。名称可以是确切位置,也可以是相对于当前目录的位置。

(没有)

具体目录

/var/log

写入spring.log指定的目录。名称可以是确切位置,也可以是相对于当前目录的位置。

  日志文件达到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
  4、自定义日志配置
    给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不使用他默认配置的了
    

Logging System Customization

Logback

logback-spring.xmllogback-spring.groovylogback.xml, or logback.groovy

Log4j2

log4j2-spring.xml or log4j2.xml

JDK (Java Util Logging)

logging.properties

    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日志框架(四)的更多相关文章

  1. SpringBoot与日志框架1(基本使用)

    一.日志框架 1.无论在什么系统,日志框架都是一个重要角色,所以理解和用好日志框架是相当重要的:像JDBC一样,日志框架分为接口层的门面和具体的实现组成. 2.市面上的产品: 2.1门面:SLF4J( ...

  2. SpringBoot与日志框架2(日志内斗)

    一.SpringBoot如何引入slf4j+logback框架的呢? 在POM文件中 <dependency> <groupId>org.springframework.boo ...

  3. SpringBoot日记——日志框架篇

    在项目的开发中,日志是必不可少的一个记录事件的组件,所以也会相应的在项目中实现和构建我们所需要的日志框架. 而市面上常见的日志框架有很多,比如:JCL.SLF4J.Jboss-logging.jUL. ...

  4. SpringBoot整合日志框架LogBack

    日志可以记录我们应用程序的运行情况,我们可以通过日志信息去获取应用程序更多的信息.常用处理java日志的组件有:slf4j.log4j.logback.common-logging等.其中log4j是 ...

  5. Springboot入门-日志框架配置(转载)

    默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台. Logback是log4j框架的作者开发的新一代日志框架,它效率更高.能够适应诸多的运行环境,同时天然支 ...

  6. springboot的日志框架slf4j (使用logback输出日志以及使用)

    1.为什么使用logback? ——在开发中不建议使用System.out因为大量的使用会增加资源的消耗.因为使用System.out是在当前线程执行的,写入文件也是写入完毕之后才继续执行下面的程序. ...

  7. SpringBoot系列之日志框架介绍及其原理简介

    SpringBoot系列之日志框架介绍及其原理简介 1.常用日志框架简介 市面上常用日志框架:JUL.JCL.jboss-logging.logback.log4j.log4j2.slf4j.etc. ...

  8. springboot+logback日志输出企业实践(上)

    目录 1.引言 2.logback简介 3. springboot默认日志框架-logback 3.1 springboot示例工程搭建 3.2 日志输出与基本配置 3.2.1 日志默认输出 3.2. ...

  9. Spring Boot第四弹,一文教你如何无感知切换日志框架?

    持续原创输出,点击上方蓝字关注我吧 目录 前言 Spring Boot 版本 什么是日志门面? 如何做到无感知切换? 如何切换? 引入依赖 指定配置文件 日志如何配置? 总结 前言 首先要感谢一下读者 ...

随机推荐

  1. 详解Linux操作系统的iptables原理及配置

    linux网络防火墙 netfilter :内核中的框架,过滤框架,网络过滤器! iptables  :实现数据过滤.net.mangle等规则生成的工具 防火墙:硬件.软件.规则(匹配规则.处理办法 ...

  2. PAT甲级1013题解——并查集+路径压缩

    题目分析: 本题初步浏览题目就知道是并查集的模板题,数据输入范围N为1~1000,则M的范围为0~1000^2,通过结构体记录每一对连线的关系,p[]数组记录每个节点的跟,对于k次查询,每次都要重新维 ...

  3. 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 ...

  4. Spring Boot 之:接口参数校验

    Spring Boot 之:接口参数校验,学习资料 网址 SpringBoot(八) JSR-303 数据验证(写的比较好) https://qq343509740.gitee.io/2018/07/ ...

  5. PHP memcache 环形队列

    <?php   /**  * PHP memcache 环形队列类  * 因业务需要只保留的队列中的Pop和Push,修改过期时间为0即永久  */ class MQueue {     pub ...

  6. Linux 系统结构,nglinx

    Linux 系统结构 Linux系统一般有4个主要部分:内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用系统. N ...

  7. 用数据泵技术实现逻辑备份Oracle 11g R2 数据泵技术详解(expdp impdp)

    用数据泵技术实现逻辑备份 from:https://blog.csdn.net/weixin_41078837/article/details/80618916 逻辑备份概述 逻辑备份时创建数据库对象 ...

  8. haproxy 2.0 dataplaneapi rest api 几个方便的问题排查接口

    在使用haproxy 2.0 dataplaneapi的时候,刚开始的时候我们可能需要进行调试,保证我们的配置在我们的系统环境中 是可以使用的,以下是自己在当前学习中为了排查问题会使用的几个api 创 ...

  9. 重装了服务器,用的是centos/php微信小程序版,centos 命令大全

    centos 命令大全 1.关机 (系统的关机.重启以及登出 ) 的命令 shutdown -h now 关闭系统(1) init 0 关闭系统(2) telinit 0 关闭系统(3) shutdo ...

  10. Excel中筛选两个表中相同的数据和快速填充一列的公式

    将两个工作表放在一个文件中,使用if函数和countif函数判断 =if(判断条件countif(区域,条件),真值,[假值]) 实例 =if(countif(Sheet2!$A$1:$A$44,A2 ...