一、前言

上篇介绍了 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的更多相关文章

  1. Spring Boot 项目实战(五)集成 Dubbo

    一.前言 上篇介绍了 Redis 的集成过程,可用于解决热点数据访问的性能问题.随着业务复杂度的提高,单体应用越来越庞大,就好比一个类的代码行数越来越多,分而治之,切成多个类应该是更好的解决方法,所以 ...

  2. Spring Boot 项目学习 (二) MySql + MyBatis 注解 + 分页控件 配置

    0 引言 本文主要在Spring Boot 基础项目的基础上,添加 Mysql .MyBatis(注解方式)与 分页控件 的配置,用于协助完成数据库操作. 1 创建数据表 这个过程就暂时省略了. 2 ...

  3. Spring Boot 项目实战(六)集成 Apollo

    一.前言 上篇介绍了 Spring Boot 集成 Dubbo,使我们的系统打下了分布式的基础.随着程序功能的日益复杂,程序的配置日益增多:各种功能开关.参数配置.服务器地址等:对程序配置的期望值也越 ...

  4. Spring Boot 项目实战(三)集成 Swagger 及 JavaMelody

    一.前言 上篇介绍了 Logback 的集成过程,总体已经达到了基本可用的项目结构.本篇主要介绍两个常用工具,接口文档工具 Swagger .项目监控工具 JavaMelody 的集成步骤. 二.Sw ...

  5. Spring Boot 项目实战(四)集成 Redis

    一.前言 上篇介绍了接口文档工具 Swagger 及项目监控工具 JavaMelody 的集成过程,使项目更加健壮.在 JAVA Web 项目某些场景中,我们需要用缓存解决如热点数据访问的性能问题,业 ...

  6. Spring Boot 项目实战(一)Maven 多模块项目搭建

    一.前言 最近公司项目准备开始重构,框架选定为 Spring Boot ,本篇主要记录了在 IDEA 中搭建 Spring Boot Maven 多模块项目的过程. 二.软件及硬件环境 macOS S ...

  7. Github 上热门的 Spring Boot 项目实战推荐

    最近经常被读者问到有没有 Spring Boot 实战项目可以学习,于是,我就去 Github 上找了 10 个我觉得还不错的实战项目.对于这些实战项目,有部分是比较适合 Spring Boot 刚入 ...

  8. Spring boot后台搭建二集成Shiro实现用户验证

    上一篇文章中介绍了Shiro 查看 将Shiro集成到spring boot的步骤: (1)定义一个ShiroConfig,配置SecurityManager Bean,SecurityManager ...

  9. Spring boot后台搭建二集成Shiro权限控制

    上一篇文章,实现了用户验证 查看,接下来实现下权限控制 权限控制,是管理资源访问的过程,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等 Apache Shir ...

随机推荐

  1. linux space/mark设置

    参考链接: http://blog.csdn.net/zhaozh2000/article/details/6460223 串口数据的发送: 数据的发送: 数据位+检验位+停止位, 进行数据的发送.( ...

  2. python中的%s%是什么意思

    它是一个字符串格式化语法(它从C借用). 请参阅  “格式化字符串”: Python支持将值格式化为字符串.虽然这可以包括非常复杂的表达式,但最基本的用法是将值插入到%s 占位符的字符串中  . 编辑 ...

  3. SpringAOP+注解实现简单的日志管理

    今天在再次深入学习SpringAOP之后想着基于注解的AOP实现日志功能,在面试过程中我们也经常会被问到:假如项目已经上线,如何增加一套日志功能?我们会说使用AOP,AOP也符合开闭原则:对代码的修改 ...

  4. classfication中使用图像金字塔和sliding windows提高准确率

    之前对imagenet的预训模型进行finetune,找出了很多样本选择时的注意事项,当时在测试如下这张照片时,效果不好,我认为是物体过小造成的,因此尝试使用图像金字塔的方法: 当时结果如下: 一开始 ...

  5. ARMV8 datasheet学习笔记1:预备知识

    1. 前言 ARMv8的架构继承以往ARMv7与之前处理器技术的基础; 除了支持现有的16/32bit的Thumb2指令外,也向前兼容现有的A32(ARM 32bit)指令集. 基于64bit的AAr ...

  6. vim 超强发行版

    推荐第一个: https://github.com/spf13/spf13-vim https://github.com/Spacevim/Spacevim https://github.com/JB ...

  7. flask_restplus(1)- 未完成

    快速开始 本指南假设您对Flask有一定的了解,并且您已经安装了Flask和Flask- restplus.如果没有,则按照安装部分中的步骤操作. 初始化 与其他所有扩展一样,您可以使用应用程序对象初 ...

  8. 查看tomcat运行状态

    实时查看tomcat并发连接数: netstat -na | grep ESTAB | grep 8080 | wc -l 实时查看apache并发连接数: netstat -na | grep ES ...

  9. (并发编程)进程 (multiprocessing--Process实现进程并发)

    ['创建进程2方式种', '进程对象属性:join方法,守护进程obj.daemon=True,obj.pid, obj.name, obj.terminate(),obj.is_alive()等 ' ...

  10. Java中日期格式化SimpleDateFormat类包含时区的处理方法

    1.前言 需要把格式为“2017-02-23T08:04:02+01:00”转化成”23-02-2017-T15:04:02“格式(中国时区为+08:00所以是15点),通过网上查找答案,发现没有我需 ...