请求日志几乎是所有大型企业级项目的必要的模块,请求日志对于我们来说后期在项目运行上线一段时间用于排除异常、请求分流处理、限制流量等。请求日志一般都会记录请求参数、请求地址、请求状态(Status Code)、SessionId、请求方法方式(Method)、请求时间、客户端IP地址、请求返回内容、耗时等等。如果你得系统还有其他个性化的配置,也可以完成记录。

本章目标

通过SpringBoot整合与拦截器整合完成请求日志的记录,本章节日志记录使用SpringDataJPA与MySQL数据库记录。

构建项目

我们使用InteiiJ IDEA创建一个SpringBoot项目,预先依赖模块有Web、JPA、MySQL、Druid等。项目结构如下图1所示:





springboot 审计日志 springboot请求日志_MySQL


图1


配置数据源

我们直接从之前的项目中复制一个application.yml文件到/resource下,application.yml内容如下图2所示:



springboot 审计日志 springboot请求日志_MySQL_02


图2


创建数据表结构

我们把请求日志直接保存到本地的MySQL数据库内,下面我们先来创建一个请求日志表,结构如下图3所示:



springboot 审计日志 springboot请求日志_springboot 审计日志_03


图3


我们表结构内的字段比较多,数据结构创建完成后,接下来根据表结构创建实体并配置实体JPA,如下图4所示:



springboot 审计日志 springboot请求日志_springboot 审计日志_04


图4


可以看到上图4,我们对应数据库内的表名以及字段名创建实体映射、字段映射,根据实体我们创建一个实现SpringDataJPA接口JpaRepository的子接口,LoggerJPA,如下图5所示:



springboot 审计日志 springboot请求日志_MySQL_05


图5


JpaRepository接口包含了SpringDataJPA内的常用到的CRUD方法,后面章节我们会拿出来分支来专门讲解SpringDataJPA使用。

创建日志拦截器

我们上面的步骤有关请求日志的存储已经编写完成,那么我们接下来需要编写一个请求日志的拦截器,自定义SpringMVC拦截器需要实现HandlerIntercptor接口,并且实现内部的三个方法,如下图6所示拦截器代码详情:



springboot 审计日志 springboot请求日志_springboot 审计日志_06


图6


上面的三个方法在前面章节:第六章:如何在SpringBoot项目中使用拦截器已经讲过了,这里就不多做解释了,有需要的请去看下我的第六章讲解。
这里需要注意一点,我们在拦截器内无法通过SpringBean的方式注入LoggerJPA,我只能通过另外一种形式。

WebApplicationContextUtils

这个工具类可以通过HttpServletRequest请求对象的上下文(ServetCotext)获取Spring管理的Bean,具体代码如下图7所示:



springboot 审计日志 springboot请求日志_springboot 审计日志_07


图7


可以看到上图7创建了一个getDAO的方法,方法需要传入一个实体的类型,以及一个HttpServetRequest请求对象,通过WebApplicationContextUtils内部的getRequiredWebApplicationContext方法获取到BeanFactory(实体工厂类),从而通过工厂实体的getBean方法就可以拿到SpringDataJPA为我们管理的LoggerJPA持久化数据接口实例。

记录请求日志

我们处理日志请求时需要用到FastJson、HttpServet依赖,所以我们修改pom.xml配置文件加入FastJson开源组件以及HttpServlet的maven依赖,如下图8所示:



springboot 审计日志 springboot请求日志_MySQL_08


图8


接下来我们开始编写请求日志的创建,首先我们在preHandle方法内创建LoggerEntity实体,并记录一些必要参数后将实体写入到当前请求对象HttpServletRequest内,如下图9、图10所示:



springboot 审计日志 springboot请求日志_springboot 审计日志_09


图9



springboot 审计日志 springboot请求日志_数据库_10


图10


可以看到我们上面记录了我们日志实体内的大部分参数,当用户发送请求时在进入SpringMVC的控制器之前会进入preHandle方法,然后记录下我们的请求日志内容,并将请求日志的实体写入到请求对象内,下面就会进入对应springMVC控制器方法的方法,在最后渲染视图即将返回前台的时候开始执行我们下面需要边写的afterCompletion方法,代码如下图11所示:



springboot 审计日志 springboot请求日志_springboot 审计日志_11


图11


我们在afterCompletion方法内记录了请求相应码、请求时间戳、请求返回值等。其中请求返回值我们是在哪里设置的呢?那么我们接下来开始编写测试请求控制器IndexController。你就会明白了。

编写测试控制器

我们在controller包下创建一个IndexController并且添加@RestController注解来标明IndexController是一个restful风格的控制器。如下图12所示:



springboot 审计日志 springboot请求日志_springboot 审计日志_12


图12


我们在IndexControll控制器内简单添加了一个测试方法login,可以看到我们在拦截器内的疑问得到的解释,LOGGER_RETURN是从我们的请求方法传入到LoggerInterceptor拦截器内afterCompletion方法中的。

配置拦截器

上述我们的代码基本已经编写完成,不要忘记最重要的一步,我们需要将LoggerInterceptor拦截器添加到我们的SpringBoot项目内,让SpringBoot项目可以识别拦截。我们需要创建一个LoggerConfguration配置类,如下图13所示:



springboot 审计日志 springboot请求日志_拦截器_13


图13


我们的项目编码已经完成,下面我们来尝试运行项目看看效果。

初尝试运行项目

运行日志如下图14所示,如果没有出现异常证明项目运行成功了,如果出现异常请根据对应异常检查错误。



springboot 审计日志 springboot请求日志_springboot 审计日志_14


图14


我们项目已经运行成功,那么我们接下来测试我们的请求日志是否可以记录成功,我们先来访问地址:http://127.0.0.1:8080/index/login?name=yuqiyu(简书插入链接无法带参数,请复制到地址栏访问),效果如下图15所示:



springboot 审计日志 springboot请求日志_数据库_15


图15


可以看到我们成功的返回了在IndexControll的login方法配置的json信息,那么我的请求日志是否已经记录到数据库呢?我们先来看下InteiiJ IDEA工具的控制器是否已经打印了SQL,如下图16所示:



springboot 审计日志 springboot请求日志_拦截器_16


图16


可以看到已经正常打印了,我们打开表查看下数据,如下图17所示:



springboot 审计日志 springboot请求日志_数据库_17


图17


我们已经将请求日志成功的写入到数据库。

总结

上述内容就是本章的全部讲解,本章主要讲解了SpringBoot项目如何配置日志拦截器,将用户的请求参数写入到数据库内,使用SpringDataJPA以及Druid连接池完成数据的持久化操作。当前如果要在企业级大型项目使用,还请定期清理请求日志。如果你有记录错误日志发送邮件的需求,可以通过判断HttpServertReponse对象的statusCode来完成,具体的错误堆栈信息记录,需要我们后续章节讲解。