This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 52a91bb feat: use route/service name instead of id in prometheus
metric (#4004)
52a91bb is described below
commit 52a91bb846270febf4ff66a10914f92ab43e4d4a
Author: Shuyang Wu <[email protected]>
AuthorDate: Fri Apr 9 16:02:11 2021 +0800
feat: use route/service name instead of id in prometheus metric (#4004)
---
apisix/plugins/prometheus.lua | 6 ++
apisix/plugins/prometheus/exporter.lua | 22 ++--
docs/en/latest/plugins/prometheus.md | 32 +++---
docs/zh/latest/plugins/prometheus.md | 31 +++---
t/plugin/prometheus.t | 4 +-
t/plugin/prometheus2.t | 177 ++++++++++++++++++++++++++++++++-
6 files changed, 232 insertions(+), 40 deletions(-)
diff --git a/apisix/plugins/prometheus.lua b/apisix/plugins/prometheus.lua
index 5236dda..d89ffb6 100644
--- a/apisix/plugins/prometheus.lua
+++ b/apisix/plugins/prometheus.lua
@@ -23,6 +23,12 @@ local plugin_name = "prometheus"
local default_export_uri = "/apisix/prometheus/metrics"
local schema = {
type = "object",
+ properties = {
+ prefer_name = {
+ type = "boolean",
+ default = false
+ }
+ },
additionalProperties = false,
}
diff --git a/apisix/plugins/prometheus/exporter.lua
b/apisix/plugins/prometheus/exporter.lua
index 533415c..a4648b8 100644
--- a/apisix/plugins/prometheus/exporter.lua
+++ b/apisix/plugins/prometheus/exporter.lua
@@ -32,6 +32,7 @@ local get_upstreams = require("apisix.upstream").upstreams
local clear_tab = core.table.clear
local get_stream_routes = router.stream_routes
local get_protos = require("apisix.plugins.grpc-transcode.proto").protos
+local service_fetch = require("apisix.http.service").get
@@ -101,7 +102,7 @@ function _M.init()
metrics.latency = prometheus:histogram("http_latency",
"HTTP request latency in milliseconds per service in APISIX",
- {"type", "service", "consumer", "node"}, DEFAULT_BUCKETS)
+ {"type", "route", "service", "consumer", "node"}, DEFAULT_BUCKETS)
metrics.bandwidth = prometheus:counter("bandwidth",
"Total bandwidth in bytes consumed per service in APISIX",
@@ -115,15 +116,20 @@ function _M.log(conf, ctx)
local route_id = ""
local balancer_ip = ctx.balancer_ip or ""
- local service_id
+ local service_id = ""
local consumer_name = ctx.consumer_name or ""
local matched_route = ctx.matched_route and ctx.matched_route.value
if matched_route then
- service_id = matched_route.service_id or ""
route_id = matched_route.id
- else
- service_id = vars.host
+ service_id = matched_route.service_id or ""
+ if conf.prefer_name == true then
+ route_id = matched_route.name or route_id
+ if service_id ~= "" then
+ local service = service_fetch(service_id)
+ service_id = service and service.value.name or service_id
+ end
+ end
end
local matched_uri = ""
@@ -139,17 +145,17 @@ function _M.log(conf, ctx)
local latency = (ngx.now() - ngx.req.start_time()) * 1000
metrics.latency:observe(latency,
- gen_arr("request", service_id, consumer_name, balancer_ip))
+ gen_arr("request", route_id, service_id, consumer_name, balancer_ip))
local apisix_latency = latency
if ctx.var.upstream_response_time then
local upstream_latency = ctx.var.upstream_response_time * 1000
metrics.latency:observe(upstream_latency,
- gen_arr("upstream", service_id, consumer_name, balancer_ip))
+ gen_arr("upstream", route_id, service_id, consumer_name,
balancer_ip))
apisix_latency = apisix_latency - upstream_latency
end
metrics.latency:observe(apisix_latency,
- gen_arr("apisix", service_id, consumer_name, balancer_ip))
+ gen_arr("apisix", route_id, service_id, consumer_name, balancer_ip))
metrics.bandwidth:inc(vars.request_length,
gen_arr("ingress", route_id, service_id, consumer_name, balancer_ip))
diff --git a/docs/en/latest/plugins/prometheus.md
b/docs/en/latest/plugins/prometheus.md
index a7100bf..55de090 100644
--- a/docs/en/latest/plugins/prometheus.md
+++ b/docs/en/latest/plugins/prometheus.md
@@ -25,7 +25,9 @@ This plugin exposes metrics in Prometheus Exposition format.
## Attributes
-none.
+| Name | Type | Requirement | Default | Valid | Description
|
+| ------------ | --------- | ----------- | -------- | ----- |
------------------------------------------------------------------------------------------
|
+| prefer_name | boolean | optional | false | | When set to
`true`, would print route/service `name` instead of `id` in Prometheus metric. |
## API
@@ -57,8 +59,8 @@ plugin_attr:
## How to enable it
-`prometheus` plugin can be enable with empty table, because it doesn't have
-any options yet.
+`prometheus` plugin could be enable with empty table.
+Notice, `name` could be duplicated for multiple routes/services, so when set
`prefer_name` to `true`, take care of naming format or it could be misleading.
For example:
@@ -192,13 +194,13 @@ Or you can goto [Grafana
official](https://grafana.com/grafana/dashboards/11719)
Here is the original metric data of APISIX:
```shell
-$ curl http://127.0.0.1:9080/apisix/prometheus/metrics
+$ curl http://127.0.0.1:9091/apisix/prometheus/metrics
# HELP apisix_bandwidth Total bandwidth in bytes consumed per service in Apisix
# TYPE apisix_bandwidth counter
-apisix_bandwidth{type="egress",route="",service="127.0.0.1",consumer="",node=""}
8417
+apisix_bandwidth{type="egress",route="",service="",consumer="",node=""} 8417
apisix_bandwidth{type="egress",route="1",service="",consumer="",node="127.0.0.1"}
1420
apisix_bandwidth{type="egress",route="2",service="",consumer="",node="127.0.0.1"}
1420
-apisix_bandwidth{type="ingress",route="",service="127.0.0.1",consumer="",node=""}
189
+apisix_bandwidth{type="ingress",route="",service="",consumer="",node=""} 189
apisix_bandwidth{type="ingress",route="1",service="",consumer="",node="127.0.0.1"}
332
apisix_bandwidth{type="ingress",route="2",service="",consumer="",node="127.0.0.1"}
332
# HELP apisix_etcd_modify_indexes Etcd modify index for APISIX keys
@@ -227,9 +229,9 @@
apisix_batch_process_entries{name="zipkin_report",route_id="9",server_addr="127.
apisix_etcd_reachable 1
# HELP apisix_http_status HTTP status codes per service in Apisix
# TYPE apisix_http_status counter
-apisix_http_status{code="200",route="1",matched_uri="/hello",matched_host="",service="127.0.0.2",consumer="",node="127.0.0.1"}
4
-apisix_http_status{code="200",route="2",matched_uri="/world",matched_host="",service="bar.com",consumer="",node="127.0.0.1"}
4
-apisix_http_status{code="404",route="",matched_uri="",matched_host="",service="127.0.0.1",consumer="",node=""}
1
+apisix_http_status{code="200",route="1",matched_uri="/hello",matched_host="",service="",consumer="",node="127.0.0.1"}
4
+apisix_http_status{code="200",route="2",matched_uri="/world",matched_host="",service="",consumer="",node="127.0.0.1"}
4
+apisix_http_status{code="404",route="",matched_uri="",matched_host="",service="",consumer="",node=""}
1
# HELP apisix_nginx_http_current_connections Number of HTTP connections
# TYPE apisix_nginx_http_current_connections gauge
apisix_nginx_http_current_connections{state="accepted"} 11994
@@ -244,12 +246,12 @@ apisix_nginx_http_current_connections{state="writing"} 1
apisix_nginx_metric_errors_total 0
# HELP apisix_http_latency HTTP request latency in milliseconds per service in
APISIX
# TYPE apisix_http_latency histogram
-apisix_http_latency_bucket{type="apisix",service="",consumer="",node="127.0.0.1",le="1"}
1
-apisix_http_latency_bucket{type="apisix",service="",consumer="",node="127.0.0.1",le="2"}
1
-apisix_http_latency_bucket{type="request",service="",consumer="",node="127.0.0.1",le="1"}
1
-apisix_http_latency_bucket{type="request",service="",consumer="",node="127.0.0.1",le="2"}
1
-apisix_http_latency_bucket{type="upstream",service="",consumer="",node="127.0.0.1",le="1"}
1
-apisix_http_latency_bucket{type="upstream",service="",consumer="",node="127.0.0.1",le="2"}
1
+apisix_http_latency_bucket{type="apisix",route="1",service="",consumer="",node="127.0.0.1",le="1"}
1
+apisix_http_latency_bucket{type="apisix",route="1",service="",consumer="",node="127.0.0.1",le="2"}
1
+apisix_http_latency_bucket{type="request",route="1",service="",consumer="",node="127.0.0.1",le="1"}
1
+apisix_http_latency_bucket{type="request",route="1",service="",consumer="",node="127.0.0.1",le="2"}
1
+apisix_http_latency_bucket{type="upstream",route="1",service="",consumer="",node="127.0.0.1",le="1"}
1
+apisix_http_latency_bucket{type="upstream",route="1",service="",consumer="",node="127.0.0.1",le="2"}
1
...
# HELP apisix_node_info Info of APISIX node
# TYPE apisix_node_info gauge
diff --git a/docs/zh/latest/plugins/prometheus.md
b/docs/zh/latest/plugins/prometheus.md
index cef4745..4089894 100644
--- a/docs/zh/latest/plugins/prometheus.md
+++ b/docs/zh/latest/plugins/prometheus.md
@@ -25,7 +25,9 @@ title: prometheus
## 属性
-无
+| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述
|
+| ------------ | ------ | ------ | ------ | ------------ |
----------------------------------------------------- |
+| prefer_type | boolean | 可选 | false | | 设置为`true`时,Prometheus
指标中将使用路由和服务的 `name` 而不是 `id`。 |
## 接口
@@ -57,7 +59,8 @@ plugin_attr:
## 如何开启插件
-`prometheus` 插件用空{}就可以开启了,他没有任何的选项。
+`prometheus` 插件可以使用空 {} 开启。
+注意,多个路由/服务可以设置为相同的名称,因此当设置 `prefer_name` 为 `true` 时,注意规范命名否则容易引起误解。
例子如下:
@@ -184,13 +187,13 @@ plugin_attr:
这里是 APISIX 的原始的指标数据集:
```shell
-$ curl http://127.0.0.2:9080/apisix/prometheus/metrics
+$ curl http://127.0.0.1:9091/apisix/prometheus/metrics
# HELP apisix_bandwidth Total bandwidth in bytes consumed per service in Apisix
# TYPE apisix_bandwidth counter
-apisix_bandwidth{type="egress",route="",service="127.0.0.1",consumer="",node=""}
8417
+apisix_bandwidth{type="egress",route="",service="",consumer="",node=""} 8417
apisix_bandwidth{type="egress",route="1",service="",consumer="",node="127.0.0.1"}
1420
apisix_bandwidth{type="egress",route="2",service="",consumer="",node="127.0.0.1"}
1420
-apisix_bandwidth{type="ingress",route="",service="127.0.0.1",consumer="",node=""}
189
+apisix_bandwidth{type="ingress",route="",service="",consumer="",node=""} 189
apisix_bandwidth{type="ingress",route="1",service="",consumer="",node="127.0.0.1"}
332
apisix_bandwidth{type="ingress",route="2",service="",consumer="",node="127.0.0.1"}
332
# HELP apisix_etcd_modify_indexes Etcd modify index for APISIX keys
@@ -219,9 +222,9 @@
apisix_batch_process_entries{name="zipkin_report",route_id="9",server_addr="127.
apisix_etcd_reachable 1
# HELP apisix_http_status HTTP status codes per service in Apisix
# TYPE apisix_http_status counter
-apisix_http_status{code="200",route="1",matched_uri="/hello",matched_host="",service="127.0.0.2",consumer="",node="127.0.0.1"}
4
-apisix_http_status{code="200",route="2",matched_uri="/world",matched_host="",service="bar.com",consumer="",node="127.0.0.1"}
4
-apisix_http_status{code="404",route="",matched_uri="",matched_host="",service="127.0.0.1",consumer="",node=""}
1
+apisix_http_status{code="200",route="1",matched_uri="/hello",matched_host="",service="",consumer="",node="127.0.0.1"}
4
+apisix_http_status{code="200",route="2",matched_uri="/world",matched_host="",service="",consumer="",node="127.0.0.1"}
4
+apisix_http_status{code="404",route="",matched_uri="",matched_host="",service="",consumer="",node=""}
1
# HELP apisix_nginx_http_current_connections Number of HTTP connections
# TYPE apisix_nginx_http_current_connections gauge
apisix_nginx_http_current_connections{state="accepted"} 11994
@@ -236,12 +239,12 @@ apisix_nginx_http_current_connections{state="writing"} 1
apisix_nginx_metric_errors_total 0
# HELP apisix_http_latency HTTP request latency in milliseconds per service in
APISIX
# TYPE apisix_http_latency histogram
-apisix_http_latency_bucket{type="apisix",service="",consumer="",node="127.0.0.1",le="1"}
1
-apisix_http_latency_bucket{type="apisix",service="",consumer="",node="127.0.0.1",le="2"}
1
-apisix_http_latency_bucket{type="request",service="",consumer="",node="127.0.0.1",le="1"}
1
-apisix_http_latency_bucket{type="request",service="",consumer="",node="127.0.0.1",le="2"}
1
-apisix_http_latency_bucket{type="upstream",service="",consumer="",node="127.0.0.1",le="1"}
1
-apisix_http_latency_bucket{type="upstream",service="",consumer="",node="127.0.0.1",le="2"}
1
+apisix_http_latency_bucket{type="apisix",route="1",service="",consumer="",node="127.0.0.1",le="1"}
1
+apisix_http_latency_bucket{type="apisix",route="1",service="",consumer="",node="127.0.0.1",le="2"}
1
+apisix_http_latency_bucket{type="request",route="1",service="",consumer="",node="127.0.0.1",le="1"}
1
+apisix_http_latency_bucket{type="request",route="1",service="",consumer="",node="127.0.0.1",le="2"}
1
+apisix_http_latency_bucket{type="upstream",route="1",service="",consumer="",node="127.0.0.1",le="1"}
1
+apisix_http_latency_bucket{type="upstream",route="1",service="",consumer="",node="127.0.0.1",le="2"}
1
...
# HELP apisix_node_info Info of APISIX node
# TYPE apisix_node_info gauge
diff --git a/t/plugin/prometheus.t b/t/plugin/prometheus.t
index 7df67e4..216fcf2 100644
--- a/t/plugin/prometheus.t
+++ b/t/plugin/prometheus.t
@@ -303,7 +303,7 @@
qr/apisix_bandwidth\{type="egress",route="1",service="",consumer="",node="127.0.
--- request
GET /apisix/prometheus/metrics
--- response_body eval
-qr/apisix_http_latency_count\{type="request",service="",consumer="",node="127.0.0.1"\}
\d+/
+qr/apisix_http_latency_count\{type="request",route="1",service="",consumer="",node="127.0.0.1"\}
\d+/
--- no_error_log
[error]
@@ -344,7 +344,7 @@ passed
-=== TEST 16: use service 1 in route 1
+=== TEST 16: use service 1 in route 2
--- config
location /t {
content_by_lua_block {
diff --git a/t/plugin/prometheus2.t b/t/plugin/prometheus2.t
index c587c4e..5437485 100644
--- a/t/plugin/prometheus2.t
+++ b/t/plugin/prometheus2.t
@@ -238,7 +238,7 @@ GET /not_found
--- request
GET /apisix/prometheus/metrics
--- response_body eval
-qr/apisix_http_status\{code="404",route="",matched_uri="",matched_host="",service="localhost",consumer="",node=""\}
\d+/
+qr/apisix_http_status\{code="404",route="",matched_uri="",matched_host="",service="",consumer="",node=""\}
\d+/
--- no_error_log
[error]
@@ -728,3 +728,178 @@ GET /apisix/prometheus/metrics
--- error_code: 200
--- response_body_like eval
qr/apisix_batch_process_entries\{name="sls-logger",route_id="10",server_addr="127.0.0.1"\}
\d+/
+
+
+
+=== TEST 37: create service and route both with name
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/services/1',
+ ngx.HTTP_PUT,
+ [[{
+ "name": "service_name",
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "name": "route_name",
+ "service_id": 1,
+ "plugins": {
+ "prometheus": {
+ "prefer_name": true
+ }
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 38: pipeline of client request
+--- request
+GET /hello
+--- error_code: 200
+--- no_error_log
+[error]
+
+
+
+=== TEST 39: fetch the prometheus metric data
+--- request
+GET /apisix/prometheus/metrics
+--- response_body eval
+qr/apisix_bandwidth\{type="egress",route="route_name",service="service_name",consumer="",node="127.0.0.1"\}
\d+/
+--- no_error_log
+[error]
+
+
+
+=== TEST 40: remove service name
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/services/1',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 41: pipeline of client request
+--- request
+GET /hello
+--- error_code: 200
+--- no_error_log
+[error]
+
+
+
+=== TEST 42: fetch the prometheus metric data
+--- request
+GET /apisix/prometheus/metrics
+--- response_body eval
+qr/apisix_bandwidth\{type="egress",route="route_name",service="1",consumer="",node="127.0.0.1"\}
\d+/
+--- no_error_log
+[error]
+
+
+
+=== TEST 43: remove route name, but still set prefer_name to name
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "service_id": 1,
+ "plugins": {
+ "prometheus": {
+ "prefer_name": true
+ }
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 44: pipeline of client request
+--- request
+GET /hello
+--- error_code: 200
+--- no_error_log
+[error]
+
+
+
+=== TEST 45: fetch the prometheus metric data
+--- request
+GET /apisix/prometheus/metrics
+--- response_body eval
+qr/apisix_bandwidth\{type="egress",route="1",service="1",consumer="",node="127.0.0.1"\}
\d+/
+--- no_error_log
+[error]