🍅程序员小王的博客:程序员小王的博客 🍅CSDN地址:程序员小王java 🍅 欢迎点赞 👍 收藏 ?留言 📝 🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕 🍅java自学的学习路线:java自学的学习路线
一、前言
我们写完一个项目,运维时,如果出现了bug,我们需要查看控制台的日志,但是那个日志无关方法太多,查找不是很方便,还有就是一个项目上线之后,我们需要记录谁操作了那些功能,以防出现矛盾知道是谁点了这个功能造成的问题,由谁来负责,为了解决这两个问题,我在SpringBoot项目中使用了对控制层切面+注解的方法来实现将日志存储在数据库里面
二、实现详细源码
1、相关依赖
- springboot项目的依赖需要,还需要一个aop切面的依赖,mybatis的依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
2、配置文件
在application.properties文件里加这样一条配置
server.port: 8080
spring.aop.auto=true
3、我们首先需要准备mysql表
DROP TABLE IF EXISTS `syslog`;
CREATE TABLE `syslog` (
`id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键',
`username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
`operation` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '操作',
`method` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '方法名',
`createDate` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '日志' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
4、创建数据库表之后就需要写实体类了
package com.sgsg.verification.entity;
import java.io.Serializable;
public class Syslog implements Serializable {
private String id;
private String username;
private String operation;
private String method;
private String createDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate;
}
}
- 这里如果用lombok的话,只需要一个@Data注解
@Data
public class Syslog implements Serializable {
private String id;
private String username;
private String operation;
private String method;
private String createDate;
}
5、先写dao层和mapper层
(1)dao层
@Mapper
public interface SysLogMapper {
int addLog(Syslog syslog);
}
(2)mapper层
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sgsg.verification.dao.SysLogMapper">
<insert id="addLog" parameterType="com.sgsg.verification.entity.Syslog">
insert into syslog(id, username, operation, method, createDate)
values (#{id}, #{username}, #{operation}, #{method}, #{createDate})
</insert>
</mapper>
6、写业务层
import com.sgsg.verification.entity.Syslog;
public interface SysLogService {
int addLog(Syslog syslog);
}
@Service
public class SysLogServiceImpl implements SysLogService {
@Autowired
public SysLogMapper sysLogMapper;
@Override
public int addLog(Syslog syslog) {
return sysLogMapper.addLog(syslog);
}
}
7、切面核心方法
package com.sgsg.verification.aspect;
import com.auth0.jwt.interfaces.Claim;
import com.sgsg.verification.dao.UserDao;
import com.sgsg.verification.entity.Result;
import com.sgsg.verification.entity.Syslog;
import com.sgsg.verification.entity.UserInfoEntity;
import com.sgsg.verification.log.Mylog;
import com.sgsg.verification.service.SysLogService;
import com.sgsg.verification.service.UserService;
import com.sgsg.verification.utils.JwtUtil;
import com.sgsg.verification.utils.UserInfoUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
@Aspect
@Component
public class SysLogAspect {
@Autowired
private SysLogService sysLogService;
@Autowired
private UserDao userDao;
@Autowired
private JwtUtil jwtUtil;
@Pointcut("@annotation(com.sgsg.verification.log.Mylog ))")
public void logPoinCut() {
}
@AfterReturning("logPoinCut()")
public void saveSysLog(JoinPoint joinPoint) {
System.out.println("切面。。。。。");
Syslog sysLog = new Syslog();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Mylog myLog = method.getAnnotation(Mylog.class);
if (myLog != null) {
String value = myLog.value();
sysLog.setOperation(value);
}
String id = UUID.randomUUID().toString();
sysLog.setId(id);
String className = joinPoint.getTarget().getClass().getName();
String methodName = method.getName();
sysLog.setMethod(className + "." + methodName);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
sysLog.setCreateDate(simpleDateFormat.format(new Date()));
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
assert attributes != null;
HttpServletRequest request = attributes.getRequest();
String token = request.getHeader("authorization");
Map<String, Claim> claims = jwtUtil.verity(token);
Claim userId = claims.get("userId");
UserInfoEntity user = userDao.getInfoById(userId.asInt());
sysLog.setUsername(user.getCname());
sysLogService.addLog(sysLog);
}
}
8、我们自己定义注解类
package com.sgsg.verification.log;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Mylog {
String value() default "";
}
9、在控制层使用我们自定义的注解
package com.sgsg.verification.controller;
import com.sgsg.verification.entity.Result;
import com.sgsg.verification.log.Mylog;
import com.sgsg.verification.service.EnumService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/enums")
public class EnumController {
@Autowired
private EnumService enumService;
@Mylog(value = "获取枚举")
@GetMapping("/selectAll")
public Result selectAll() {
return enumService.selectAll();
}
}
10、启动项目之后我们的日志就存储在数据库里面了
|