🍅程序员小王的博客:程序员小王的博客
🍅CSDN地址:程序员小王java
🍅 欢迎点赞 👍 收藏 ⭐留言 📝
🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕
🍅java自学的学习路线:java自学的学习路线
我们写完一个项目,运维时,如果出现了bug,我们需要查看控制台的日志,但是那个日志无关方法太多,查找不是很方便,还有就是一个项目上线之后,我们需要记录谁操作了那些功能,以防出现矛盾知道是谁点了这个功能造成的问题,由谁来负责,为了解决这两个问题,我在SpringBoot项目中使用了对控制层切面+注解的方法来实现将日志存储在数据库里面
org.springframework.boot spring-boot-starter-parent 2.2.5.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aop
在application.properties文件里加这样一条配置
server.port: 8080
spring.aop.auto=true
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;
package com.sgsg.verification.entity;
/*** @author 王恒杰* @date 2022/10/25 14:54* @Description:*/
import java.io.Serializable;
public class Syslog implements Serializable {private String id; //我用的UUITprivate String username; //用户名private String operation; //操作private String method; //方法名private String createDate; //操作时间,这里可以使用Date来实现。我写的有个工具类。用的String接收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;}
}
@Data
public class Syslog implements Serializable {private String id; //我用的全宇宙唯一的子串串、也是直接用的工具类private String username; //用户名private String operation; //操作private String method; //方法名private String createDate; //操作时间,这里可以使用Date来实现。我写的有个工具类。用的String接收}
/*** @author 王恒杰* @date 2022/10/25 14:59* @Description:*/
@Mapper
public interface SysLogMapper {/*** 写入日志* @param syslog* @return*/int addLog(Syslog syslog);
}
insert into syslog(id, username, operation, method, createDate)values (#{id}, #{username}, #{operation}, #{method}, #{createDate})
import com.sgsg.verification.entity.Syslog;/*** @author 王恒杰* @date 2022/10/25 14:58* @Description:*/
public interface SysLogService {//写入日志int addLog(Syslog syslog);
}
/*** @author 王恒杰* @date 2022/10/25 14:58* @Description:*/
@Service
public class SysLogServiceImpl implements SysLogService {@Autowiredpublic SysLogMapper sysLogMapper;//写入日志@Overridepublic int addLog(Syslog syslog) {return sysLogMapper.addLog(syslog);}}
package com.sgsg.verification.aspect;/*** @author 王恒杰* @date 2022/10/25 14:57* @Description:*/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 {@Autowiredprivate SysLogService sysLogService;//将数据写入数据库的操作@Autowiredprivate UserDao userDao;@Autowiredprivate JwtUtil jwtUtil;//定义切点 @Pointcut//在注解的位置切入代码@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);//保存获取的操作}//设置idString 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()));//获取用户名//拿到当前用户的信息、我这里使用的Token。直接从Token中获取当前用户信息ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();assert attributes != null;HttpServletRequest request = attributes.getRequest();// 从 http 请求头中取出 tokenString token = request.getHeader("authorization");// 解析token并获取token中的用户信息Map claims = jwtUtil.verity(token);Claim userId = claims.get("userId");//获取用户UserInfoEntity user = userDao.getInfoById(userId.asInt());sysLog.setUsername(user.getCname());//调用service保存SysLog实体类到数据库sysLogService.addLog(sysLog);}
}
package com.sgsg.verification.log;
/*** @author 王恒杰* @date 2022/10/25 14:56* @Description: 自定义注解类*/
import java.lang.annotation.*;
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档public @interface Mylog {String value() default "";
}
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;/*** @author 王恒杰* @date 2022/10/6 12:30* @Description:*/
@Slf4j
@RestController
@RequestMapping("/enums")
public class EnumController {@Autowiredprivate EnumService enumService;@Mylog(value = "获取枚举")@GetMapping("/selectAll")public Result selectAll() {return enumService.selectAll();}
}