目录

一、Prometheus自定义指标类型

1.1 Counter(计数器)

1.2 Gauge(仪表盘)

1.3 Histogram(直方图)

1.4 Summary(摘要)

二、PromQL语句

2.1 查询结果类型(3种)

2.2 查询语句

三、gateway自定义埋点

3.1 引入jar包

3.2 项目添加配置

3.3 gateway创建全局过滤器

四、Grafana自定义图表

五、参考资料


一、Prometheus自定义指标类型

共4种指标类型:Counter、Gauge、Histogram、Summary

1.1 Counter(计数器)

1):值只增不减

2):调用inc(),计数器+1

3):应用场景:请求总量、错误总量,微服务在线时间、CPU使用时间等

1.2 Gauge(仪表盘)

1):值可增可减,反应指标的当前状态

2):调用inc(),+1;dec(),-1

3):应用场景:当前正在处理的Http请求数量、CPU使用率、内存使用率等

1.3 Histogram(直方图)

指定分布范围内(buckets)记录大小或者事件发生的次数(数据分布情况)

1):默认的buckets范围为:{.005, .01, .025, .05, .075, .1, .25, .5, .75, 1, 2.5, 5, 7.5, 10}

2):自动创建3个指标:

              事件发生总次数:XX_count,如:请求总数

              所有事件产生值的总和: XX_sum,如:请求总数的响应时间总和

              事件产生值分布在bucket中的次数:XX_bucket,如:在1s-2s响应时间的次数

3):应用场景:请求响应时间分布等

1.4 Summary(摘要)

自定义分布范围的数据分布情况,类似Histogram

1):自定义分布范围quantile(与Histogram区别,可自定义)

2):自动创建3个指标:

              事件发生总次数:XX_count,如:请求总数

              所有事件产生值的总和: XX_sum,如:请求总数的响应时间总和

              事件产生值分布在quantile中的次数:XX{quantile="XXX"},如:在分位数XXX响应时间的次数

3):应用场景:请求响应时间分布等

二、PromQL语句

参考资料:https://www.bookstack.cn/read/prometheus_practice/promql-summary.md

2.1 查询结果类型(3种)

瞬时数据(Instant vector):一个时序只有一个点,例如:http_requests_total

区间数据(Range vector):一个时序有多个点,例如:http_requests_total[5m]

纯量数据(Scalar):纯量只有一个数字,没有时序,例如:count(http_requests_total)

2.2 查询语句

1):条件查询:=、!=、=~、!~,如:http_requests_total{code=~"2.."}:表示查询 code 为 "2xx" 的数据

2):算数运算符:+、-、*、/、%、^, 如: http_requests_total{code=~"2.."} * 2

3):比较运算符:==、!=、>、<、>=、<=, 如:http_requests_total{code=~"5.."} > 50

4):逻辑运算符:and、or、unless, 如:http_requests_total{code=~"5.."} or http_requests_total{code=~"4.."}

5):聚合运算符:sum、min、max、avg、count、topk,如:sum(http_requests_total{code=~"2.."})

6):内置函数:rate、floor......,如:rate(http_requests_total{code=~"2.."}[2m]):表示在2分钟内状态为2XX每秒请求数量,即:2min内请求增加量除以120s

三、gateway自定义埋点

3.1 引入jar包

<!-- 监控 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
	<groupId>io.micrometer</groupId>
	<artifactId>micrometer-registry-prometheus</artifactId>
	<version>1.6.5</version>
</dependency>

3.2 项目添加配置

management:
  endpoints:
    web:
      exposure:
        include: '*'

3.3 gateway创建全局过滤器

package com.common.instance.gateway.filters;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.*;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @description Grafana统计全局过滤器
 * @author tcm
 * @version 1.0.0
 * @date 2021/4/13 16:00
 **/
public class GrafanaStatisticsGlobalFilter implements GlobalFilter, Ordered {

    public static Summary requestLatency;
    public static Counter counter;
    public volatile static Gauge gauge;
    private PrometheusMeterRegistry prometheusMeterRegistry;

    public GrafanaStatisticsGlobalFilter(MeterRegistry meterRegistry){
        this.prometheusMeterRegistry = (PrometheusMeterRegistry)meterRegistry;
        requestLatency = Summary
                .build("demo_gateway_response_time_summary", "微服务响应时间")
                .labelNames("routeId", "uri", "status")
                .register(prometheusMeterRegistry.getPrometheusRegistry());
        counter = Counter
                .build("demo_gateway_request_count", "网关请求次数")
                .labelNames("routeId", "uri", "status")
                .register(prometheusMeterRegistry.getPrometheusRegistry());
        gauge = Gauge
                .build("demo_gateway_process_request_gauge", "网关进行中请求")
                .labelNames("routeId", "uri", "status")
                .register(prometheusMeterRegistry.getPrometheusRegistry());
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取路由
        Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
        // 定义标签s
        Summary.Timer requestTimer = requestLatency.labels(route.getId(), exchange.getRequest().getURI().getPath(), String.valueOf(exchange.getResponse().getStatusCode().value())).startTimer();
        // 请求加1
        gauge.labels(route.getId(), exchange.getRequest().getURI().getPath(), String.valueOf(exchange.getResponse().getStatusCode().value())).inc();

        return chain.filter(exchange)
                .doOnSuccess(aVoid -> endTimer(requestTimer, exchange, "doOnSuccess"))
                .doOnError(throwable -> endTimer(requestTimer, exchange, "doOnError"));
    }

    // 过滤器结束后,处理逻辑
    private void endTimer(Summary.Timer requestTimer, ServerWebExchange exchange, String flag) {
        // 获取路由
        Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
        //
        requestTimer.observeDuration();
        // 响应加1
        counter.labels(route.getId(), exchange.getRequest().getURI().getPath(), String.valueOf(exchange.getResponse().getStatusCode().value())).inc();
        // 响应请求减1
        gauge.labels(route.getId(), exchange.getRequest().getURI().getPath(), String.valueOf(exchange.getResponse().getStatusCode().value())).dec();
    }

    @Override
    public int getOrder() {
        return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 50;
    }

}

四、Grafana自定义图表

Step1:点击"Create"按钮,如下图所示:

Prometheus 指标采集只能是数字吗 prometheus自定义指标_自定义

Step2:点击"Add an empt pannel",编辑图表:

Prometheus 指标采集只能是数字吗 prometheus自定义指标_自定义_02

Step3:已添加的图表:

Prometheus 指标采集只能是数字吗 prometheus自定义指标_响应时间_03

五、参考资料

https://cloud.tencent.com/developer/article/1553781

http://yunlzheng.github.io/2018/01/24/use-prometheus-monitor-your-spring-boot-application/

PromQL用法:https://www.bookstack.cn/read/prometheus_practice/promql-summary.md