This is an automated email from the ASF dual-hosted git repository.
LiteSun 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 238aa9ee43 feat(prometheus): configure expired metric cleanup interval
(#13981)
238aa9ee43 is described below
commit 238aa9ee437d0dd3117649cfd55bbdd930895f4d
Author: AlinsRan <[email protected]>
AuthorDate: Tue Oct 27 16:52:30 2026 +0800
feat(prometheus): configure expired metric cleanup interval (#13981)
---
apisix-master-0.rockspec | 2 +-
apisix/cli/config.lua | 3 +-
apisix/plugins/prometheus/exporter.lua | 10 ++-
conf/config.yaml.example | 1 +
docs/en/latest/plugins/prometheus.md | 3 +
docs/zh/latest/plugins/prometheus.md | 3 +
t/plugin/prometheus-cleanup-interval.t | 113 +++++++++++++++++++++++++++++++++
7 files changed, 131 insertions(+), 4 deletions(-)
diff --git a/apisix-master-0.rockspec b/apisix-master-0.rockspec
index 1e4b1e0276..441b56dd03 100644
--- a/apisix-master-0.rockspec
+++ b/apisix-master-0.rockspec
@@ -55,7 +55,7 @@ dependencies = {
"lua-resty-openidc = 1.9.0-1",
"lua-resty-saml = 0.2.7",
"luafilesystem = 1.8.0-1",
- "nginx-lua-prometheus-api7 = 1.0.0-1",
+ "nginx-lua-prometheus-api7 = 1.1.0-1",
"jsonschema = 0.9.13-0",
"lua-resty-ipmatcher = 0.6.1-0",
"lua-resty-kafka = 0.23-0",
diff --git a/apisix/cli/config.lua b/apisix/cli/config.lua
index a35ffa5b29..2ce29a0a47 100644
--- a/apisix/cli/config.lua
+++ b/apisix/cli/config.lua
@@ -359,7 +359,8 @@ local _M = {
ip = "127.0.0.1",
port = 9091
},
- refresh_interval = 15
+ refresh_interval = 15,
+ remove_expired_keys_interval = 3600
},
["server-info"] = {
report_ttl = 60
diff --git a/apisix/plugins/prometheus/exporter.lua
b/apisix/plugins/prometheus/exporter.lua
index 4ccc3f56b7..42467761e6 100644
--- a/apisix/plugins/prometheus/exporter.lua
+++ b/apisix/plugins/prometheus/exporter.lua
@@ -565,7 +565,10 @@ function _M.http_init(prometheus_enabled_in_stream)
local ai_cache_embedding_latency_exptime = core.table.try_read_attr(attr,
"metrics",
"ai_cache_embedding_latency", "expire")
- prometheus = base_prometheus.init("prometheus-metrics", metric_prefix)
+ prometheus = base_prometheus.init("prometheus-metrics", {
+ prefix = metric_prefix,
+ remove_expired_keys_interval = attr and
attr.remove_expired_keys_interval,
+ })
metrics.connections = prometheus:gauge("nginx_http_current_connections",
"Number of HTTP connections",
@@ -733,7 +736,10 @@ function _M.stream_init()
metric_prefix = attr.metric_prefix
end
- prometheus = base_prometheus.init("prometheus-metrics", metric_prefix)
+ prometheus = base_prometheus.init("prometheus-metrics", {
+ prefix = metric_prefix,
+ remove_expired_keys_interval = attr and
attr.remove_expired_keys_interval,
+ })
init_stream_metrics()
diff --git a/conf/config.yaml.example b/conf/config.yaml.example
index d07a8d0563..c654eb4ca9 100644
--- a/conf/config.yaml.example
+++ b/conf/config.yaml.example
@@ -724,6 +724,7 @@ plugin_attr: # Plugin attributes
ip: 127.0.0.1 # Set the IP.
port: 9091 # Set the port.
refresh_interval: 15 # Set the interval for refreshing
cached metric data. unit: second.
+ remove_expired_keys_interval: 3600 # Cleanup interval in seconds;
capped at 3600. Non-positive values disable cleanup.
# metrics: # Create extra labels from nginx variables:
https://nginx.org/en/docs/varindex.html
# http_status:
# expire: 0 # The expiration time after which metrics are removed.
unit: second.
diff --git a/docs/en/latest/plugins/prometheus.md
b/docs/en/latest/plugins/prometheus.md
index b793cf0709..97da21a7bc 100644
--- a/docs/en/latest/plugins/prometheus.md
+++ b/docs/en/latest/plugins/prometheus.md
@@ -43,6 +43,8 @@ By default, `prometheus` configurations are pre-configured in
the [default confi
The prompt- and completion-token histograms default to buckets at `1`, `10`,
`50`, `100`, `200`, `500`, `1000`, `2000`, `5000`, `10000`, `20000`, `50000`,
`100000`, `200000`, `500000`, and `1000000` tokens. Configure
`llm_prompt_tokens_buckets` and `llm_completion_tokens_buckets` when different
boundaries better fit the workload.
+`remove_expired_keys_interval` controls expired metric cleanup in both HTTP
and stream workers. It defaults to 3600 seconds; larger values are capped at
3600, and non-positive values disable cleanup. Automatic reclamation remains
enabled for positive intervals. This is independent of `refresh_interval`,
which controls the metrics exposition cache. Shorter cleanup intervals reclaim
expired entries sooner but scan the shared dictionary more often. Instances
sharing the dictionary use the s [...]
+
To customize these values, add the corresponding configurations to
`config.yaml`. For example:
```yaml
@@ -50,6 +52,7 @@ plugin_attr:
prometheus: # Plugin: prometheus attributes
export_uri: /apisix/prometheus/metrics # Set the URI for the Prometheus
metrics endpoint.
metric_prefix: apisix_ # Set the prefix for Prometheus
metrics generated by APISIX.
+ remove_expired_keys_interval: 3600 # Cleanup interval in seconds.
enable_export_server: true # Enable the Prometheus export
server.
export_addr: # Set the address for the
Prometheus export server.
ip: 127.0.0.1 # Set the IP.
diff --git a/docs/zh/latest/plugins/prometheus.md
b/docs/zh/latest/plugins/prometheus.md
index 33b513950f..434847b7c6 100644
--- a/docs/zh/latest/plugins/prometheus.md
+++ b/docs/zh/latest/plugins/prometheus.md
@@ -43,6 +43,8 @@ description: 本文将介绍 prometheus 插件,以及将 APISIX 与 Prometheu
prompt token 和 completion token 直方图的默认桶边界为
`1`、`10`、`50`、`100`、`200`、`500`、`1000`、`2000`、`5000`、`10000`、`20000`、`50000`、`100000`、`200000`、`500000`
和 `1000000` 个 token。如果这些边界不适合实际负载,可通过 `llm_prompt_tokens_buckets` 和
`llm_completion_tokens_buckets` 自定义。
+`remove_expired_keys_interval` 控制 HTTP 和 stream worker 的过期指标清理间隔,默认 3600
秒;更大的值按 3600 秒处理,非正数关闭清理。间隔为正数时,自动回收保持开启。此配置与控制指标输出缓存的 `refresh_interval`
独立。缩短间隔可以更早回收过期条目,但会增加共享字典扫描频率。共享字典的实例使用相同间隔;reload 时缩短间隔后,回收仍可能等待原间隔结束。
+
要自定义这些值,请将相应的配置添加到 config.yaml 中。例如:
```yaml
@@ -50,6 +52,7 @@ plugin_attr:
prometheus: # 插件:prometheus 属性
export_uri: /apisix/prometheus/metrics # 设置 Prometheus 指标端点的 URI。
metric_prefix: apisix_ # 设置 APISIX 生成的 Prometheus 指标的前缀。
+ remove_expired_keys_interval: 3600 # 过期指标清理间隔,单位为秒。
enable_export_server: true # 启用 Prometheus 导出服务器。
export_addr: # 设置 Prometheus 导出服务器的地址。
ip: 127.0.0.1 # 设置 IP。
diff --git a/t/plugin/prometheus-cleanup-interval.t
b/t/plugin/prometheus-cleanup-interval.t
new file mode 100644
index 0000000000..899bdd2fb5
--- /dev/null
+++ b/t/plugin/prometheus-cleanup-interval.t
@@ -0,0 +1,113 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+use t::APISIX 'no_plan';
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+ $block->set_value("extra_yaml_config", "stream_plugins:\n -
prometheus\n");
+ $block->set_value("stream_conf_enable", 1);
+ $block->set_value("extra_stream_config", <<'_EOC_');
+server {
+ listen 1993;
+ content_by_lua_block {
+ local prom =
require("apisix.plugins.prometheus.exporter").get_prometheus()
+ ngx.say(prom.remove_expired_keys_interval, ":",
prom.auto_flush_expired, ":", prom.prefix)
+ }
+}
+_EOC_
+ $block->set_value("config", <<'_EOC_');
+ location /t {
+ content_by_lua_block {
+ local prom =
require("apisix.plugins.prometheus.exporter").get_prometheus()
+ ngx.say("http: ", prom.remove_expired_keys_interval, ":",
+ prom.auto_flush_expired, ":", prom.prefix)
+ local sock = ngx.socket.tcp()
+ assert(sock:connect("127.0.0.1", 1993))
+ ngx.say("stream: ", assert(sock:receive("*l")))
+ sock:close()
+ }
+ }
+_EOC_
+ $block->set_value("request", "GET /t");
+});
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: default cleanup interval
+--- response_body
+http: 3600:true:apisix_
+stream: 3600:true:apisix_
+--- no_error_log
+[error]
+
+
+
+=== TEST 2: custom cleanup interval and metric prefix
+--- yaml_config
+plugin_attr:
+ prometheus:
+ remove_expired_keys_interval: 30
+ metric_prefix: custom_
+--- response_body
+http: 30:true:custom_
+stream: 30:true:custom_
+--- no_error_log
+[error]
+
+
+
+=== TEST 3: cleanup interval is capped
+--- yaml_config
+plugin_attr:
+ prometheus:
+ remove_expired_keys_interval: 7200
+ metric_prefix: apisix_
+--- response_body
+http: 3600:true:apisix_
+stream: 3600:true:apisix_
+--- no_error_log
+[error]
+
+
+
+=== TEST 4: zero disables cleanup
+--- yaml_config
+plugin_attr:
+ prometheus:
+ remove_expired_keys_interval: 0
+ metric_prefix: apisix_
+--- response_body
+http: 0:true:apisix_
+stream: 0:true:apisix_
+--- no_error_log
+[error]
+
+
+
+=== TEST 5: negative interval disables cleanup
+--- yaml_config
+plugin_attr:
+ prometheus:
+ remove_expired_keys_interval: -1
+ metric_prefix: apisix_
+--- response_body
+http: -1:true:apisix_
+stream: -1:true:apisix_
+--- no_error_log
+[error]