cat监控http请求-CatFilter

AlgoNebula
• 阅读 2526

背景

CatFilter是用于http监控,即web项目里的controller类里的方法的监控。

实现原理其实就是servlet里的filter。

本文主要讲springboot web项目和非springboot web项目如何实现监控url监控。

CatFilter

是cat客户端jar里的类,实现了servlet里的Filter接口。

非springboot web项目

直接配置即可,配置filter之后,就相当于引入了过滤器,这个和servlet filter的使用方法一样。


web.xml

<!-- cat监控http请求-->
    <filter>
        <filter-name>cat-filter</filter-name>
        <filter-class>com.dianping.cat.servlet.CatFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>cat-filter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>

springboob web项目

如果是拦截所有请求,就直接用cat自带的CatFilter即可。

但是如果要排除静态资源,就需要扩展CatFilter,因为springboot filter不支持排除资源路径,只支持pattern匹配。

扩展CatFilter

package com.xxx.qrcode.ugate.payment.filter;

import com.dianping.cat.servlet.CatFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.springframework.util.AntPathMatcher;

/**
 * 重写CatFilter,排除.js/.css/.html等静态资源
 *
 * @author gzh
 * @createTime 2021/2/23 2:54 PM
 */
public class QrcodeCatFilter extends CatFilter {

  /**
   * 排除.js/.css/.html等静态资源
   */
  private static List<String> excludeUrlPatterns = Arrays.asList("/**/*.html", "/**/*.jsp",
      "/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg",
      "/**/*.jpeg", "/**/*.gif", "/**/*.svg");

  private static AntPathMatcher antPathMatcher = new AntPathMatcher();

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException,    ServletException {
    //获取当前请求的相对路径(即去掉域名/项目名字之后的路径)
    HttpServletRequest httpServletRequest = (HttpServletRequest)request;
    String ServletPath = httpServletRequest.getServletPath();

    //校验路径是否匹配
    boolean b = excludeUrlPatterns.stream()
        .anyMatch(e -> antPathMatcher.match(e, ServletPath));
    if (b) { //如果是静态资源,不走CatFilter
      chain.doFilter(request, response);
    }else { //如果不是静态资源,才走CatFilter
      super.doFilter(request, response, chain);
    }
  }
}

说明
1.自定义扩展类,覆盖了拦截方法doFilter,会根据是否是静态资源请求路径,来决定要不要被拦截。

2.启动的时候,CatFilter的init等方法,还是会被执行,因为自定义的扩展类继承了CatFilter。

配置过滤器

配置过滤器

/**
   * 配置过滤器
   * @return
   */
  @Bean
  public FilterRegistrationBean registerFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new QrcodeCatFilter());
//    registration.addUrlPatterns("*.do");
//    registration.addInitParameter("exclusions", "*.css");
//    registration.setName("CatFilter");
    return registration;
  }

完整配置

package com.xxx.xxx.ugate.payment.config.webconfig;

import com.xxx.qrcode.ugate.payment.filter.QrcodeCatFilter;
import com.xxx.qrcode.ugate.payment.intercepter.LogPreInterceptor;
import xxx.log.logback.web.LogbackConfigListener;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * LogbackConfigListener配置
 * 输出日志文件
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

  @Bean
  public ServletListenerRegistrationBean<LogbackConfigListener> initLogbackConfigListener() {
    ServletListenerRegistrationBean<LogbackConfigListener> result = new ServletListenerRegistrationBean<>();
    result.setListener(new LogbackConfigListener());
    return result;
  }

  /**
   * 配置拦截器
   * @param registry
   */
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LogPreInterceptor())
//        .addPathPatterns("/**/*.do")
        .excludePathPatterns("/**/*.html", "/**/*.jsp",
                                  "/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg",
                                    "/**/*.jpeg", "/**/*.gif", "/**/*.svg");
  }

  /**
   * 配置过滤器
   * @return
   */
  @Bean
  public FilterRegistrationBean registerFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new QrcodeCatFilter());
//    registration.addUrlPatterns("*.do");
//    registration.addInitParameter("exclusions", "*.css");
//    registration.setName("CatFilter");
    return registration;
  }
}

参考

https://github.com/spring-pro...

jdk8知识点

如何排除静态资源请求路径?

自定义扩展过滤器的源码

package com.xxx.qrcode.ugate.payment.filter;

import com.dianping.cat.servlet.CatFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.springframework.util.AntPathMatcher;

/**
 * 重写CatFilter,排除.js/.css/.html等静态资源
 *
 * @author gzh
 * @createTime 2021/2/23 2:54 PM
 */
public class QrcodeCatFilter extends CatFilter {

  /**
   * 排除.js/.css/.html等静态资源
   */
  private static List<String> excludeUrlPatterns = Arrays.asList("/**/*.html", "/**/*.jsp",
      "/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg",
      "/**/*.jpeg", "/**/*.gif", "/**/*.svg");

  private static AntPathMatcher antPathMatcher = new AntPathMatcher();

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException,    ServletException {
    //获取当前请求的相对路径(即去掉域名/项目名字之后的路径)
    HttpServletRequest httpServletRequest = (HttpServletRequest)request;
    String ServletPath = httpServletRequest.getServletPath();

    //校验路径是否匹配
    boolean b = excludeUrlPatterns.stream()
        .anyMatch(e -> antPathMatcher.match(e, ServletPath));
    if (b) { //如果是静态资源,不走CatFilter
      chain.doFilter(request, response);
    }else { //如果不是静态资源,才走CatFilter
      super.doFilter(request, response, chain);
    }
  }
}

排除静态资源的时候,用了jdk8的知识点。

1.得到流stream
主要是从集合得到流,这个是jdk8才有的功能和方法。

2.得到流之后,要对流数据进行计算
什么计算?匹配数据。怎么匹配?用anyMatch方法来匹配。

3.anyMatch方法的入参是Predicate类型
源码

public interface Stream<T> extends BaseStream<T, Stream<T>> {
/**
     * Returns whether any elements of this stream match the provided
     * predicate.  May not evaluate the predicate on all elements if not
     * necessary for determining the result.  If the stream is empty then
     * {@code false} is returned and the predicate is not evaluated.
     *
     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
     * terminal operation</a>.
     *
     * @apiNote
     * This method evaluates the <em>existential quantification</em> of the
     * predicate over the elements of the stream (for some x P(x)).
     *
     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
     *                  <a href="package-summary.html#Statelessness">stateless</a>
     *                  predicate to apply to elements of this stream
     * @return {@code true} if any elements of the stream match the provided
     * predicate, otherwise {@code false}
     */
    boolean anyMatch(Predicate<? super T> predicate);

Predicate类型是函数式接口

/**
 * Represents a predicate (boolean-valued function) of one argument.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #test(Object)}.
 *
 * @param <T> the type of the input to the predicate
 *
 * @since 1.8
 */
@FunctionalInterface //有函数式接口注解,说明就是函数式接口,即入参可以是lambda表达式语句或代码块
public interface Predicate<T> {

4.e是什么?
e是遍历流的时候,流里的当前元素。

5.AntPathMatcher
pattern模式匹配路径,spring框架自带的匹配路径功能。核心有两点:

1)*.do  
*,表示匹配0或多个字符  
2)/**  
/**,表示匹配0或多个目录

参考

jdk8实战


总结

除了用Jdk8里的知识点,去排除静态资源请求路径,当然也可以用传统的代码去排除。具体实现就是遍历集合数据,然后一个个数据去匹配当前请求路径。

参考:https://blog.csdn.net/qq_2393...

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Johnny21 Johnny21
4年前
Promethus(普罗米修斯)监控
一、任务背景某某某公司是一家电商网站,由于公司的业务快速发展,公司要求对现有机器进行业务监控,责成运维部门来实施这个项目。任务要求1)部署监控服务器,实现7x24实时监控2)针对公司的业务及研发部门设计监控系统,对监控项和触发器拿出合理意见3)做好问题预警机制,对可能出现的问题要及时告警并形成严格的处理机制4)做好监控告警系统,要求可以实
Stella981 Stella981
3年前
CAT 3.0 开源发布,支持多语言客户端及多项性能提升
!cat(https://usergoldcdn.xitu.io/2018/11/2/166d21d7e89a29e2?w1902&h1087&fjpeg&s119201)项目背景CAT(CentralApplicationTracking),是美团点评基于Java开发的一套开源的分布式实时监控系统。美团点评基础架构
Stella981 Stella981
3年前
Nginx + lua +[memcached,redis]
精品案例1、Nginxluamemcached,redis实现网站灰度发布2、分库分表/基于Leaf组件实现的全球唯一ID(非UUID)3、Redis独立数据监控,实现订单超时操作/MQ死信操作SelectPollEpollReactor模型4、分布式任务调试Quartz应用
Stella981 Stella981
3年前
Eg挨蒙—Zabbix监控进程占cpu和内存大小及批量监控端口
监控简介:通过shell脚本的方式,实现对进程占cpu百分比和内存大小的监控,通过python脚本方式,实现批量监控服务器端口。一、监控进程占cpu的百分比和内存的大小1、在agent端编写脚本\root@monitorsbin\$cat/usr/local/zabbix/scripts/processtatus.sh!/
Stella981 Stella981
3年前
Spring Boot 监控和管理生产环境
springbootactuator模块提供了一个监控和管理生产环境的模块,可以使用http、jmx、ssh、telnet等拉管理和监控应用。审计(Auditing)、健康(health)、数据采集(metricsgathering)会自动加入到应用里面。首先,写一个最基本的springboot项目。基于Maven的项目添加‘starte
Stella981 Stella981
3年前
Serverless 实战:通过 Serverless 架构实现监控告警
在实际生产中,我们经常需要做一些监控脚本来监控网站服务或者API服务是否可用。传统的方法是使用网站监控平台(例如DNSPod监控、360网站服务监控,以及阿里云监控等),它们的原理是通过用户自己设置要监控的服务地址和监测的时间阈值,由监控平台定期发起请求对网站或服务的可用性进行判断。这些方法很大众化,通用性很强,但也不是所有场景都适合。例如,如
Stella981 Stella981
3年前
Prometheus监控告警浅析
前言最近有个新项目需要搞一套完整的监控告警系统,我们使用了开源监控告警系统Prometheus;其功能强大,可以很方便对其进行扩展,并且可以安装和使用简单;本文首先介绍Prometheus的整个监控流程;然后介绍如何收集监控数据,如何展示监控数据,如何触发告警;最后展示一个业务系统监控的demo。监控架构Prometheus的整个
API 小达人 API 小达人
1年前
开发常用的 3种 API 监控报告- Eolink Apikit
API监控报告是一种监测API异常的工具。在API管理中,查看API异常监控的监控报告,是EolinkApikit常用的功能。EolinkApikit的监控报告有3种:单接口监控报告、流程监控报告、项目监控报告
AlgoNebula
AlgoNebula
Lv1
沧海月明珠有泪,蓝田玉暖日生烟!此情可待成追忆,只是当时以惘然!
文章
4
粉丝
0
获赞
0