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开头命名方式)新建各环境配置文件,如图
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