SpringBoot初始教程之日志处理(二)
SpringBoot初始教程之日志处理(二)
1.介绍
SpringBoot默认是采用logback进行日志处理、Logback是由log4j创始人设计的又一个开源日志组件。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来访问日志的功能
2. 快速开始
由于SpringBoot自动引入了logback的依赖包,所以只需要进行正常配置即可,本项目源码存放https://git.oschina.net/wangkang_daydayup/SpringBoot-Learn/tree/master/springboot-2
<?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>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion> <artifactId>springboot-2</artifactId> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.1.RELEASE</version>
</plugin>
</plugins>
</build> </project>
整个项目的核心文件是logback.xml,logback.xml需要放到classpath根目录下src/main/resources/logback.xml
,下面
是一个在生产环境中使用的xml、在生产中往往会因为大量的日志导致io过高,所以通过AsyncAppender进行异步的日志记录。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--<include resource="org/springframework/boot/logging/logback/base.xml"/>-->
<!-- 项目的appid -->
<property name="APP_ID" value="com.leona.cms"/>
<property name="LOG_PATH" value="log"></property>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<appender name="FILE_LOG"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
</filter>
<file>${LOG_PATH}/${APP_ID}/access.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APP_ID}/access.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-4relative [%thread] %-5level %logger{35} - %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>${LOG_PATH}/${APP_ID}/access_debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APP_ID}/access_debug.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-4relative [%thread] %-5level %logger{35} - %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>${LOG_PATH}/${APP_ID}/access_info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APP_ID}/access_info.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-4relative [%thread] %-5level %logger{35} - %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>${LOG_PATH}/${APP_ID}/access_warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APP_ID}/access_warn.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-4relative [%thread] %-5level %logger{35} - %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>${LOG_PATH}/${APP_ID}/access_error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APP_ID}/access_error.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender> <appender name="ASYNC_LOG" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<appender-ref ref="FILE_LOG"/>
</appender>
<appender name="ASYNC_LOG" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<appender-ref ref="FILE_LOG"/>
</appender>
<appender name="ASYNC_LOG_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</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>512</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>512</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>512</queueSize>
<appender-ref ref="FILE_ERROR"/>
</appender>
<root level="INFO">
<!-- appender referenced after it is defined -->
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC_LOG"/>
<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>
<logger name="org.springframework" level="INFO"/>
</configuration>
每个日志文件都配置了一个规则,对昨天的文件都进行打包压缩成zip、来减少日志文件使用的空间,在生产中我们每天都会把压缩文件发送给相关人员
而maxHistory
配置了日志在服务器上面只存留十个备份
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APP_ID}/access.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
这块主要是指定root的日志级别,一般来说都会指定到info级别,因为SpringBoot运行的时候会产生大量的debug日志,
而<logger name="org.springframework" level="DEBUG"/>定义了org.springframework这个包里面输出debug日志、
一般来说如果使用Mybatis或者hibernate,需要输出SQL都需要通过这里进行配置,输出debug级别的日志
<root level="INFO">
<!-- appender referenced after it is defined -->
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC_LOG"/>
<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>
<logger name="org.springframework" level="DEBUG"/>
这块需要注意、如果使用main方法直接启动SpringBoot的话是无法自动加载日志文件的,需要使用插件springBoot插件运行
3.多环境日志级别配置
3.1 基于spring profile方案
在开发环境和生产环境中往往会使用不同的日志级别、这个是需要就需要对不同环境进行区分。这个可以通过spring profile来进行解决
运行的时候指定-Dspring.profiles.active=(dev or prod) 参数、根据不同的profile会加载application-dev.yaml或者application-prod.yaml
两个yaml文件分别加载不同的文件
#application-dev.yaml logging:
config: classpath:logback-dev.xml #application-prod.yaml
logging:
config: classpath:logback-prod.xml
3.2 基于maven方案
基于maven的方案是在打包的时候动态指定resources的目录,通过不同目录存放不同的文件,通过-Pprod来指定是生产环境
mvn clean -Pprod -DskipTests=true package
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>project.properties</exclude>
<exclude>logback.xml</exclude>
<exclude>application.yml</exclude>
</excludes>
</resource>
<resource>
<directory>config/${package.environment}</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>dev</id>
<properties>
<package.environment>dev</package.environment>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>stable</id>
<properties>
<package.environment>stable</package.environment>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<package.environment>prod</package.environment>
</properties>
</profile>
</profiles>
转:http://blog.csdn.net/king_is_everyone/article/details/53074006
SpringBoot初始教程之日志处理(二)的更多相关文章
- SpringBoot初始教程之项目结构(一)
SpringBoot初始教程之项目结构 1 简介 spring Boot makes it easy to create stand-alone, production-grade Spring ba ...
- 🔥SpringBoot图文教程2—日志的使用「logback」「log4j」
有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...
- SpringBoot图文教程5—SpringBoot 中使用Aop
有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...
- SpringBoot图文教程7—SpringBoot拦截器的使用姿势这都有
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- SpringBoot图文教程6—SpringBoot中过滤器的使用
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文系列教程技术大纲 鹿老师的Java笔记 SpringBo ...
- SpringBoot图文教程4—SpringBoot 实现文件上传下载
有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...
- SpringBoot图文教程3—「‘初恋’情结」集成Jsp
有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...
- SpringBoot图文教程8 — SpringBoot集成MBG「代码生成器」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- SpringBoot图文教程9—SpringBoot 导入导出 Excel 「Apache Poi」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
随机推荐
- TUM好用的工具
https://vision.in.tum.de/data/datasets/rgbd-dataset/tools?tdsourcetag=s_pctim_aiomsg
- OpenCV:应用篇
手势跟踪识别 车牌检测 人脸识别 去雾 图像阈值分割提取
- 光猫&路由器网络配置
前期准备:电脑(工业电脑).网线.光猫.路由器 1.检查连接光猫后能否正常上网:把网线两头的水晶头,一头插在光猫上的千兆口,一头插在电脑(工业电脑)的网口上,看电脑能否正常上网: 可以正常上网:说明光 ...
- C++ new delete(一)
在C#.Java這種managed語言,因為有garbage collection,所以完全不用考慮free()或delete,但在C/C++,有時候要delete的,有時又不用,到底哪些改delet ...
- JavaScript—获取当下往后七天的时间
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- poj3710 Christmas Game
题目描述 题解: 树上删边. 对于奇数长度的环,可以看做一条边. 对于偶数长度的环,可以看做什么都没有. 没有特别好的解释…… 代码: #include<cstdio> #include& ...
- cmd启动MySQL服务器发生错误
Mysql net start mysql启动,提示发生系统错误 5 拒绝访问 原文:https://blog.csdn.net/angel_guoo/article/details/7919037 ...
- KVM中存储的配置
存储配置和启动顺序 QEMU提供了对多种块存储设备的模拟,包括IDE设备.SCSI设备.软盘.U盘.virtio磁盘等,而且对设备的启动顺序提供了灵活的配置. 1. 存储的基本配置选项 在qemu-k ...
- (二十一)python 3 内置函数
阅读目录 1.abs() 2.dict() 3.help() 4.min() 5.setattr() 6.all() 7.dir() 8.hex() 9.next() 10.slice() 11.an ...
- mysql启动问题
/usr/local/mysql/bin/mysqld: Can't find file: './mysql/plugin.frm' (errno: 13 - Permission denied) - ...