From 06a1151a425a56bdf4df340d813f16da1fec1547 Mon Sep 17 00:00:00 2001 From: Sihyeon Jang Date: Tue, 14 Apr 2026 09:55:56 +0900 Subject: [PATCH] fix: store KeyIndex entries without exptime to allow safe flush_expired usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When metrics are registered with an exptime (e.g. expire=300), the KeyIndex index entries (__key:N) were also stored with the same exptime via dict:add(). However, while metric value keys have their TTL refreshed on every incr/set call, the KeyIndex index entries are NOT refreshed because prometheus.lua's lookup_or_create() returns early from its local Lua cache on cache hit, skipping the key_index:add() call entirely. This means that after 'exptime' seconds, the index entry expires and gets removed by flush_expired() — even for metrics that are still actively being recorded. On the next metric_data() collection, sync_expired() detects the missing index entry and removes it from memory, causing the metric to silently disappear from Prometheus output. Fix: store KeyIndex entries with nil exptime (permanent). Since dict:add() only succeeds once per key (returns 'exists' error if key exists), setting nil here means the index entry is created permanently, while metric value keys still expire normally. flush_expired() will then only remove expired metric value entries, leaving the index intact. --- prometheus_keys.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus_keys.lua b/prometheus_keys.lua index 45d8066..1127086 100644 --- a/prometheus_keys.lua +++ b/prometheus_keys.lua @@ -133,7 +133,7 @@ function KeyIndex:add(key_or_keys, err_msg_lru_eviction, exptime) end end N = N+1 - local ok, err, forcible = self.dict:add(self.key_prefix .. N, key, exptime) + local ok, err, forcible = self.dict:add(self.key_prefix .. N, key, nil) if ok then local _, _, forcible2 = self.dict:incr(self.key_count, 1, 0) self.keys[N] = key