SpringBoot2.x整合slf4j+logback日志框架

Posted 孔子-说

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot2.x整合slf4j+logback日志框架相关的知识,希望对你有一定的参考价值。

目录

1、Slf4j及Logback简介

2、日志级别

3、maven依赖

3.1 springboot2 maven配置文件

3.2 普通maven项目的配置文件

4、logback、springboot配置说明

4.1 logback.xml 和 logback-spring.xml 的区别

4.2 logback.xml 配置文件的加载机制

4.3 SpringBoot结合logback配置说明

4.3.1 logback配置说明

4.3.2 SpringBoot 配置说明

5、Logback 配置详解

5.1 根节点

5.2 子节点

5.3 子节点

5.4 子节点

5.5 子节点

5.5.1 ConsoleAppender,把日志输出到控制台

5.5.2 FileAppender,把日志添加到文件

5.5.3 RollingFileAppender,滚动记录文件

5.5.4 SocketAppender、SMTPAppender、DBAppender

5.6 子节点

5.7 子节点

5.8 配置注意事项

5.9 配置示例

6、使用技巧

6.1 使用springProfile灵活配置各种环境

6.2 springProperty读取spring配置文件属性

6.3 自定义配置文件名称时,本地调试正常,生产环境异常

7、logback-spring.xml常用配置

7.1 logback配置1

7.2 logback配置2

7.3 logback配置3

7.4 logback配置4

7.5 logback配置5

7.6 logback配置6

7.7 logback配置7

8、JAVA使用logback接口输出日志


SpringBoot对所有内部日志使用通用日志记录,但保留底层日志实现。为Java Util Logging、Log4J2和Logback提供了默认配置。在不同的情况下,日志记录器都预先配置为使用控制台输出,同时还提供可选的文件输出。默认情况下,SpringBoot使用Logback进行日志记录。

1、Slf4j及Logback简介

SLF4J(Simple logging Facade for Java)是由log4j创始人设计的日志标准接口,意思为简单日志门面,它是把不同的日志系统的实现进行了具体的抽象化,只提供了统一的日志使用接口,使用时只需要按照其提供的接口方法进行调用即可,由于它只是一个接口,并不是一个具体的可以直接单独使用的日志框架,所以最终日志的格式、记录级别、输出方式等都要通过接口绑定的具体的日志系统来实现,这些具体的日志系统就有log4j,logback,java.util.logging等,它们才实现了具体的日志系统的功能。SLF4J的官方网站为http://www.slf4j.org。

  • 注意:要始终使用SLF4J的接口写入日志,使用Logback只需要配置,若需要替换日志组件的时候将不需要修改具体日志代码。

Logback是由log4j创始人设计的又一个开源日志组件,做为Slf4j的默认实现。logback当前分成三个模块:logback-core、logback- classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个 改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging。logback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能。 Logback的官方网站为 http://logback.qos.ch。

2、日志级别

日志级别有8个(从高到低): OFF(关闭)FATAL(致命)ERROR(错误)WARN(警告)INFO(信息)DEBUG(调试)TRACE(跟踪)ALL(所有),默认的日志配置在消息写入时将消息回显到控制台。默认情况下,将记录错误级别、警告级别和信息级别的消息。

  • ALL 最低等级的,用于打开所有日志记录。
  • TRACE 很低的日志级别,一般不会使用,可以用来追踪详细的程序运行流,比如程序的运行过程中,运行到了哪一个方法,进入了哪一条分支。通过trace程序的运行流程,可以判断程序是否按照期望的逻辑在运行。
  • DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,这类日志往往用在判断是否有出现bug的场景,且往往记录了代码运行的详细信息,比如方法调用传入的参数信息等。
  • INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。
  • WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。用来警告程序进入了一个特殊的状态,在该状态下程序可以继续运行,但是不建议让程序进入该状态,因为该状态可能导致结果出现问题。
  • ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。
  • FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。
  • OFF 最高等级的,用于关闭所有日志记录。

Log4j定义了上述8个级别的log,而SLF4J和Logback没有定义FATAL级别(Logback does not have a FATAL level. It is mapped to ERROR。Logback没有FATAL致命级别。它被映射到ERROR错误级别)

如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。

  • 建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。

3、maven依赖

SpringBoot采用的默认的日志框架就是slf4j+logback,所以配置的时候无需在pom.xml中添加依赖,我们只需要手动添加配置文件就好(即便不添加SpringBoot也默认开启了)。

3.1 springboot2 maven配置文件

maven项目只要集成了springboot,就默认包含了slf4j和logback的配置,可以点开springboot的配置看一下。

1)找到spring-boot-starter-parent配置,如下。

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.2.2.RELEASE</version>
   <relativePath/> <!-- lookup parent from repository -->
</parent>

2)按住ctrl键,鼠标左键点击artifactId标签中的spring-boot-starter-parent,进入starter parent的pom文件,找到该文件的parent部分,按住ctrl键,鼠标左键点击spring-boot-dependencies,如下图所示。 

3) 上一步骤之后进入了springboot-dependendies的pom文件,搜索找到spring-boot-starter的依赖,按住ctrl键,鼠标左键点击spring-boot-starter,如下图。

4) 上一步骤之后进入了spring-boot-starter的pom文件,搜索找到spring-boot-starter-logging的依赖,按住ctrl键,鼠标左键点击spring-boot-starter-logging,如下图。

5) 上一步骤之后进入了spring-boot-starter-logging的pom文件,找到dependencies部分,可以看到已经包括了默认的日志依赖,如下图。

3.2 普通maven项目的配置文件

若为非springboot的maven项目,需要引入相关的依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>demo</artifactId>
        <groupId>com.kz</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>thread</artifactId>

    <dependencies>
        <!--https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-access -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>

</project>

4、logback、springboot配置说明

4.1 logback.xml 和 logback-spring.xml 的区别

logback.xml 和 logback-spring.xml 都可以用来配置logback,但是2者的加载顺序是不一样的(logback.xml 由日志框架加载,而 logback-spring.xml 由SpringBoot来加载)。

  • ①logback.xml--->②application.properties--->③logback-spring.xml

可以看到 logback.xml 加载早于 application.properties,所以如果你在logback.xml使用了变量时,而恰好这个变量是写在application.properties时,那么就会获取不到,只要改成logback-spring.xml就可以解决,所以最好将配置文件命名为logback-spring.xml。

logback-spring.xml这样的命名方式是官方推荐的,使用 logback.xml 的命名直接被日志框架识别了,而使用logback-spring.xml这样的命名日志框架就不直接加载,而由SpringBoot来加载,这样在日志配置文件中可以使用<springProfile>标签,可以指定某配置项只在某个环境下生效(即开发环境dev或是生产环境pro等)

4.2 logback.xml 配置文件的加载机制

logback在启动时,日志框架会根据以下步骤寻找 logback.xml 配置文件(而 logback-spring.xml 是由springboot加载的)

  • ①在classpath中寻找logback-test.xml文件;
  • ②如果找不到logback-test.xml,则在 classpath中寻找logback.groovy文件;
  • ③如果找不到 logback.groovy,则在classpath中寻找logback.xml文件;
  • 如果上述的文件都找不到,则logback会使用JDK的SPI机制查找 META-INF/services/ch.qos.logback.classic.spi.Configurator中的 logback 配置实现类,这个实现类必须实现Configuration接口,使用它的实现来进行配置。
  • 如果上述操作都不成功,logback 就会使用它自带的 BasicConfigurator 来配置,并将日志输出到console。

4.3 SpringBoot结合logback配置说明

4.3.1 logback配置说明

位置(resources目录下)说明
官方推荐logback-spring.xml默认读取resources目录下的 logback-spring.xml
自定义位置log/logback-spring.xmlapplication.yml或者properties中配置: logging.config=classpath:log/logback-spring.xml
logback.xmllogback.xml默认读取resources目录下的 logback.xml
logback.xml位置log/logback.xmlapplication.yml或者properties中配置: logging.config=classpath:log/logback.xml,

一般情况下,使用官方的推荐配置,在resources目录下新建logback-spring.xml,填写内容如下(只输出日志到控制台)。使用官方推荐配置时,application.yml或者properties中可以不加配置。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志存放路径 -->
	<property name="log.path" value="/home/logs" />
    <!-- 日志输出格式 -->
	<property name="log.pattern" value="%dHH:mm:ss.SSS [%thread] %-5level %logger20 - [%method,%line] - %msg%n" />

	<!-- 控制台输出 -->
	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>$log.pattern</pattern>
		</encoder>
	</appender>

	<root level="info">
		<appender-ref ref="console" />
	</root>
</configuration> 

4.3.2 SpringBoot 配置说明

logback文件名为logback-spring.xml,logback.xml,且位于resources目录下时,可以不添加任何配置。否则至少需要在配置application.properties文件中添加属性 logging.config=classpath:log/logback-spring.xml 指定日志配置文件的位置。application.yml示例如下:

# 日志配置
logging:
  # 指定配置文件的路径
  config: classpath:log/logback-spring.xml
  level:
    # root表示整个项目,默认级别为info
    root: info
    # com.demo包的日志级别为debug
    com.founder: debug
    # org.springframework包的日志级别为warn
    org.springframework: warn

5、Logback 配置详解

Logback使用主要依赖于Logger、Appender 和 Layout 这三个类之上。

  • Logger: 记录日志是使用,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。
  • Appender: 用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等。
  • Layout: 负责把事件转换成字符串,格式化的日志信息的输出。

主要标签的用处:

  • appender,负责定义日志的输出目的地(控制台、日志文件、滚动日志文件,其他如logstash等)。
  • encoder负责定义日志的输出样式和字符编码,如果在控制台出现?????或乱码,则指定编码(一般是UTF-8)就好了。
  • filter负责过滤日志,即使logger传来了dubug级别以上的日志,如果filter中设定了级别为info,则该appender只会将info级别及以上的日志输出到目的地。
  • rollingPolicy负责制定日志文件的滚动规则,是根据日志文件大小还是根据日期进行滚动。
  • logger,负责定义我们实际代码中使用的logger。logger中有一个非常重要的属性name,name必须指定。在logback中,logger有继承关系,而所有的logger的祖先是root。

5.1 根节点<configuration>

包含下面三个属性:

  • scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
  • scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
  • debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
    <!--其他配置省略--> 
</configuration> 

5.2 子节点<contextName>

用来设置上下文名称,每个logger都关联到logger上下文,默认上下文名称为default。但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。

<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
     <contextName>myAppName</contextName> 
    <!--其他配置省略-->
</configuration>    

5.3 子节点<property>

用来定义变量值,它有两个属性name和value,通过<property>定义的值会被插入到logger上下文中,可以使“$”来使用变量。name: 变量的名称,value: 变量定义的值。

<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
   <property name="APP_Name" value="myAppName" /> 
   <contextName>$APP_Name</contextName> 
   <!--其他配置省略--> 
</configuration>

5.4 子节点<timestamp>

获取时间戳字符串,有两个属性key和datePattern

  • key: 标识此<timestamp> 的名字;
  • datePattern: 设置将当前时间(解析配置文件的时间)转换为字符串的模式,遵循java.txt.SimpleDateFormat的格式。
<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
  <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/> 
  <contextName>$bySecond</contextName> 
  <!-- 其他配置省略--> 
</configuration>

5.5 子节点<appender>

负责写日志的组件,它有两个必要属性name和class。name指定appender名称,class指定appender的全限定名。

5.5.1 ConsoleAppender,把日志输出到控制台

有以下子节点,示例配置表示把>=DEBUG级别的日志都输出到控制台

  • <encoder>:对日志进行格式化。(具体参数稍后讲解 )
  • <target>:字符串System.out(默认)或者System.err。
<configuration> 
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
      <encoder> 
         <pattern>%-4relative [%thread] %-5level %logger35 - %msg %n</pattern> 
      </encoder> 
   </appender> 

   <root level="DEBUG"> 
      <appender-ref ref="STDOUT" /> 
   </root> 
</configuration>

5.5.2 FileAppender,把日志添加到文件

有以下子节点,示例配置表示把>=DEBUG级别的日志都输出到testFile.log

  • <file>:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。
  • <append>:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。
  • <encoder>:对记录事件进行格式化。(具体参数稍后讲解 )
  • <prudent>:如果是 true,日志会被安全的写入文件,即使其他的FileAppender也在向此文件做写入操作,效率低,默认是 false。
<configuration> 
  <appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
    <file>testFile.log</file> 
    <append>true</append> 
    <encoder> 
      <pattern>%-4relative [%thread] %-5level %logger35 - %msg%n</pattern> 
    </encoder> 
  </appender> 

  <root level="DEBUG"> 
    <appender-ref ref="FILE" /> 
  </root> 
</configuration>

5.5.3 RollingFileAppender,滚动记录文件

滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。有以下子节点:

  • <file>:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。
  • <append>:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。
  • <rollingPolicy>:当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类。

<rollingPolicy>属性class定义具体的滚动策略类,有3类。

1)class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"是最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。有以下子节点:

  • 1.1)<fileNamePattern>:必要节点,包含文件名及“%d”转换符,“%d”可以包含一个java.text.SimpleDateFormat指定的时间格式,如:%dyyyy-MM。如果直接使用 %d,默认格式是 yyyy-MM-dd。RollingFileAppender的file子节点可有可无,通过设置file,可以为活动文件和归档文件指定不同位置,当前日志总是记录到file指定的文件(活动文件),活动文件的名字不会改变;如果没设置file,活动文件的名字会根据fileNamePattern 的值,每隔一段时间改变一次。“/”或者“\\”会被当做目录分隔符。
  • 1.2)<maxHistory>:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,且<maxHistory>是6,则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件时,那些为了归档而创建的目录也会被删除。

2)class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy": 查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender 触发当前活动文件滚动。有以下子节点:

  • 2.1)<maxFileSize>:这是活动文件的大小,默认值是10MB。
  • 2.2)<prudent>:当为true时,不支持FixedWindowRollingPolicy。支持TimeBasedRollingPolicy,但是有两个限制,1不支持也不允许文件压缩,2不能设置file属性,必须留空。
  • 2.3)<triggeringPolicy >: 告知 RollingFileAppender 合适激活滚动。

3)class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy" 根据固定窗口算法重命名文件的滚动策略。有以下子节点:

  • 3.1)<minIndex>:窗口索引最小值
  • 3.2)<maxIndex>:窗口索引最大值,当用户指定的窗口过大时,会自动将窗口设置为12。
  • 3.3)<fileNamePattern>:必须包含“%i”例如,假设最小值和最大值分别为1和2,命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。还可以指定文件压缩选项,例如,mylog%i.log.gz 或者 没有log%i.log.zip
<configuration> 
   <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 
         <fileNamePattern>logFile.%dyyyy-MM-dd.log</fileNamePattern> 
         <maxHistory>30</maxHistory> 
      </rollingPolicy> 
      <encoder> 
         <pattern>%-4relative [%thread] %-5level %logger35 - %msg%n</pattern> 
      </encoder> 
   </appender> 

   <root level="DEBUG"> 
      <appender-ref ref="FILE" /> 
   </root> 
</configuration>

上述配置表示每天生成一个日志文件,保存30天的日志文件。

5.5.4 SocketAppender、SMTPAppender、DBAppender

SocketAppender、SMTPAppender、DBAppender、SyslogAppender、SiftingAppender等并不常用,这里就不详解了。大家可以参考官方文档(http://logback.qos.ch/documentation.html),还可以编写自己的Appender。

5.6 子节点<logger>

用来设置某一个包或具体的某一个类的日志打印级别、以及指定<appender>。<logger>仅有一个name属性,一个可选的level和一个可选的additivity属性。可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。

  • 属性name: 用来指定受此logger约束的某一个包或者具体的某一个类。
  • 属性level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。 如果未设置此属性,那么当前logger将会继承上级的级别。
  • 属性additivity: 是否向上级logger传递打印信息。默认是true。同<logger>一样,可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。

5.7 子节点<root>

它也是<logger>元素,是根logger,所有<logger>的上级。只有一个level属性,因为name已经被命名为"root",且已经是最上级了。

  • level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,不能设置为INHERITED或者同义词NULL。 默认是DEBUG。

5.8 配置注意事项

1)必需appender 配置为rolling的才能滚动

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

2)在FixedWindowRollingPolicy里面不能配置%dyyyy-MM-dd, 如果配置了的话,会导致滚动失败,不仅不能生成滚动文件,当前文件也不再写入,只能且必需配置%i。FixedWindowRollingPolicy可以和SizeBasedTriggeringPolicy配合使用。

<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
     <FileNamePattern>tests.%i.log.zip</FileNamePattern>
     <MinIndex>1</MinIndex>
     <MaxIndex>3</MaxIndex>
</rollingPolicy>

<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
     <MaxFileSize>5MB</MaxFileSize>
</triggeringPolicy>

3)TimeBasedRollingPolicy 不能和SizeBasedTriggeringPolicy配合使用,如果两个同时配置,在达到最大文件大小的时候,会导致即不会生成滚动文件,当前文件也不再写入。

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">        
    <fileNamePattern>logFile.%dyyyy-MM-dd.log</fileNamePattern>          
    <maxHistory>30</maxHistory>         
</rollingPolicy>

4)springProfile 配置为dev时, 输出端可以为console, 但配成prod时, 切记关闭console输出。

5)SpringBoot默认读取resources下的,若是放到了自定义的路径下, 则需要在application.yml中配置其具体路径。

6)有时候需要打印低级别(如debug)的日志,不要把<root level=“info”>改成<root level=“DEBUG”>,这样日志会出现很多其他框架的输出的信息,不利于排查日志,可以单独给某个包指定日志输出级别,这样只有被设置为debug模式的包下的代码会打印debug日志,其他包还按照设置的默认级别如info打印日志。

5.9 配置示例

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration  scan="true" scanPeriod="10 seconds">

    <!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->

    <contextName>logback</contextName>
    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“$”来使用变量。 -->
    <property name="log.path" value="D:/nmyslog/nmys" />

    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="$CONSOLE_LOG_PATTERN:-%clr(%dyyyy-MM-dd HH:mm:ss.SSS)faint %clr($LOG_LEVEL_PATTERN:-%5p) %clr($PID:- )magenta %clr(---)faint %clr([%15.15t])faint %clr(%-40.40logger39)cyan %clr(:)faint %m%n$LOG_EXCEPTION_CONVERSION_WORD:-%wEx"/>


    <!--输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>info</level>
        </filter>
        <encoder>
            <Pattern>$CONSOLE_LOG_PATTERN</Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>


    <!--输出到文件-->

    <!-- 时间滚动输出 level为 DEBUG 日志 -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>$log.path/log_debug.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%dyyyy-MM-dd HH:mm:ss.SSS [%thread] %-5level %logger50 - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志归档 -->
            <fileNamePattern>$log.path/debug/log-debug-%dyyyy-MM-dd.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录debug级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 INFO 日志 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>$log.path/log_info.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%dyyyy-MM-dd HH:mm:ss.SSS [%thread] %-5level %logger50 - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>$log.path/info/log-info-%dyyyy-MM-dd.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 WARN 日志 -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>$log.path/log_warn.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%dyyyy-MM-dd HH:mm:ss.SSS [%thread] %-5level %logger50 - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>$log.path/warn/log-warn-%dyyyy-MM-dd.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录warn级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>


    <!-- 时间滚动输出 level为 ERROR 日志 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>$log.path/log_error.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%dyyyy-MM-dd HH:mm:ss.SSS [%thread] %-5level %logger50 - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>$log.path/error/log-error-%dyyyy-MM-dd.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录ERROR级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!--
        <logger>用来设置某一个包或者具体的某一个类的日志打印级别、
        以及指定<appender>。<logger>仅有一个name属性,
        一个可选的level和一个可选的addtivity属性。
        name:用来指定受此logger约束的某一个包或者具体的某一个类。
        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
              还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
              如果未设置此属性,那么当前logger将会继承上级的级别。
        addtivity:是否向上级logger传递打印信息。默认是true。
    -->
    <!--<logger name="org.springframework.web" level="info"/>-->
    <!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>-->
    <!--
        使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
        第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
        第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
     -->


    <!--
        root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
        不能设置为INHERITED或者同义词NULL。默认是DEBUG
        可以包含零个或多个元素,标识这个appender将会添加到这个logger。
    -->

    <!--开发环境:打印控制台-->
    <springProfile name="dev">
        <logger name="com.nmys.view" level="debug"/>
    </springProfile>

    <root level="info">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="DEBUG_FILE" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="WARN_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>

    <!--生产环境:输出到文件-->
    <!--<springProfile name="pro">-->
        <!--<root level="info">-->
            <!--<appender-ref ref="CONSOLE" />-->
            <!--<appender-ref ref="DEBUG_FILE" />-->
            <!--<appender-ref ref="INFO_FILE" />-->
            <!--<appender-ref ref="ERROR_FILE" />-->
            <!--<appender-ref ref="WARN_FILE" />-->
        <!--</root>-->
    <!--</springProfile>-->

</configuration>

6、使用技巧

6.1 使用springProfile灵活配置各种环境

该 <springProfile> 标签允许我们更加灵活配置文件,可选地包含或排除配置部分。元素中的任何位置均支持轮廓部分。使用该name属性指定哪个配置文件接受配置。可以使用逗号分隔列表指定多个配置文件。

<springProfile name="dev">
    <!-- 开发环境时激活 -->
</springProfile>

<springProfile name="dev,test">
    <!-- 开发,测试的时候激活-->
</springProfile>

<springProfile name="!prod">
    <!-- 当 "生产" 环境时,该配置不激活-->
</springProfile>

 实例:

<!-- 开发环境日志级别为DEBUG --><springProfile name="dev">
    <root level="DEBUG">
        <appender-ref ref="FILE"/>
        <appender-ref ref="STDOUT"/>
    </root>
</springProfile>

<!-- 测试环境日志级别为INFO -->
<springProfile name="test">
    <root level="INFO">
        <appender-ref ref="FILE"/>
        <appender-ref ref="STDOUT"/>
    </root>
</springProfile>

6.2 springProperty读取spring配置文件属性

若使用 logback.xml 作为logback的配置文件名称时,因为logback.xml的加载顺序早于springboot的application.yml (或application.properties) ,通过<property name="log.path" value="$path.log"/>读不到path.log的值,这时候可以有两种解决方案:

方案一:将logback.xml 改名为logback-spring.xml,这个名字的文件是通过springboot加载的,可以读取到springboot的 application.yml 中的配置属性。

方案二:通过springProperty标签来引用,<springProperty scope="context" name="log.path" source="path.log"/>,注意这里没有加 $ 符号。

6.3 自定义配置文件名称时,本地调试正常,生产环境异常

官方推荐名称是logback-spring.xml,若使用 spring-logback.xml 等自定义名称定义配置文件时,在本地调试可以正常写入日志文件,但打包发布到tomcat以后,有时候会出现日志配置不生效的问题,建议将日志配置文件名改为 logback-spring.xml (Spring Boot官方推荐优先使用带有**-spring.xml 的文件名作为你的日志配置)。

7、logback-spring.xml常用配置

7.1 logback配置1

只配置root

<configuration>   
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">   
    <!-- encoder 默认配置为PatternLayoutEncoder -->   
    <encoder>   
      <pattern>%dHH:mm:ss.SSS [%thread] %-5level %logger36 - %msg%n</pattern>   
    </encoder>   
  </appender>   
   
  <root level="INFO">             
    <appender-ref ref="STDOUT" />   
  </root>     
     
</configuration>  

7.2 logback配置2

带有loger的配置,不指定级别,不指定appender,

<configuration>   
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">   
    <!-- encoder 默认配置为PatternLayoutEncoder -->   
    <encoder>   
      <pattern>%dHH:mm:ss.SSS [%thread] %-5level %logger36 - %msg%n</pattern>   
    </encoder>   
  </appender>   
   
  <!-- logback为java中的包 -->   
  <logger name="logback"/>   
   
  <root level="DEBUG">             
    <appender-ref ref="STDOUT" />   
  </root>     
     
</configuration>  

7.3 logback配置3

带有多个loger的配置,指定级别,指定appender。

<configuration>   
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">   
    <!-- encoder 默认配置为PatternLayoutEncoder -->   
    <encoder>   
      <pattern>%dHH:mm:ss.SSS [%thread] %-5level %logger36 - %msg%n</pattern>   
    </encoder>   
  </appender>   
   
  <!-- logback为java中的包 -->   
  <logger name="logback"/>   
  <!--logback.LogbackDemo:类的全路径 -->   
  <logger name="logback.LogbackDemo" level="INFO" additivity="false">  
    <appender-ref ref="STDOUT"/>  
  </logger>   
    
  <root level="ERROR">             
    <appender-ref ref="STDOUT" />   
  </root>     
</configuration>  

7.4 logback配置4

控制台输出日志、按天输出日志文件,分别指定日志级别。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志存放路径 -->
	<property name="log.path" value="/home/logs" />
    <!-- 日志输出格式 -->
	<property name="log.pattern" value="%dHH:mm:ss.SSS [%thread] %-5level %logger20 - [%method,%line] - %msg%n" />

	<!-- 控制台输出 -->
	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>$log.pattern</pattern>
		</encoder>
	</appender>
	
	<!-- 系统日志输出 -->
	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
	    <file>$log.path/sys-info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
			<fileNamePattern>$log.path/sys-info.%dyyyy-MM-dd.log</fileNamePattern>
			<!-- 日志最大的历史 60天 -->
			<maxHistory>60</maxHistory>
		</rollingPolicy>
		<encoder>
			<pattern>$log.pattern</pattern>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>INFO</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
	</appender>
	
	<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
	    <file>$log.path/sys-error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>$log.path/sys-error.%dyyyy-MM-dd.log</fileNamePattern>
			<!-- 日志最大的历史 60天 -->
			<maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>$log.pattern</pattern>
        </encoder>
        <

以上是关于SpringBoot2.x整合slf4j+logback日志框架的主要内容,如果未能解决你的问题,请参考以下文章

Springboot2.x整合logback slf4j

Springboot2.x最全整合系列(持续更新)

springboot2.x整合kafka

SpringBoot2.x整合WebSoket

springboot2.x整合quartz2.x.md

SpringBoot2.x 整合Redis和使用Redis缓存