基于Spring Cloud自定义注解 - 登录日志

操作日志代码实现

java 复制代码
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.context.annotation.Import;

import com.martian.api.log.common.aspect.SysLogAspect;
import com.martian.api.log.fallback.SysLogApiProviderFallback;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({SysLogAspect.class, SysLogApiProviderFallback.class})
public @interface EnableSysLog {

}
java 复制代码
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;


@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SysLog {
   String value() default "";
}
java 复制代码
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
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.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.martian.api.log.SysLogApiProvider;
import com.martian.api.log.common.utils.HttpContextUtils;
import com.martian.api.log.common.utils.IPUtils;
import com.martian.common.config.auth.utils.UserContextHolder;
import com.martian.common.config.auth.vo.UserContext;
import com.martian.common.utils.R;

import io.swagger.annotations.ApiOperation;

@Component
@Aspect
public class SysLogAspect {

   @Autowired
   SysLogApiProvider sysLogApiProvider;

   @Pointcut("@annotation(com.martian.api.log.annotation.SysLog)")
   public void logPointCut() {

   }

   @Around("logPointCut()")
   public Object around(ProceedingJoinPoint point) throws Throwable {
      long beginTime = System.currentTimeMillis();
      // 执行方法
      Object result = point.proceed();
      // 执行时长(毫秒)
      long time = System.currentTimeMillis() - beginTime;

      // 保存日志
      saveSysLog(point, time, result);

      return result;
   }

   private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object result) {

      Map<String, Object> param = new HashMap<String, Object>();

      MethodSignature signature = (MethodSignature) joinPoint.getSignature();
      Method method = signature.getMethod();

      ApiOperation syslog = method.getAnnotation(ApiOperation.class);
      if (syslog != null) {
         // 注解上的描述
         param.put("operation", syslog.value());
      }

      // 请求的方法名
      String className = joinPoint.getTarget().getClass().getName();
      String methodName = signature.getName();
      param.put("method", className + "." + methodName + "()");

      // 请求的参数
      Object[] args = joinPoint.getArgs();
      // HttpServletRequest、MultipartFile等不能序列化,从入参里排除,否则报异常
      Stream<?> stream = ArrayUtils.isEmpty(args) ? Stream.empty() : Arrays.asList(args).stream();
      List<Object> logArgs = stream.filter(arg -> (!(arg instanceof HttpServletRequest)
            && !(arg instanceof HttpServletResponse) && !(arg instanceof MultipartFile)))
            .collect(Collectors.toList());
      try {
         param.put("params", JSON.toJSONString(logArgs));
      } catch (Exception e) {
         param.put("params", args.toString());
      }

      // 获取request
      HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
      // url
      param.put("url", request.getRequestURL().toString());
      // 设置IP地址
      param.put("ip", IPUtils.getIpAddr(request));

      // 用户名
      UserContext user = UserContextHolder.getInstance().getContext();
      if (user != null) {
         param.put("username", user.getUsername());
         param.put("trueName", user.getTrueName());
         param.put("systemType", user.getSystemType());
      }
      if (result != null) {
         // 返回结果
         R r = (R) result;
         param.put("msg", r.getMessage());
         param.put("status", r.getStatus());
      }
      param.put("time", time);
      param.put("createDate", new Date());
      sysLogApiProvider.saveLog(param);

   }

}

Feign远程调用保存日志信息到数据库

java 复制代码
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import com.martian.api.log.fallback.SysLogApiProviderFallback;
import com.martian.common.utils.R;

@Component
@FeignClient(name="martian-log-center", fallback = SysLogApiProviderFallback.class)
public interface SysLogApiProvider {
    
    @GetMapping(value="/sys/log/pageList")
    R pageList(@RequestParam Map<String, Object> param); 
    
    @PostMapping(value="/sys/log/save", consumes="application/json")
    R saveLog(@RequestBody Map<String, Object> param);

    @PostMapping(value="/sys/loginLog/save", consumes="application/json")
    R saveLoginLog(Map<String, Object> param);

    @GetMapping(value="/sys/loginLog/pageList")
    R pageListLogin(@RequestParam Map<String, Object> param);

}
java 复制代码
import java.util.Map;
import org.springframework.stereotype.Component;
import com.martian.api.log.SysLogApiProvider;
import com.martian.common.utils.R;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class SysLogApiProviderFallback implements SysLogApiProvider {

   @Override
   public R pageList(Map<String, Object> param) {
      log.error("pageList fallback, param={}", param);
      return R.error("martian-log-center not available when list param=" + param);
   }

   @Override
   public R saveLog(Map<String, Object> param) {
      log.error("saveLog fallback, param={}", param);
      return R.error("martian-log-center not available when save param=" + param);
   }

   @Override
   public R saveLoginLog(Map<String, Object> param) {
      log.error("saveLoginLog fallback, param={}", param);
      return R.error("martian-log-center not available when saveLoginLog param=" + param);
   }

   @Override
   public R pageListLogin(Map<String, Object> param) {
      log.error("pageListLogin fallback, param={}", param);
      return R.error("martian-log-center not available when pageList param=" + param);
   }
}
相关推荐
蓝眸少年CY44 分钟前
(第七篇)spring cloud之Hystrix断路器
spring·spring cloud·hystrix
李慕婉学姐2 小时前
Springboot旅游景点管理系统2fj40iq6(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
技术宅星云2 小时前
0x00.Spring AI Agent开发指南专栏简介
java·人工智能·spring
蓝眸少年CY2 小时前
(第八篇)spring cloud之zuul路由网关
后端·spring·spring cloud
long3163 小时前
弗洛伊德·沃肖算法 Floyd Warshall Algorithm
java·后端·算法·spring·springboot·图论
Loo国昌3 小时前
【LangChain1.0】第一篇:基础认知
后端·python·算法·语言模型·prompt
源代码•宸3 小时前
Golang原理剖析(channel面试与分析)
开发语言·经验分享·后端·面试·golang·select·channel
鹿角片ljp3 小时前
Java多线程编程:从基础到实战的完整指南
java·开发语言·后端
rannn_1114 小时前
【Javaweb学习|Day6】日志技术、多表查询、分页查询及优化(动态SQL)
java·后端·javaweb
IT 行者4 小时前
深入理解 OAuth2/OIDC 中的 Issuer:身份认证的基石
spring