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]

Reply via email to