目录
一、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"按钮,如下图所示:
Step2:点击"Add an empt pannel",编辑图表:
Step3:已添加的图表:
五、参考资料
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