本章结束后对应的节选代码文件:
Gangbb-Vue-05-Log
项目地址:https://github.com/Gang-bb/Gangbb-Vue历史遗留TODO:
- 第三章
- mybatis缓存暂时没用到,后面整合redis后用redis做缓存(整合Redis完成)。
- 重写mybatis配置文件扫描mapper(日志整合章节完成)
- 整合暂时没有用到druid数据源,后续会用到
本章将留下TODO:
- 第四章
- 登录日志还未实现。(到登录和权限模块完成)
LogAspect
从缓存获取当前的用户信息使用模拟的数据(到登录和权限模块完成)本章将解决TODO:
- 第三章
- 重写mybatis配置文件扫描mapper(日志整合章节完成)
本章只是简单的对日志工具进行引入和配置
整体思路:SLF4j+log4j2+Aop(若依的日志实现使用的是logback)
具体详细选型介绍可以查看我的文章:SpringBoot系列-- SpringBoot整合SLF4j+log4j2+aop记录web请求
原来文章的切点是设置在监听controller目录下,即所有请求。按照若依的做法是创建一个自定义@Log
注解,切点设为该注解,如此设计更加灵活和扩展,决定采用它的方案!
<properties>
<fastjson.version>1.2.74fastjson.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>${fastjson.version}version>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-log4j2artifactId>
dependency>
<dependency>
<groupId>com.gangbbgroupId>
<artifactId>Gangbb-commonartifactId>
dependency>
dependencies>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
dependency>
dependencies>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>com.gangbbgroupId>
<artifactId>Gangbb-coreartifactId>
dependency>
dependencies>
注解要删除上节使用的:
<dependency>
<groupId>com.gangbbgroupId>
<artifactId>Gangbb-commonartifactId>
dependency>
因为导入的Gangbb-core
中已经有Gangbb-common
,不删除会导致循环依赖。
表名和其中一些字段名和若依的不一样
CREATE TABLE `sys_operation_log` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '日志主键id',
`title` varchar(255) DEFAULT '' COMMENT '操作模块',
`business_type` tinyint(4) unsigned DEFAULT '0' COMMENT '业务类型(0其它 1新增 2修改 3删除)',
`class_method` varchar(255) DEFAULT '' COMMENT '请求处理方法',
`request_method` varchar(255) DEFAULT '' COMMENT '请求方式',
`operator_type` tinyint(4) unsigned DEFAULT '0' COMMENT '操作类别(0其它 1后台用户 2手机端用户)',
`operation_name` varchar(50) DEFAULT '' COMMENT '操作人员',
`operation_url` varchar(150) DEFAULT '' COMMENT '请求url',
`operation_ip` varchar(20) DEFAULT '' COMMENT '操作ip',
`operation_location` varchar(255) DEFAULT '' COMMENT '操作地点',
`operation_param` varchar(255) DEFAULT '' COMMENT '请求参数',
`json_result` varchar(255) DEFAULT '' COMMENT '返回参数',
`operation_status` tinyint(4) unsigned DEFAULT '0' COMMENT '操作状态(0正常 1异常)',
`error_msg` varchar(255) DEFAULT '' COMMENT '错误消息',
`operation_time` datetime DEFAULT NULL COMMENT '操作时间',
`creator` varchar(100) DEFAULT '' COMMENT '创建者',
`createTime` datetime DEFAULT NULL COMMENT '创建时间',
`reviser` varchar(100) DEFAULT '' COMMENT '更新者',
`updateTime` datetime DEFAULT NULL COMMENT '更新时间',
`isDel` tinyint(4) unsigned DEFAULT '0' COMMENT '是否删除 0-未删除 1-已删除',
`remark` varchar(255) DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
在 common通用工具模块 中定义:
一、Log
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
/**
* 模块
*/
public String title() default "";
/**
* 功能
*/
public BusinessType businessType() default BusinessType.OTHER;
/**
* 操作人类别
*/
public OperatorType operatorType() default OperatorType.MANAGE;
/**
* 是否保存请求的参数
*/
public boolean isSaveRequestData() default true;
}
二、BusinessType
public enum BusinessType
{
/**
* 其它
*/
OTHER,
/**
* 新增
*/
INSERT,
/**
* 修改
*/
UPDATE,
/**
* 删除
*/
DELETE,
/**
* 授权
*/
GRANT,
/**
* 导出
*/
EXPORT,
/**
* 导入
*/
IMPORT,
/**
* 强退
*/
FORCE,
/**
* 生成代码
*/
GENCODE,
/**
* 清空数据
*/
CLEAN,
}
三、OperatorType
public enum OperatorType
{
/**
* 其它
*/
OTHER,
/**
* 后台用户
*/
MANAGE,
/**
* 手机端用户
*/
MOBILE
}
本节代码涉及过长不再贴出
整体思路:切入带有@Log的Controller,记录相应的请求信息。
需要先定义本节需要的一些实体类、枚举和工具类:
(其中有互相引用的,全部引入项目就不会错)
BaseEntity
所有entity实体类都要继承的基类,
SysOperationLog
操作日志记录表 对应数据库(sys_operation_log)表
BusinessStatus
操作状态枚举
BusinessType
业务操作类型 枚举
OperatorType
操作人类别 枚举
StringUtils
字符串工具类
CharsetKit
字符集工具类
Convert
类型转换器
StrFormatter
字符串格式化工具
IpUtils
获取IP工具类
EscapeUtil
转义和反转义工具类
HTMLFilter
HTML过滤器,用于去除XSS漏洞隐患
ServletUtils
客户端工具类
AddressUtils
获取地址类
HttpUtils
通用http发送方法
Constants
通用常量信息
GangbbConfig
读取项目相关配置
AsyncManager
异步任务管理器
Threads
线程相关工具类
SpringUtils
spring工具类 方便在非spring管理环境中获取bean
ThreadPoolConfig
线程池配置
AsyncFactory
异步工厂,产生任务用(目前只定义了 记录操作日志信息recordOperation
方法,记录登录信息recordLogininfor
方法后面到登录再涉及)
核心的LogAspect
切面处理类中的保存Log具体处理方法handleLog
主要逻辑:
既然最后一步要操数据库当然需要各层的文件:
<Configuration status="fatal">
<Properties>
<Property name="baseDir" value="${sys:user.home}/logs/Gangbb_Vue"/>
Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="debug" onMatch="ACCEPT"
onMismatch="DENY"/>
<PatternLayout
pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
Console>
<RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
<Filters>
<ThresholdFilter level="debug"/>
<ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
Filters>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
Policies>
<DefaultRolloverStrategy max="15"/>
RollingFile>
<RollingFile name="info_appender" fileName="${baseDir}/info.log"
filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
<Filters>
<ThresholdFilter level="info"/>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
Filters>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
Policies>
<DefaultRolloverStrategy max="15"/>
RollingFile>
<RollingFile name="error_appender" fileName="${baseDir}/error.log"
filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
<Filters>
<ThresholdFilter level="error"/>
Filters>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
Policies>
<DefaultRolloverStrategy max="15"/>
RollingFile>
Appenders>
<Loggers>
<logger name="org.mybatis" level="info" additivity="false">
<AppenderRef ref="Console"/>
logger>
<Logger name="org.springframework" level="WARN" additivity="false">
<AppenderRef ref="Console"/>
Logger>
<logger name="com.zaxxer.hikari" level="WARN" additivity="false">
<appender-ref ref="Console"/>
logger>
<logger name="org.hibernate.validator" level="WARN" additivity="false">
<appender-ref ref="Console"/>
logger>
<Root level="debug">
<AppenderRef ref="Console"/>
<AppenderRef ref="debug_appender"/>
<AppenderRef ref="info_appender"/>
<AppenderRef ref="error_appender"/>
Root>
Loggers>
Configuration>
看到控制台有什么不爽的打印信息,在 标签对内再写一个
添加:MyBatisConfig
使 Mybatis支持*匹配扫描包
Gangbb-admin的application.yml
:
mybatis:
configuration:
# 实体类驼峰命名转成数据库中的下划线命名
map-underscore-to-camel-case: true
# 指定 MyBatis 所用日志的具体实现
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# 全局映射器启用缓存
cache-enabled: true
# 允许 JDBC 支持自动生成主键
use-generated-keys: true
# 配置默认的执行器
default-executor-type: reuse
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapper-locations: classpath*:mapper/**/*Mapper.xml
# 扫描实体类路径(搜索指定包别名)
type-aliases-package: com.gangbb.**.entity
ApplicationConfig
配置对dao层mapper的扫描。@Configuration
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
// 指定要扫描的Mapper类的包的路径
@MapperScan("com.gangbb.**.dao")
public class ApplicationConfig
{
/**
* 时区配置
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
{
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
}
}
新建测试TestLogAnnotationController
@RestController
@RequestMapping("log")
public class TestLogAnnotationController {
@Log(title = "测试@Log注解", businessType = BusinessType.OTHER)
@GetMapping("/hello")
public String HelloLog(){
return "测试@Log注解,记录操作日志";
}
}
发送请求:
日志控制台打印信息:
(是不是十分清晰明了,i了i了!)