Spring Boot 项目实战(二)集成 Logback
一、前言
上篇介绍了 Spring Boot Maven 多模块项目的搭建方法以及 MyBatis 的集成。通常在调试接口或者排查问题时我们主要借助于日志,一个设计合理的日志文件配置能大大降低我们的排查难度,本篇主要介绍 Logback 集成步骤。
二、集成 Logback
2.1 引入依赖包
其实 Spring Boot 提供的父工程中已经包含了所依赖的 Logback jar 包,可通过项目父 pom 中的 「spring-boot-starter-parent」>> 「spring-boot-dependencies」找到 Logback 的三个依赖包。
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
2.2 简单日志配置
在自定义日志配置之前我们可以先尝试一下 Spring Boot 默认的日志配置,可通过修改 application.properties 文件中的配置项设置。
① 更改默认日志级别
默认情况下 Spring Boot 从控制台打印出来的日志级别只有 ERROR、WARN、INFO 这三种,如果需要打印 DEBUG 级别的日志,可以使用以下配置项设置。
logging.level.root = DEBUG
② 将日志输出到文件中
默认情况下 Spring Boot 只会在控制台打印日志,可以使用「 logging.path 」或「 logging.file 」其中一个配置项将日志输出到文件中。
logging.path = ./logs
或
logging.file = ./logs/demo.log
注意事项:
- logging.path 和 logging.file 都可以是相对路径或者绝对路径
- 但它们两个是不会叠加的,也就是说即使同时配置 logging.path = ./logs 与 logging.file = demo.log 也不会在 ./logs 目录下 生成 demo.log 文件,实际结果是最终只在项目根目录生成了 demo.log 文件。
- 当只配置 logging.path 时,会在该 path 下生成一个 spring.log 文件,该文件名是固定的无法修改,若 path 不存在则会自动创建该路径。
2.3 自定义日志配置
我们可能需要将一些特定包或者特定级别的日志打印到单独的文件中方便排查问题,显然默认的日志配置并不能满足我们需求,需要我们自定义。
2.3.1 Logback XML 基础配置介绍
首先熟悉下常规的配置项,详见:Logback XML 基础配置详解
2.3.2 自定义日志配置文件内容解析
然后在 demo-web 层的 resources 目录下创建名为「 logback.xml 」的文件,具体内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 每隔一分钟扫描配置文件 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 设置上下文名称为 demo -->
<contextName>demo</contextName>
<!-- 定义日志输出格式变量:%d表示时间 花括号内为时间格式 %level表示日志级别 %thread表示线程名 %logger{0}表示输出日志的类名 [%line]表示行号用方括号包裹 %msg表示日志消息 %n换行 -->
<property name="log.pattern" value="[%d{'MM-dd HH:mm:ss,SSS'}] %level [%thread] %logger{0}[%line] - %msg%n"/>
<!-- 定义日志字符集 -->
<property name="log.charset" value="UTF-8"/>
<!-- 定义日志级别 -->
<property name="log.level" value="INFO"/>
<!-- 定义日志存放路径 -->
<property name="log.path" value="logs"/>
<!-- 输出到控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出格式 -->
<encoder>
<!-- 日志字符集 -->
<charset>${log.charset}</charset>
<!-- 日志输出格式 -->
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 时间滚动输出日志 -->
<appender name="COMMON" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 写入的文件名 -->
<file>${log.path}/common.log</file>
<!-- 追加到文件结尾 -->
<append>true</append>
<!-- 滚动策略:按照每天生成日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径及文件名格式 -->
<fileNamePattern>${log.path}/common.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志文件保留天数 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<charset>${log.charset}</charset>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- 单日志文件最大限制100兆 超过则将文件内容归档到按照 fileNamePattern 命名的文件中 源文件则清空 -->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 级别过滤器匹配 ERROR 级别日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<charset>${log.charset}</charset>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<appender name="DB" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/db.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/db.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<charset>${log.charset}</charset>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 指定 com.example.demo.dao.mapper 包要使用的 appender 且不向上级传递 -->
<logger name="com.example.demo.dao.mapper" level="DEBUG" additivity="false">
<!-- 指定使用 DB 及 ERROR 这两个 appender -->
<appender-ref ref="DB"/>
<appender-ref ref="ERROR"/>
</logger>
<!-- 根 logger -->
<root level="${log.level}">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="COMMON"/>
<appender-ref ref="ERROR"/>
</root>
</configuration>
2.3.3 多环境自定义日志配置
然而,上述配置中 <property> 标签的值都是写死的,但我们的项目环境可能有多套,每套环境的日志配置都有所区别,这就需要借助 Spring Boot 提供的 <springProfile> 及 <springProperty> 标签解决。
① 首先将刚才新建的 「 logback.xml 」文件重命名为「 logback-spring.xml 」。
注:因为文件的命名与加载顺序有关,logback.xml 早于 application.properties 加载,而 logback-spring.xml 晚于 application.properties 加载。而且 logback-spring.xml 中 Spring Boot 提供了一些特定的配置项支持,如 <springProperty>、<springProfile>。
② 其次将 <property> 标签定义的配置项改为使用 <springProperty> 标签声明。
<springProperty scope="context" name="log.charset" source="log.charset" defaultValue="UTF-8"/>
<springProperty scope="context" name="log.level" source="log.level" defaultValue="INFO"/>
<springProperty scope="context" name="log.path" source="log.path" defaultValue="./logs"/>
<springProperty scope="context" name="log.pattern" source="log.pattern" defaultValue="[%d{'MM-dd HH:mm:ss,SSS',GMT+8:00}] %level [%thread] %logger{0}[%line] - %msg%n"/>
注:因为只有使用 <springProperty> 标签才能使用 application.properties 文件中的配置项,它的工作方式与 Logback 标准的 <property> 类似,source 指定 application.properties 文件中的配置项。defaultValue 为默认值。
③ 使用 <springProfile> 标签指定配置生效环境
<!-- 开发及测试环境才打印 SQL 日志 -->
<springProfile name="dev,test">
<!-- 指定 com.example.demo.dao.mapper 包要使用的 appender 且不向上级传递 -->
<logger name="com.example.demo.dao.mapper" level="DEBUG" additivity="false">
<!-- 指定使用 DB 及 ERROR 这两个 appender -->
<appender-ref ref="DB"/>
<appender-ref ref="ERROR"/>
</logger>
</springProfile>
注:上述配置生效的前提是在 application.properties 文件中指定生效环境(即 spring.profiles.active = dev )
④ 启动项目可以看到在项目根目录生成 logs 目录,目录中有三个日志文件(即 common.log 、db.log 、error.log ),访问 上篇的 http://localhost:8080/demo/test 接口后 db.log 输出如下日志:
[01-30 17:58:05,296] DEBUG [http-nio-8080-exec-1] selectById[159] - ==> Preparing: SELECT `id`, `user_name` FROM `db_user` WHERE `id` = ?
[01-30 17:58:05,317] DEBUG [http-nio-8080-exec-1] selectById[159] - ==> Parameters: 1(Integer)
[01-30 17:58:05,373] DEBUG [http-nio-8080-exec-1] selectById[159] - <== Total: 1
三、结语
至此 Spring Boot 集成 Logback 的具体步骤介绍完毕,我们自定义了一个简单的日志配置,也看到了最后的输出结果。后续将继续介绍其余中间件或者工具的集成步骤。
Spring Boot 项目实战(二)集成 Logback的更多相关文章
- Spring Boot 项目实战(五)集成 Dubbo
一.前言 上篇介绍了 Redis 的集成过程,可用于解决热点数据访问的性能问题.随着业务复杂度的提高,单体应用越来越庞大,就好比一个类的代码行数越来越多,分而治之,切成多个类应该是更好的解决方法,所以 ...
- Spring Boot 项目学习 (二) MySql + MyBatis 注解 + 分页控件 配置
0 引言 本文主要在Spring Boot 基础项目的基础上,添加 Mysql .MyBatis(注解方式)与 分页控件 的配置,用于协助完成数据库操作. 1 创建数据表 这个过程就暂时省略了. 2 ...
- Spring Boot 项目实战(六)集成 Apollo
一.前言 上篇介绍了 Spring Boot 集成 Dubbo,使我们的系统打下了分布式的基础.随着程序功能的日益复杂,程序的配置日益增多:各种功能开关.参数配置.服务器地址等:对程序配置的期望值也越 ...
- Spring Boot 项目实战(三)集成 Swagger 及 JavaMelody
一.前言 上篇介绍了 Logback 的集成过程,总体已经达到了基本可用的项目结构.本篇主要介绍两个常用工具,接口文档工具 Swagger .项目监控工具 JavaMelody 的集成步骤. 二.Sw ...
- Spring Boot 项目实战(四)集成 Redis
一.前言 上篇介绍了接口文档工具 Swagger 及项目监控工具 JavaMelody 的集成过程,使项目更加健壮.在 JAVA Web 项目某些场景中,我们需要用缓存解决如热点数据访问的性能问题,业 ...
- Spring Boot 项目实战(一)Maven 多模块项目搭建
一.前言 最近公司项目准备开始重构,框架选定为 Spring Boot ,本篇主要记录了在 IDEA 中搭建 Spring Boot Maven 多模块项目的过程. 二.软件及硬件环境 macOS S ...
- Github 上热门的 Spring Boot 项目实战推荐
最近经常被读者问到有没有 Spring Boot 实战项目可以学习,于是,我就去 Github 上找了 10 个我觉得还不错的实战项目.对于这些实战项目,有部分是比较适合 Spring Boot 刚入 ...
- Spring boot后台搭建二集成Shiro实现用户验证
上一篇文章中介绍了Shiro 查看 将Shiro集成到spring boot的步骤: (1)定义一个ShiroConfig,配置SecurityManager Bean,SecurityManager ...
- Spring boot后台搭建二集成Shiro权限控制
上一篇文章,实现了用户验证 查看,接下来实现下权限控制 权限控制,是管理资源访问的过程,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等 Apache Shir ...
随机推荐
- [HAOI2018]奇怪的背包 (DP,数论)
[HAOI2018]奇怪的背包 \(solution:\) 首先,这一道题目的描述很像完全背包,但它所说的背包总重量是在模P意义下的,所以肯定会用到数论.我们先分析一下,每一个物品可以放无数次,可以达 ...
- transition,过渡效果
语法: transtion:property time change-speed delay. 人话就是:属性(property )在多少秒内(time )通过什么样的速度(change-speed) ...
- 2017-2018-2 20155303『网络对抗技术』Final:Web渗透获取WebShell权限
2017-2018-2 『网络对抗技术』Final:Web渗透获取WebShell权限 --------CONTENTS-------- 一.Webshell原理 1.什么是WebShell 2.We ...
- oracle_集合函数
查询10和20号部门的员工 SQL> 1. select * from emp where deptno in (10,20); SQL> 2. select * from emp whe ...
- 【Python】Python-基础语法学习
基础语法学习 果然学完 C++ 后再看其他语言的确有很多的共性,只需要熟悉一下python的独特语法和 C++ 中的差异就可以写出一些小的程序,而写得过程中也再次体会出python代码的精简和灵活: ...
- setfacl报错Operation not supported
对文件目录setfacl权限设置时报错Operation not supported Google一下,发现是分区acl权限问题 一般情况下(ext4),默认acl支持都是加载的.但如果遇到二般情况, ...
- vs2010补丁
背景 我都不知道这是干啥的了.想起.net真是一把鼻涕一把泪.搞了这么久.net,也被它坑了好多.有这时间搞搞开源东西多好.看见下面还有tfs,想起当时有个java同事竟然用vss管理java代码,后 ...
- CentOS 6.5自动化运维之基于cobbler服务的自动化安装操作系统详解
一.Cobbler安装 前提:cobbler由epel源提供,故此需要事先配置指向epel的yum源方可进行类似下面的安装过程. # yum install -y epel-release # yum ...
- EntityFramework codefirst Enable-Migrations No context type was found in the assembly “MyApp.Web” error
Enable-Migrations -Force -ContextTypeName "MyApp.Repository.DataContext" -ProjectName &quo ...
- MVC,MVP设计模式
什么是MVP MVP是模型(Model).视图(View).主持人(Presenter)的缩写,分别代表项目中3个不同的模块. 模型(Model):负责处理数据的加载或者存储,比如从网络或本地数据库获 ...