1-简介
审计⽇记就是记录⽤户的操作记录
基于AOP动态代理 实现⾃定义审计⽇志注解, 并⽀持Spel表达式解析
2-实现
2-1 ⽇志存储实体类
@Data@Builder@ToString
public class AuditingLog { private String userId; // ⽤户id
private String userNickname; //⽤户昵称 private String operationInfo; //操作信息
private String interfaceName; // 调⽤的接⼝⽅法名 private String applicationName; // 调⽤的服务名 private LocalDateTime createTime; //操作时间}
2-2 ⾃定义审计⽇志注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})public @interface AuditLog { String logInfo(); //⽇志信息}
2-3 ⽇志注解的AOP的切⾯
@Aspect@Component
public class AuditLogAOP {
@Value(\"${spring.application.name}\")
private String applicationName; //从配置⽂件获得服务名
// spel表达式解析器
private SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
// 参数名发现器
private DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); @Before(value = \"@annotation(enableAuditLog) || @within(enableAuditLog)\") public void getAutiLogInfo(JoinPoint joinPoint, AuditLog enableAuditLog){ MethodSignature signature = (MethodSignature) joinPoint.getSignature(); if (enableAuditLog == null) {
enableAuditLog = signature.getMethod().getAnnotation(AuditLog.class); }
// 构建⽇志存储对象
AuditingLog auditlog = AuditingLog.builder().applicationName(applicationName).createTime(LocalDateTime.now()).build(); auditlog.setUserId(xxx); // 从上下⽂获取当前操作的⽤户信息 auditlog.setUserNickname(xx);
// 设置操作的接⼝⽅法名
auditlog.setInterfaceName(signature.getDeclaringTypeName()+\".\"+signature.getName()); // 获得⽇志注解上⾃定义的⽇志信息
String logInfo = enableAuditLog.logInfo();
// Spel表达式解析⽇志信息 // 获得⽅法参数名数组
String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());
if (parameterNames != null && parameterNames.length > 0){
EvaluationContext context = new StandardEvaluationContext();
//获取⽅法参数值
Object[] args = joinPoint.getArgs(); for (int i = 0; i < args.length; i++) {
context.setVariable(parameterNames[i],args[i]); // 替换spel⾥的变量值为实际值, ⽐如 #user --> user对象 }
// 解析出实际的⽇志信息
String opeationInfo = spelExpressionParser.parseExpression(logInfo).getValue(context).toString(); auditlog.setOperationInfo(opeationInfo); }
// 打印⽇志信息
log.info(auditlog.toString());
//TODO 这时可以将⽇志信息auditlog进⾏异步存储,⽐如写⼊到⽂件通过logstash增量的同步到Elasticsearch或者DB }}
2-4 开启审计⽇志功能
在分布式项⽬中⼀般会将⽇志抽离出来公共调⽤, 所以为了⽅便的注⼊审计⽇志功能,可以编写对应 Enable注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import({AuditLogAOP.class}) // 注⼊AOP切⾯到容器public @interface EnableAuditLog {}
3 使⽤
3-1 开启审计⽇志功能
在要使⽤审计⽇志功能的服务的⼊⼝类开启审计⽇志功能⽐如
@SpringBootApplication@EnableDiscoveryClient
@EnableAuditLog //开启审计⽇志public class UmsAdminApplication { public static void main(String[] args) {
SpringApplication.run(UmsAdminApplication.class,args); }}
3-2 在接⼝上使⽤
⽐如:
@AuditLog(logInfo = \"'新增管理员:'+ #user.username\") @PostMapping
public String addUser(@RequestBody User user){
return null; }
转载:https://blog.csdn.net/weixin_41347419/article/details/107573038
因篇幅问题不能全部显示,请点此查看更多更全内容