Logback+slf4j实现多环境配置

Logback+slf4j实现多环境配置


logback的前世今生,作为log4j的大兄弟,据说性能是log4j的十倍,在此不探讨到底比log4j快多少倍,今天做日志处理使用了logback+slf4j作为日志的处理的主要工具,slf4j很好的兼容了logback,作为facade,无缝兼容助推了logback。

首先,我们为什么要写日志呢?

我们先仔细了解一下logback

Logback 是由 log4j 创始人设计的又一个开源日记组件,Logback 当前分成三个模块:logback-core,logback- classic和logback-access。logback-core是其它两个模块的基础模块,logback-classic是log4j的一个 改良版本。此外logback-classic 完整实现 SLF4J API 使你可以很方便地更换成其它日记系统如log4j或JDK14 Logging。logback-access访问模块与Servlet容器集成提供通过Http来访问日记的功能。maven 最新依赖如下:

这个就不需要我来详细描述了,日志作为开发人员,上线后的主要得分手段,要不出现错误,岂不是哑巴吃黄连,有苦说不出,所以这个时候日志就显得格外的重要了,特别的是错误日志的编写,下面有几种处理日志的手段,日志系统,最常见的就是:aop日志,log4j1,log4j2,slf4j,logback都可以实现想要目的,接下来我们重点介绍一下logback+slf4j的适配及编写,It's show time.


项目结构:springboot+logback+slf4j

目的:多环境下适配日志/日志层级的分离

工具:

    

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.1.6</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.6</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.18</version>
</dependency>


上面是所需的maven配置文件,如果使用spring-boot,兼容logback,默认已经集成了这些文件,所以就不需要自己依赖注入了,直接在项目中使用就行了

我们主要看使用spring profile来分配环境

Spring profile是Spring 3引入的概念,主要用在项目多环境运行的情况下,通过**方式实现多环境切换,省去多环境切换时配置参数和文件的修改,相比较Maven profile简单实用,易于上手。并且Spring profile提供了多种**方法,例如配置文件,注解,jvm参数设置等等


1.在根目录(以application开头命名方式)新建各环境配置文件,如图

Logback+slf4j实现多环境配置

2.分别配置各环境有差异的配置,共有配置可以配置在application.yml,例如application-dev配置开发环境的日志配置,application-prd配置生产环境的日志配置(具体日志配置下面介绍)。

#日志相关配置
logging:
  config: classpath:conf/logback-dev.xml
#日志相关配置
logging:
  config: classpath:conf/logback-prd.xml

3.在application.yml加上当前生效的环境配置,例如profiles:active:dev表示当前生效的环境配置为application-dev.yml,事先配好每个环境的配置,切换环境时只需要修改active:dev即可,无需复杂的修改各个配置。

spring:
  profiles:
    active: dev
  datasource:
    url: jdbc:mysql://rm-vmo.mysql.rds.aliyuncs.com:3306/****?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: mysql
    password: ******
    driver-class-name: com.mysql.jdbc.Driver
  
#简单日志相关配置(如果不使用logback,支持简单的日志输出)
#logging:
#  level:
#    root: INFO
#    org:
#      hibernate: ERROR
#  path: /var/log/***

logback日志配置

logback-dev.xml (开发环境)

<?xml version="1.0" encoding="UTF-8"?>
<!-- 不分级别同步文件日志输出配置 -->
<configuration>
    <!-- 日志级别 -->
    <property name="logLevel" value="INFO"></property>
    <!-- 日志地址 -->
    <property name="logPath" value="/var/log"></property>
    <!-- 最大保存时间 -->
    <property name="maxHistory" value="10"/>
    <!-- 异步缓冲队列的深度,该值会影响性能.默认值为256 -->
    <property name="queueSize" value="512"></property>

    <!-- 控制台打印日志的相关配置 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志格式 -->
        <encoder>  
        <!--对应的颜色显示 -->   
        
       <pattern>%d{yyyy-MM-dd HH:mm:ss}  %highlight(%-4level) %-5relative --- [%thread]  %cyan(%logger{15}) : %msg %n</pattern>
        </encoder>
    </appender>

    <!-- 文件保存日志的相关配置,同步 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 保存日志文件的路径 -->
        <file>${logPath}/log.log</file>
        <!-- 日志格式 -->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss}  %highlight(%-4level) %-5relative --- [%thread]  %cyan(%logger{15}) : %msg %n</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>${logLevel}</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${logPath}/classonline-%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 最大保存时间-->
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
    </appender>


    <!--配置Hibernate日志-->
    <logger name="org.hibernate" level="ERROR"/>
    <!-- 基于INFO处理日志:具体控制台或者文件对日志级别的处理还要看所在appender配置的filter,如果没有配置filter,则使用root配置 -->
    <root level="${logLevel}">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

logback-prd.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 分级别异步文件日志输出配置 -->
<configuration>
    <!-- 日志级别 -->
    <property name="logLevel" value="INFO"></property>
    <!-- 日志地址 -->
    <property name="logPath" value="/var/log"></property>
    <!-- 最大保存时间 -->
    <property name="maxHistory" value="30"/>
    <!-- 异步缓冲队列的深度,该值会影响性能.默认值为256 -->
    <property name="queueSize" value="512"></property>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss}  %highlight(%-5level) %-5relative --- [%thread]  %cyan(%logger{15}) : %msg %n</pattern>
        </encoder>
    </appender>

    <appender name="FILE_DEBUG"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/log_debug.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/log_debug.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss}  %highlight(%-5level) %-5relative --- [%thread]  %cyan(%logger{15}) : %msg %n</pattern>
        </encoder>
    </appender>
    <appender name="FILE_INFO"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/log_info.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/log_info.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss}  %highlight(%-5level) %-5relative --- [%thread]  %cyan(%logger{15}) : %msg %n</pattern>
        </encoder>
    </appender>

    <appender name="FILE_WARN"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/log_warn.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/log_warn.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss}  %highlight(%-5level) %-5relative --- [%thread]  %cyan(%logger{15}) : %msg %n</pattern>
        </encoder>
    </appender>
    <appender name="FILE_ERROR"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/log_error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/log_error.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss}  %highlight(%-5level) %-5relative --- [%thread]  %cyan(%logger{15}) : %msg %n</pattern>
        </encoder>
    </appender>

    <appender name="ASYNC_LOG_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_DEBUG"/>
    </appender>
    <appender name="ASYNC_LOG_INFO" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_INFO"/>
    </appender>
    <appender name="ASYNC_LOG_WARN" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_WARN"/>
    </appender>
    <appender name="ASYNC_LOG_ERROR" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_ERROR"/>
    </appender>
    <!--配置Hibernate日志-->
    <logger name="org.hibernate" level="ERROR"/>

    <root level="${logLevel}">
        <!-- appender referenced after it is defined -->
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="ASYNC_LOG_DEBUG"/>
        <appender-ref ref="ASYNC_LOG_INFO"/>
        <appender-ref ref="ASYNC_LOG_WARN"/>
        <appender-ref ref="ASYNC_LOG_ERROR"/>
    </root>
</configuration>

你就可以在你目的文件看到生成的文件,切换application.yml

active: dev 或者 prd