springboot请求url日志推送到rabbitmq

//AOP切面 :多个切面时,@Order(i)注解来标识切面的优先级。i的值越小,优先级越高
@Order(6)
@Aspect
@Component
public class ControllerAspect {

   @Autowired
   private AmqpTemplate template;

   @Pointcut("execution(public * com.vanrui.controller.*.*(..))")
   public void log(){}

   //统计请求的处理时间
   ThreadLocal<Long> startTime = new ThreadLocal<>();
   ThreadLocal<String> url = new ThreadLocal<>();
   ThreadLocal<String> reqType = new ThreadLocal<>();
   ThreadLocal<String> reqIp = new ThreadLocal<>();

   @Before("log()")
   public void doBefore(JoinPoint joinPoint) throws Throwable{
      startTime.set(System.currentTimeMillis());
      //接收到请求,记录请求内容
      ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
      HttpServletRequest request = attributes.getRequest();
      url.set(request.getRequestURL().toString());
      reqType.set(request.getMethod());
      reqIp.set(getIpAddr(request));
   }

   @AfterReturning(returning = "ret" , pointcut = "log()")
   public void doAfterReturning(Object ret){
      //处理完请求后,返回内容
      Long time = System.currentTimeMillis()-startTime.get();
      RxRequestLog rxRequestLog = new RxRequestLog();
      rxRequestLog.setUrl(url.get().split("/api/")[1]);
      rxRequestLog.setReqType(reqType.get());
      rxRequestLog.setExeTime(time.intValue());
      rxRequestLog.setReqTime(new Date(startTime.get()));
      rxRequestLog.setReqIp(reqIp.get());
      if (ret instanceof ResponseDTO) {
         ResponseDTO responseDTO = (ResponseDTO)ret;
         rxRequestLog.setResult(responseDTO.getCode());
      }
      template.convertAndSend(ConstantUtil.REQ_LOG_QUEUE, rxRequestLog);
   }

   /**
    * 获取目标主机的ip
    *
    * @param request
    * @return
    */
   private String getRemoteHost(HttpServletRequest request) {
      String ip = request.getHeader("X-Forwarded-For");
      if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
         //多次反向代理后会有多个ip值,第一个ip才是真实ip
         int index = ip.indexOf(",");
         if(index != -1){
            return ip.substring(0,index);
         }else{
            return ip;
         }
      }
      ip = request.getHeader("X-Real-IP");
      if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
         return ip;
      }
      ip = request.getRemoteAddr();
      return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
   }

   /**
    * 获取用户真实IP地址,不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
    * 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值
    *
    * @return ip
    */
   private String getIpAddr(HttpServletRequest request) {

      String[] ipHeaderArray = new String[]{"x-forwarded-for","Proxy-Client-IP","WL-Proxy-Client-IP","HTTP_CLIENT_IP","HTTP_X_FORWARDED_FOR","X-Real-IP"};
      String ip = null;
      for (String ipHeader : ipHeaderArray) {
         ip = request.getHeader(ipHeader);
         if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip.split(",")[0];
         }
      }
      ip = request.getRemoteAddr();
      return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
   }
}

辅助类:

@Data
@ApiModel
public class RxRequestLog implements Serializable {
    /**
     * 系统id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @ApiParam(value="系统id")
    private Integer id;
    /**
     * 请求IP
     */
    @ApiParam(value="请求IP")
    private String reqIp;
    /**
     * 请求地址
     */
    @ApiParam(value="请求地址")
    private String url;
    /**
     * 请求时间
     */
    @ApiParam(value="请求时间")
    private Date reqTime;
    /**
     * 请求方式
     */
    @ApiParam(value="请求方式")
    private String reqType;
    /**
     * 执行时长(毫秒)
     */
    @ApiParam(value="执行时长(毫秒)")
    private Integer exeTime;
    /**
     * 请求结果(0-成功, 1-失败)
     */
    @ApiParam(value="请求结果(0-成功, 1-失败)")
    private Integer result;
    private static final long serialVersionUID = 1L;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值