日志框架介绍

  在开发过程中,我们经常使用到日志来进行排查问题,我们使用的日志框架都是由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. Httpd服务入门知识-Httpd服务常见配置案例之显示服务器版本信息

    Httpd服务入门知识-Httpd服务常见配置案例之显示服务器版本信息 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.httpd配置文件的组成 1>.主要组成 Globa ...

  2. Arthas - 开源的java诊断工具,非常有用

    常用命令 help 查看帮助 help COMMAND 查看指定命令的详细帮助 COMMAND -h 查看指定命令的详细帮助 double tab 查看支持的所有命令 dashboard 查看线程JV ...

  3. Spring AOP中JoinPoint的用法

    Spring JoinPoint的用法 JoinPoint 对象 JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的 ...

  4. cpu绘图的本质:生成图片的二进制(数字)信息

    计算机中图片是用二进制数据表达的.

  5. [RN] React Native FlatList跳转到顶部/底部

    React Native FlatList跳转到顶部/底部 核心代码如下: <ScrollView showsVerticalScrollIndicator={false} contentCon ...

  6. 再见Spring Boot 1.x

    记得很早很早之前有过一次面试,面试前端说自己喜欢JavaScript,然后面试官问,你知道当前JavaScript最新标准和规范吗?我无言以对,因为平时没有关注认真对待这些信息,然后就没有然后了. 或 ...

  7. 埃氏筛优化(速度堪比欧拉筛) + 洛谷 P3383 线性筛素数 题解

    我们一般写的埃氏筛消耗的时间都是欧拉筛的三倍,但是欧拉筛并不好想(对于我这种蒟蒻) 虽然 -- 我 -- 也可以背过模板,但是写个不会的欧拉筛不如写个简单易懂的埃氏筛 于是就有了优化 这个优化还是比较 ...

  8. linux高性能服务器编程 (八) --高性能服务器程序框架

    第八章 高性能服务器编程框架 这一章主要介绍服务器的三个主要模块: I/O处理单元.逻辑单元.存储单元.另外服务器的模型有:C/S模型和P2P模型.虽然服务器模型比较多,但是其核心框架都一样,只是在于 ...

  9. 代码注入/文件包含 弹出Meterpreter

    主要通过 msf 中 exploit 的 web_delivery 模块来实现此功能 0x01 前提背景 目标设备存在远程文件包含漏洞或者命令注入漏洞,想在目标设备上加载webshell,但不想在目标 ...

  10. webgestalt 通路富集分析

    http://www.webgestalt.org/ 通路富集分析 参考 http://www.sci666.com.cn/9596.html