From 6a685979b0f3ee523497e1af2d5b3c27fd5ffd5a Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Fri, 26 Jun 2026 16:08:25 +0300 Subject: [PATCH 01/17] test --- .../inputs/prometheus_http/prometheus_http.go | 29 ++++++++++++------- .../prometheus_http/prometheus_http_test.go | 22 ++++++++++++++ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index d0a14c7e7080a..d56bfd3a80d59 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -103,9 +103,9 @@ type PrometheusHttp struct { errors *RateCounter client *http.Client mtx *sync.Mutex - //files *sync.Map - //fileHash map[string]string - cache *bigcache.BigCache + files *sync.Map + hashes *sync.Map + cache *bigcache.BigCache } type PrometheusHttpPushFunc = func(when time.Time, tags map[string]string, stamp time.Time, value float64) @@ -123,9 +123,6 @@ type PrometheusHttpDatasource interface { var description = "Collect data from Prometheus http api" -var globalFiles = sync.Map{} -var globalHashes = sync.Map{} - const pluginName = "prometheus_http" // Description will return a short string to explain what the plugin does. @@ -274,7 +271,12 @@ func (p *PrometheusHttp) getAllTags(values, metricTags, metricVars map[string]st files := make(map[string]interface{}) - globalFiles.Range(func(key, value interface{}) bool { + if p.files == nil { + m["files"] = files + return m + } + + p.files.Range(func(key, value interface{}) bool { files[fmt.Sprint(key)] = value return true }) @@ -987,10 +989,16 @@ func (p *PrometheusHttp) readFiles(gid uint64, files *sync.Map, hashes *sync.Map func (p *PrometheusHttp) Gather(acc telegraf.Accumulator) error { p.acc = acc + if p.files == nil { + p.files = &sync.Map{} + } + if p.hashes == nil { + p.hashes = &sync.Map{} + } var ds PrometheusHttpDatasource = nil gid := utils.GoRoutineID() - p.readFiles(gid, &globalFiles, &globalHashes, p.Metrics, false) + p.readFiles(gid, p.files, p.hashes, p.Metrics, false) // Gather data err := p.gatherMetrics(gid, ds) return err @@ -1037,14 +1045,15 @@ func (p *PrometheusHttp) Init() error { p.setDefaultMetric(gid, m) } - //p.files = &sync.Map{} p.requests = NewRateCounter(time.Duration(p.Interval)) p.errors = NewRateCounter(time.Duration(p.Interval)) p.mtx = &sync.Mutex{} + p.files = &sync.Map{} + p.hashes = &sync.Map{} if len(p.Files) > 0 { - entries, length := p.readFiles(gid, &globalFiles, &globalHashes, p.Metrics, true) + entries, length := p.readFiles(gid, p.files, p.hashes, p.Metrics, true) seconds := time.Duration(p.Timeout).Seconds() diff --git a/plugins/inputs/prometheus_http/prometheus_http_test.go b/plugins/inputs/prometheus_http/prometheus_http_test.go index dc5411d6987a0..2a61ae4341bcf 100644 --- a/plugins/inputs/prometheus_http/prometheus_http_test.go +++ b/plugins/inputs/prometheus_http/prometheus_http_test.go @@ -1,6 +1,7 @@ package prometheus_http import ( + "sync" "testing" "github.com/stretchr/testify/require" @@ -17,3 +18,24 @@ func TestDescription(t *testing.T) { output := c.Description() require.Equal(t, output, description, "Description output is not correct") } + +func TestGetAllTagsUsesInstanceFiles(t *testing.T) { + p1 := &PrometheusHttp{files: &sync.Map{}} + p2 := &PrometheusHttp{files: &sync.Map{}} + + p1.files.Store("first", map[string]interface{}{"value": "one"}) + p2.files.Store("second", map[string]interface{}{"value": "two"}) + + tags1 := p1.getAllTags(map[string]string{"metric": "a"}, nil, nil) + tags2 := p2.getAllTags(map[string]string{"metric": "b"}, nil, nil) + + files1, ok := tags1["files"].(map[string]interface{}) + require.True(t, ok) + require.Contains(t, files1, "first") + require.NotContains(t, files1, "second") + + files2, ok := tags2["files"].(map[string]interface{}) + require.True(t, ok) + require.Contains(t, files2, "second") + require.NotContains(t, files2, "first") +} From f067979090302598cd86cbc58c7cb21456b550d9 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Fri, 26 Jun 2026 17:46:23 +0300 Subject: [PATCH 02/17] test --- cmd/telegraf/telegraf.go | 5 +++ plugin.go | 6 +++ .../inputs/prometheus_http/prometheus_http.go | 33 ++++++++--------- .../prometheus_http/prometheus_http_test.go | 37 +++++++++++-------- 4 files changed, 48 insertions(+), 33 deletions(-) diff --git a/cmd/telegraf/telegraf.go b/cmd/telegraf/telegraf.go index dabc49f449543..bbce4921dddd1 100755 --- a/cmd/telegraf/telegraf.go +++ b/cmd/telegraf/telegraf.go @@ -518,6 +518,11 @@ func (t *Telegraf) runAgent(ctx context.Context, reloadConfig bool) error { if c, err = t.loadConfiguration(); err != nil { return err } + for _, input := range c.Inputs { + if plugin, ok := input.Input.(telegraf.ConfigReloader); ok { + plugin.OnConfigReload() + } + } } if !t.test && t.testWait == 0 && len(c.Outputs) == 0 { diff --git a/plugin.go b/plugin.go index 197b59d2f32b1..2bdf5c04282a3 100644 --- a/plugin.go +++ b/plugin.go @@ -62,3 +62,9 @@ type StatefulPlugin interface { type ProbePlugin interface { Probe() error } + +// ConfigReloader allows a plugin to react when Telegraf has loaded a fresh +// configuration during a runtime reload and before the new agent starts. +type ConfigReloader interface { + OnConfigReload() +} diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index d56bfd3a80d59..bd704e1f21e88 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -103,8 +103,6 @@ type PrometheusHttp struct { errors *RateCounter client *http.Client mtx *sync.Mutex - files *sync.Map - hashes *sync.Map cache *bigcache.BigCache } @@ -123,6 +121,9 @@ type PrometheusHttpDatasource interface { var description = "Collect data from Prometheus http api" +var globalFiles = sync.Map{} +var globalHashes = sync.Map{} + const pluginName = "prometheus_http" // Description will return a short string to explain what the plugin does. @@ -130,6 +131,15 @@ func (*PrometheusHttp) Description() string { return description } +func resetGlobalFileCache() { + globalFiles = sync.Map{} + globalHashes = sync.Map{} +} + +func (*PrometheusHttp) OnConfigReload() { + resetGlobalFileCache() +} + var sampleConfig = ` # ` @@ -271,12 +281,7 @@ func (p *PrometheusHttp) getAllTags(values, metricTags, metricVars map[string]st files := make(map[string]interface{}) - if p.files == nil { - m["files"] = files - return m - } - - p.files.Range(func(key, value interface{}) bool { + globalFiles.Range(func(key, value interface{}) bool { files[fmt.Sprint(key)] = value return true }) @@ -989,16 +994,10 @@ func (p *PrometheusHttp) readFiles(gid uint64, files *sync.Map, hashes *sync.Map func (p *PrometheusHttp) Gather(acc telegraf.Accumulator) error { p.acc = acc - if p.files == nil { - p.files = &sync.Map{} - } - if p.hashes == nil { - p.hashes = &sync.Map{} - } var ds PrometheusHttpDatasource = nil gid := utils.GoRoutineID() - p.readFiles(gid, p.files, p.hashes, p.Metrics, false) + p.readFiles(gid, &globalFiles, &globalHashes, p.Metrics, false) // Gather data err := p.gatherMetrics(gid, ds) return err @@ -1048,12 +1047,10 @@ func (p *PrometheusHttp) Init() error { p.requests = NewRateCounter(time.Duration(p.Interval)) p.errors = NewRateCounter(time.Duration(p.Interval)) p.mtx = &sync.Mutex{} - p.files = &sync.Map{} - p.hashes = &sync.Map{} if len(p.Files) > 0 { - entries, length := p.readFiles(gid, p.files, p.hashes, p.Metrics, true) + entries, length := p.readFiles(gid, &globalFiles, &globalHashes, p.Metrics, true) seconds := time.Duration(p.Timeout).Seconds() diff --git a/plugins/inputs/prometheus_http/prometheus_http_test.go b/plugins/inputs/prometheus_http/prometheus_http_test.go index 2a61ae4341bcf..63276ecd0de77 100644 --- a/plugins/inputs/prometheus_http/prometheus_http_test.go +++ b/plugins/inputs/prometheus_http/prometheus_http_test.go @@ -1,7 +1,6 @@ package prometheus_http import ( - "sync" "testing" "github.com/stretchr/testify/require" @@ -19,23 +18,31 @@ func TestDescription(t *testing.T) { require.Equal(t, output, description, "Description output is not correct") } -func TestGetAllTagsUsesInstanceFiles(t *testing.T) { - p1 := &PrometheusHttp{files: &sync.Map{}} - p2 := &PrometheusHttp{files: &sync.Map{}} +func TestGetAllTagsUsesGlobalFiles(t *testing.T) { + resetGlobalFileCache() + t.Cleanup(resetGlobalFileCache) - p1.files.Store("first", map[string]interface{}{"value": "one"}) - p2.files.Store("second", map[string]interface{}{"value": "two"}) + globalFiles.Store("shared", map[string]interface{}{"value": "one"}) - tags1 := p1.getAllTags(map[string]string{"metric": "a"}, nil, nil) - tags2 := p2.getAllTags(map[string]string{"metric": "b"}, nil, nil) + tags := (&PrometheusHttp{}).getAllTags(map[string]string{"metric": "a"}, nil, nil) - files1, ok := tags1["files"].(map[string]interface{}) + files, ok := tags["files"].(map[string]interface{}) require.True(t, ok) - require.Contains(t, files1, "first") - require.NotContains(t, files1, "second") + require.Contains(t, files, "shared") +} - files2, ok := tags2["files"].(map[string]interface{}) - require.True(t, ok) - require.Contains(t, files2, "second") - require.NotContains(t, files2, "first") +func TestOnConfigReloadClearsGlobalFiles(t *testing.T) { + resetGlobalFileCache() + t.Cleanup(resetGlobalFileCache) + + globalFiles.Store("shared", map[string]interface{}{"value": "one"}) + globalHashes.Store("shared", uint64(123)) + + (&PrometheusHttp{}).OnConfigReload() + + files := (&PrometheusHttp{}).getAllTags(nil, nil, nil)["files"].(map[string]interface{}) + require.Empty(t, files) + + _, ok := globalHashes.Load("shared") + require.False(t, ok) } From d5fc5e6c7865788592c5d75295aa08cdaab86da8 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Wed, 1 Jul 2026 10:37:22 +0300 Subject: [PATCH 03/17] rollback prev changes + update bigcache --- cmd/telegraf/telegraf.go | 5 ---- go.mod | 2 +- go.sum | 4 +-- plugin.go | 6 ---- .../inputs/prometheus_http/prometheus_http.go | 14 +++------ .../prometheus_http/prometheus_http_test.go | 29 ------------------- 6 files changed, 7 insertions(+), 53 deletions(-) diff --git a/cmd/telegraf/telegraf.go b/cmd/telegraf/telegraf.go index bbce4921dddd1..dabc49f449543 100755 --- a/cmd/telegraf/telegraf.go +++ b/cmd/telegraf/telegraf.go @@ -518,11 +518,6 @@ func (t *Telegraf) runAgent(ctx context.Context, reloadConfig bool) error { if c, err = t.loadConfiguration(); err != nil { return err } - for _, input := range c.Inputs { - if plugin, ok := input.Input.(telegraf.ConfigReloader); ok { - plugin.OnConfigReload() - } - } } if !t.test && t.testWait == 0 && len(c.Outputs) == 0 { diff --git a/go.mod b/go.mod index 819218ac1871e..0c14712a833f5 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/alitto/pond v1.9.2 github.com/alitto/pond/v2 v2.3.4 github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 - github.com/allegro/bigcache v1.2.1 + github.com/allegro/bigcache/v3 v3.1.0 github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9 github.com/antchfx/jsonquery v1.3.6 github.com/antchfx/xmlquery v1.4.4 diff --git a/go.sum b/go.sum index 4cc57c0445858..6da7b57b9e0fe 100644 --- a/go.sum +++ b/go.sum @@ -828,8 +828,8 @@ github.com/alitto/pond/v2 v2.3.4 h1:hR0bqAwJiI2chu3cLN4gVyNC7rc5mj/l5wg0710nxsY= github.com/alitto/pond/v2 v2.3.4/go.mod h1:xkjYEgQ05RSpWdfSd1nM3OVv7TBhLdy7rMp3+2Nq+yE= github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 h1:qagvUyrgOnBIlVRQWOyCZGVKUIYbMBdGdJ104vBpRFU= github.com/aliyun/alibaba-cloud-sdk-go v1.63.107/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ= -github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= -github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/allegro/bigcache/v3 v3.1.0 h1:H2Vp8VOvxcrB91o86fUSVJFqeuz8kpyyB02eH3bSzwk= +github.com/allegro/bigcache/v3 v3.1.0/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I= github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9 h1:FXrPTd8Rdlc94dKccl7KPmdmIbVh/OjelJ8/vgMRzcQ= github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9/go.mod h1:eliMa/PW+RDr2QLWRmLH1R1ZA4RInpmvOzDDXtaIZkc= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= diff --git a/plugin.go b/plugin.go index 2bdf5c04282a3..197b59d2f32b1 100644 --- a/plugin.go +++ b/plugin.go @@ -62,9 +62,3 @@ type StatefulPlugin interface { type ProbePlugin interface { Probe() error } - -// ConfigReloader allows a plugin to react when Telegraf has loaded a fresh -// configuration during a runtime reload and before the new agent starts. -type ConfigReloader interface { - OnConfigReload() -} diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index bd704e1f21e88..d0a14c7e7080a 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -103,7 +103,9 @@ type PrometheusHttp struct { errors *RateCounter client *http.Client mtx *sync.Mutex - cache *bigcache.BigCache + //files *sync.Map + //fileHash map[string]string + cache *bigcache.BigCache } type PrometheusHttpPushFunc = func(when time.Time, tags map[string]string, stamp time.Time, value float64) @@ -131,15 +133,6 @@ func (*PrometheusHttp) Description() string { return description } -func resetGlobalFileCache() { - globalFiles = sync.Map{} - globalHashes = sync.Map{} -} - -func (*PrometheusHttp) OnConfigReload() { - resetGlobalFileCache() -} - var sampleConfig = ` # ` @@ -1044,6 +1037,7 @@ func (p *PrometheusHttp) Init() error { p.setDefaultMetric(gid, m) } + //p.files = &sync.Map{} p.requests = NewRateCounter(time.Duration(p.Interval)) p.errors = NewRateCounter(time.Duration(p.Interval)) p.mtx = &sync.Mutex{} diff --git a/plugins/inputs/prometheus_http/prometheus_http_test.go b/plugins/inputs/prometheus_http/prometheus_http_test.go index 63276ecd0de77..dc5411d6987a0 100644 --- a/plugins/inputs/prometheus_http/prometheus_http_test.go +++ b/plugins/inputs/prometheus_http/prometheus_http_test.go @@ -17,32 +17,3 @@ func TestDescription(t *testing.T) { output := c.Description() require.Equal(t, output, description, "Description output is not correct") } - -func TestGetAllTagsUsesGlobalFiles(t *testing.T) { - resetGlobalFileCache() - t.Cleanup(resetGlobalFileCache) - - globalFiles.Store("shared", map[string]interface{}{"value": "one"}) - - tags := (&PrometheusHttp{}).getAllTags(map[string]string{"metric": "a"}, nil, nil) - - files, ok := tags["files"].(map[string]interface{}) - require.True(t, ok) - require.Contains(t, files, "shared") -} - -func TestOnConfigReloadClearsGlobalFiles(t *testing.T) { - resetGlobalFileCache() - t.Cleanup(resetGlobalFileCache) - - globalFiles.Store("shared", map[string]interface{}{"value": "one"}) - globalHashes.Store("shared", uint64(123)) - - (&PrometheusHttp{}).OnConfigReload() - - files := (&PrometheusHttp{}).getAllTags(nil, nil, nil)["files"].(map[string]interface{}) - require.Empty(t, files) - - _, ok := globalHashes.Load("shared") - require.False(t, ok) -} From 08e567b4dc7bf7ab724bf597d5690452a96c4368 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Wed, 1 Jul 2026 10:42:51 +0300 Subject: [PATCH 04/17] fix --- plugins/inputs/prometheus_http/prometheus_http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index d0a14c7e7080a..35c300f5afe74 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -18,7 +18,7 @@ import ( "sync" "time" - "github.com/allegro/bigcache" + "github.com/allegro/bigcache/v3" "github.com/araddon/dateparse" "gopkg.in/yaml.v3" From 8ad71997daf7538c7ef9adb1b88a6102ea1ec261 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Wed, 1 Jul 2026 11:38:43 +0300 Subject: [PATCH 05/17] test increased cache dur --- plugins/inputs/prometheus_http/prometheus_http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 35c300f5afe74..49698639954d7 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -1049,7 +1049,7 @@ func (p *PrometheusHttp) Init() error { seconds := time.Duration(p.Timeout).Seconds() if p.CacheDuration <= 0 { - p.CacheDuration = config.Duration(time.Second * time.Duration(seconds)) + p.CacheDuration = config.Duration(time.Second * time.Duration(seconds) * 10) } config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) From 6167c27da78245688394ece0ccd5289d70afb3bd Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Wed, 1 Jul 2026 12:03:06 +0300 Subject: [PATCH 06/17] test cache clean window --- plugins/inputs/prometheus_http/prometheus_http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 49698639954d7..09e51608defd9 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -1054,7 +1054,7 @@ func (p *PrometheusHttp) Init() error { config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) config.Shards = 256 - config.CleanWindow = 0 + config.CleanWindow = time.Duration(p.CacheDuration * 3) /*if seconds > 0 { t := int(math.Round(seconds / 2)) if t > 1 { From e41e566c344571bffcc87f8a9c3bb30916378ce1 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Wed, 1 Jul 2026 15:15:05 +0300 Subject: [PATCH 07/17] add cache stats --- .../inputs/prometheus_http/prometheus_http.go | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 09e51608defd9..78023b982b2e3 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -643,6 +643,7 @@ func (p *PrometheusHttp) gatherMetrics(gid uint64, ds PrometheusHttpDatasource) fields := p.addFields("requests", p.requests.counter.Value()) fields["errors"] = p.errors.counter.Value() + p.addCacheStats(fields) r1 := float64(p.requests.counter.Value()) r2 := float64(p.errors.counter.Value()) @@ -654,6 +655,22 @@ func (p *PrometheusHttp) gatherMetrics(gid uint64, ds PrometheusHttpDatasource) return nil } +func (p *PrometheusHttp) addCacheStats(fields map[string]interface{}) { + + if p.cache == nil { + return + } + + stats := p.cache.Stats() + fields["cache_hits"] = stats.Hits + fields["cache_misses"] = stats.Misses + fields["cache_delete_hits"] = stats.DelHits + fields["cache_delete_misses"] = stats.DelMisses + fields["cache_collisions"] = stats.Collisions + fields["cache_len"] = p.cache.Len() + fields["cache_capacity_bytes"] = p.cache.Capacity() +} + func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchFindKey(obj interface{}, field, value string) string { if obj == nil || utils.IsEmpty(field) || utils.IsEmpty(value) { @@ -662,7 +679,7 @@ func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchFindKey(obj interface{}, if ptt.input.cache == nil { return "" } - key := fmt.Sprintf("%s.%s.%s", ptt.tag, field, value) + key := fmt.Sprintf("%s.%s.%s.%s", ptt.input.Name, ptt.tag, field, value) entry, err := ptt.input.cache.Get(key) if err == nil { @@ -991,6 +1008,7 @@ func (p *PrometheusHttp) Gather(acc telegraf.Accumulator) error { var ds PrometheusHttpDatasource = nil gid := utils.GoRoutineID() p.readFiles(gid, &globalFiles, &globalHashes, p.Metrics, false) + // Gather data err := p.gatherMetrics(gid, ds) return err @@ -1049,12 +1067,11 @@ func (p *PrometheusHttp) Init() error { seconds := time.Duration(p.Timeout).Seconds() if p.CacheDuration <= 0 { - p.CacheDuration = config.Duration(time.Second * time.Duration(seconds) * 10) + p.CacheDuration = config.Duration(time.Second * time.Duration(seconds)) } config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) config.Shards = 256 - config.CleanWindow = time.Duration(p.CacheDuration * 3) /*if seconds > 0 { t := int(math.Round(seconds / 2)) if t > 1 { @@ -1076,8 +1093,9 @@ func (p *PrometheusHttp) Init() error { } config.HardMaxCacheSize = maxSizeInMb - config.Logger = p + // config.Logger = p config.Verbose = true + config.StatsEnabled = true cache, err := bigcache.NewBigCache(config) if err != nil { From 87a1810a8327456bb48e6ac40cad4467d629a2f0 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Wed, 1 Jul 2026 17:37:40 +0300 Subject: [PATCH 08/17] test findkeys changes --- go.mod | 10 +++--- go.sum | 20 ++++++------ .../inputs/prometheus_http/prometheus_http.go | 31 +++++++++++++------ 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index 0c14712a833f5..9617c67d67018 100644 --- a/go.mod +++ b/go.mod @@ -76,8 +76,8 @@ require ( github.com/coreos/go-systemd/v22 v22.5.0 github.com/couchbase/go-couchbase v0.1.1 github.com/datadope-io/go-zabbix/v2 v2.0.1 - github.com/devopsext/tools v0.15.3 - github.com/devopsext/utils v0.4.3 + github.com/devopsext/tools v0.18.7 + github.com/devopsext/utils v0.4.8 github.com/digitalocean/go-libvirt v0.0.0-20250417173424-a6a66ef779d6 github.com/dimchansky/utfbom v1.1.1 github.com/djherbis/times v1.6.0 @@ -244,9 +244,9 @@ require ( gopkg.in/olivere/elastic.v5 v5.0.86 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.33.1 - k8s.io/apimachinery v0.33.1 - k8s.io/client-go v0.33.1 + k8s.io/api v0.33.3 + k8s.io/apimachinery v0.33.3 + k8s.io/client-go v0.33.3 layeh.com/radius v0.0.0-20221205141417-e7fbddd11d68 modernc.org/sqlite v1.37.0 software.sslmate.com/src/go-pkcs12 v0.5.0 diff --git a/go.sum b/go.sum index 6da7b57b9e0fe..77e080e6ca25a 100644 --- a/go.sum +++ b/go.sum @@ -1137,10 +1137,10 @@ github.com/devigned/tab v0.1.1 h1:3mD6Kb1mUOYeLpJvTVSDwSg5ZsfSxfvxGRTxRsJsITA= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/devopsext/sdk v0.9.6 h1:UWU4ZeINWMmgLsuCvdC/FPN+HKu1tcW06K65ler4mT4= github.com/devopsext/sdk v0.9.6/go.mod h1:AHHlOEv1+GGQ3ktHMlhuTUwo3zljV3QJbC0+8o2kn+4= -github.com/devopsext/tools v0.15.3 h1:0zTepwKqDCgcCh85ATx6cE2ri98zfOFsyunFVDTavvg= -github.com/devopsext/tools v0.15.3/go.mod h1:FXft1ABAA2XYDnbg6ElDyQHPUXXp/GRPQRFQ1R1Cz8Y= -github.com/devopsext/utils v0.4.3 h1:PbAlmjtWjppKFBG479xKkiD5U8OUbXcDRivRMW7L4Pg= -github.com/devopsext/utils v0.4.3/go.mod h1:Vg3Jxxr4i9JXPmhaZo7TvY+OEr3W3QlZDXmbN8ScU5k= +github.com/devopsext/tools v0.18.7 h1:dCVTFaylYQ4kJZX2O0zdXtnXErf5hnkayAUTwDAoPL0= +github.com/devopsext/tools v0.18.7/go.mod h1:RNiXytM21qgylYzJWya8dhfCTA+xxvI4GGFBjx0ZxAA= +github.com/devopsext/utils v0.4.8 h1:Ql8fwF36lUcHj5nw/IlZrfHEcPNmh1YPJws3MOnuCKA= +github.com/devopsext/utils v0.4.8/go.mod h1:3Apwsy4/k+baHRxsHuK0ipqdgK/YNHif0fZmO7m0W4Q= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= @@ -3532,12 +3532,12 @@ honnef.co/go/tools v0.2.2 h1:MNh1AVMyVX23VUHE2O27jm6lNj3vjO5DexS4A1xvnzk= honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -k8s.io/api v0.33.1 h1:tA6Cf3bHnLIrUK4IqEgb2v++/GYUtqiu9sRVk3iBXyw= -k8s.io/api v0.33.1/go.mod h1:87esjTn9DRSRTD4fWMXamiXxJhpOIREjWOSjsW1kEHw= -k8s.io/apimachinery v0.33.1 h1:mzqXWV8tW9Rw4VeW9rEkqvnxj59k1ezDUl20tFK/oM4= -k8s.io/apimachinery v0.33.1/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/client-go v0.33.1 h1:ZZV/Ks2g92cyxWkRRnfUDsnhNn28eFpt26aGc8KbXF4= -k8s.io/client-go v0.33.1/go.mod h1:JAsUrl1ArO7uRVFWfcj6kOomSlCv+JpvIsp6usAGefA= +k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8= +k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE= +k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA= +k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA= +k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 78023b982b2e3..87f4da2fcd4a5 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -108,6 +108,11 @@ type PrometheusHttp struct { cache *bigcache.BigCache } +// Panic implements [common.Logger]. +func (p *PrometheusHttp) Panic(obj interface{}, args ...interface{}) { + panic("unimplemented") +} + type PrometheusHttpPushFunc = func(when time.Time, tags map[string]string, stamp time.Time, value float64) type PrometheusHttpDatasourceResponse struct { @@ -662,11 +667,11 @@ func (p *PrometheusHttp) addCacheStats(fields map[string]interface{}) { } stats := p.cache.Stats() - fields["cache_hits"] = stats.Hits - fields["cache_misses"] = stats.Misses - fields["cache_delete_hits"] = stats.DelHits - fields["cache_delete_misses"] = stats.DelMisses - fields["cache_collisions"] = stats.Collisions + fields["cache_hits_count"] = stats.Hits + fields["cache_misses_count"] = stats.Misses + fields["cache_delete_hits_count"] = stats.DelHits + fields["cache_delete_misses_count"] = stats.DelMisses + fields["cache_collisions_count"] = stats.Collisions fields["cache_len"] = p.cache.Len() fields["cache_capacity_bytes"] = p.cache.Capacity() } @@ -684,16 +689,24 @@ func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchFindKey(obj interface{}, entry, err := ptt.input.cache.Get(key) if err == nil { v1 := string(entry) - if !utils.IsEmpty(v1) { - return v1 + if v1 == "nil" { + return "" } + return v1 + } + var v2 any + keys := ptt.template.RegexMatchFindKeys(obj, field, value) + if len(keys) == 0 { + v2 = "" + } else { + v2 = keys[0] } - v2 := ptt.template.RegexMatchFindKey(obj, field, value) v1 := fmt.Sprintf("%v", v2) if !utils.IsEmpty(v1) { ptt.input.cache.Set(key, []byte(v1)) return v1 } + ptt.input.cache.Set(key, []byte("nil")) return "" } @@ -1067,7 +1080,7 @@ func (p *PrometheusHttp) Init() error { seconds := time.Duration(p.Timeout).Seconds() if p.CacheDuration <= 0 { - p.CacheDuration = config.Duration(time.Second * time.Duration(seconds)) + p.CacheDuration = config.Duration(time.Second * time.Duration(seconds) * 10) } config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) From f22e341261f9d32e6afc3486f51a5ba08ece95a2 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Thu, 2 Jul 2026 08:50:02 +0300 Subject: [PATCH 09/17] test --- plugins/inputs/prometheus_http/prometheus_http.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 87f4da2fcd4a5..0dc6bf3a94a91 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -1075,6 +1075,10 @@ func (p *PrometheusHttp) Init() error { if len(p.Files) > 0 { + if p.cache != nil { + p.cache.Reset() + } + entries, length := p.readFiles(gid, &globalFiles, &globalHashes, p.Metrics, true) seconds := time.Duration(p.Timeout).Seconds() @@ -1084,7 +1088,8 @@ func (p *PrometheusHttp) Init() error { } config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) - config.Shards = 256 + config.CleanWindow = 0 + config.Shards = 64 /*if seconds > 0 { t := int(math.Round(seconds / 2)) if t > 1 { @@ -1097,9 +1102,9 @@ func (p *PrometheusHttp) Init() error { maxSizeInMb := 0 if p.CacheSize > 0 { - maxSizeInMb = int(p.CacheSize) / (1024 * 1024) + maxSizeInMb = int(p.CacheSize) / (1024) } else { - maxSizeInMb = (entries * length * int(seconds)) / (1024 * 1024) + maxSizeInMb = (entries * length * int(seconds)) / (1024) } if maxSizeInMb == 0 { maxSizeInMb = 1 From f08fc8dd87533e6736518d05b91a333136aa9a70 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Thu, 2 Jul 2026 11:21:49 +0300 Subject: [PATCH 10/17] test --- .../inputs/prometheus_http/prometheus_http.go | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 0dc6bf3a94a91..a188ba8558f75 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -690,6 +690,10 @@ func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchFindKey(obj interface{}, if err == nil { v1 := string(entry) if v1 == "nil" { + md := ptt.input.cache.KeyMetadata(key) + if md.RequestCount > 100 { + ptt.input.cache.Delete(key) + } return "" } return v1 @@ -1062,53 +1066,49 @@ func (p *PrometheusHttp) Init() error { return err } - p.Log.Debugf("[%d] %s metrics amount: %d", gid, p.Name, lMetrics) + maxltags := 0 for _, m := range p.Metrics { p.setDefaultMetric(gid, m) + ltags := len(m.Tags) + if maxltags < ltags { + maxltags = ltags + } } + p.Log.Debugf("[%d] %s metrics amount: %d, max tags %d", gid, p.Name, lMetrics, maxltags) + //p.files = &sync.Map{} p.requests = NewRateCounter(time.Duration(p.Interval)) p.errors = NewRateCounter(time.Duration(p.Interval)) p.mtx = &sync.Mutex{} - if len(p.Files) > 0 { + if len(p.Files) > 0 && p.cache == nil { - if p.cache != nil { - p.cache.Reset() - } - - entries, length := p.readFiles(gid, &globalFiles, &globalHashes, p.Metrics, true) + _, length := p.readFiles(gid, &globalFiles, &globalHashes, p.Metrics, true) seconds := time.Duration(p.Timeout).Seconds() if p.CacheDuration <= 0 { - p.CacheDuration = config.Duration(time.Second * time.Duration(seconds) * 10) + p.CacheDuration = config.Duration(time.Second * time.Duration(seconds)) } config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) config.CleanWindow = 0 config.Shards = 64 - /*if seconds > 0 { - t := int(math.Round(seconds / 2)) - if t > 1 { - config.CleanWindow = time.Duration(time.Second * time.Duration(t)) - } - }*/ - config.MaxEntriesInWindow = entries + config.MaxEntriesInWindow = lMetrics * maxltags config.MaxEntrySize = length - maxSizeInMb := 0 - if p.CacheSize > 0 { - maxSizeInMb = int(p.CacheSize) / (1024) - } else { - maxSizeInMb = (entries * length * int(seconds)) / (1024) - } - if maxSizeInMb == 0 { - maxSizeInMb = 1 - } + maxSizeInMb := 1 + // if p.CacheSize > 0 { + // maxSizeInMb = int(p.CacheSize) / (1024) + // } else { + // maxSizeInMb = (entries * length * int(seconds)) / (1024) + // } + // if maxSizeInMb == 0 { + // maxSizeInMb = 1 + // } config.HardMaxCacheSize = maxSizeInMb // config.Logger = p From 468e5548a5bb1f9e25712d6e0dcdbe87a47e83f6 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Thu, 2 Jul 2026 12:55:56 +0300 Subject: [PATCH 11/17] test --- plugins/inputs/prometheus_http/prometheus_http.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index a188ba8558f75..c5f9c59e5037c 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -684,14 +684,14 @@ func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchFindKey(obj interface{}, if ptt.input.cache == nil { return "" } - key := fmt.Sprintf("%s.%s.%s.%s", ptt.input.Name, ptt.tag, field, value) + key := fmt.Sprintf("%s.%s.%s", ptt.tag, field, value) entry, err := ptt.input.cache.Get(key) if err == nil { v1 := string(entry) if v1 == "nil" { md := ptt.input.cache.KeyMetadata(key) - if md.RequestCount > 100 { + if md.RequestCount > 1000 { ptt.input.cache.Delete(key) } return "" @@ -1095,7 +1095,7 @@ func (p *PrometheusHttp) Init() error { config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) config.CleanWindow = 0 - config.Shards = 64 + config.Shards = 1024 config.MaxEntriesInWindow = lMetrics * maxltags config.MaxEntrySize = length From fbc17e29d4a4bebfcc80e264f1f00111096efe92 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Thu, 2 Jul 2026 13:51:54 +0300 Subject: [PATCH 12/17] test --- .../inputs/prometheus_http/prometheus_http.go | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index c5f9c59e5037c..04ffcd39cd0a1 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -105,7 +105,9 @@ type PrometheusHttp struct { mtx *sync.Mutex //files *sync.Map //fileHash map[string]string - cache *bigcache.BigCache + cache *bigcache.BigCache + ctx context.Context + cancel context.CancelFunc } // Panic implements [common.Logger]. @@ -193,6 +195,13 @@ func (p *PrometheusHttp) Warn(obj interface{}, args ...interface{}) { p.Log.Warnf(s, args) } +func (p *PrometheusHttp) ensureContext() { + if p.ctx != nil { + return + } + p.ctx, p.cancel = context.WithCancel(context.Background()) +} + func (p *PrometheusHttp) Debug(obj interface{}, args ...interface{}) { s, ok := obj.(string) if !ok { @@ -573,7 +582,7 @@ func (p *PrometheusHttp) setMetrics(w *sync.WaitGroup, pm *PrometheusHttpMetric, p.client = p.makeClient(int(timeout)) } - ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, context.Background(), p.URL, p.User, p.Password, int(timeout), step, params) + ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, p.ctx, p.URL, p.User, p.Password, int(timeout), step, params) p.mtx.Unlock() break } else { @@ -591,7 +600,7 @@ func (p *PrometheusHttp) setMetrics(w *sync.WaitGroup, pm *PrometheusHttpMetric, p.client = p.makeClient(int(timeout)) } defer p.mtx.Unlock() - ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, context.Background(), p.URL, p.User, p.Password, int(timeout), step, params) + ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, p.ctx, p.URL, p.User, p.Password, int(timeout), step, params) } } } @@ -1035,9 +1044,30 @@ func (p *PrometheusHttp) Printf(format string, v ...interface{}) { p.Log.Debugf(format, v) } +func (p *PrometheusHttp) Start(telegraf.Accumulator) error { + p.ensureContext() + return nil +} + +func (p *PrometheusHttp) Stop() { + if p.cancel != nil { + p.cancel() + p.cancel = nil + } + p.ctx = nil + + if p.cache != nil { + if err := p.cache.Close(); err != nil { + p.Log.Warnf("%s cache close error: %s", p.Name, err) + } + p.cache = nil + } +} + func (p *PrometheusHttp) Init() error { gid := utils.GoRoutineID() + p.ensureContext() if p.Interval <= 0 { p.Interval = config.Duration(time.Second) * 5 @@ -1095,7 +1125,7 @@ func (p *PrometheusHttp) Init() error { config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) config.CleanWindow = 0 - config.Shards = 1024 + config.Shards = 32 config.MaxEntriesInWindow = lMetrics * maxltags config.MaxEntrySize = length @@ -1115,7 +1145,7 @@ func (p *PrometheusHttp) Init() error { config.Verbose = true config.StatsEnabled = true - cache, err := bigcache.NewBigCache(config) + cache, err := bigcache.New(p.ctx, config) if err != nil { p.Log.Warnf("[%d] %s cache error: %s", gid, err) } From 70edcd7cca73ca8e95cc2394d7deb7081238aef3 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Thu, 2 Jul 2026 15:25:56 +0300 Subject: [PATCH 13/17] test --- .../inputs/prometheus_http/prometheus_http.go | 60 +++++-------------- 1 file changed, 15 insertions(+), 45 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 04ffcd39cd0a1..8077391417df7 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -105,9 +105,7 @@ type PrometheusHttp struct { mtx *sync.Mutex //files *sync.Map //fileHash map[string]string - cache *bigcache.BigCache - ctx context.Context - cancel context.CancelFunc + cache *bigcache.BigCache } // Panic implements [common.Logger]. @@ -195,13 +193,6 @@ func (p *PrometheusHttp) Warn(obj interface{}, args ...interface{}) { p.Log.Warnf(s, args) } -func (p *PrometheusHttp) ensureContext() { - if p.ctx != nil { - return - } - p.ctx, p.cancel = context.WithCancel(context.Background()) -} - func (p *PrometheusHttp) Debug(obj interface{}, args ...interface{}) { s, ok := obj.(string) if !ok { @@ -575,14 +566,14 @@ func (p *PrometheusHttp) setMetrics(w *sync.WaitGroup, pm *PrometheusHttpMetric, case "v1": switch p.ExecutionType { - case "concurrent": + default: for { if p.mtx.TryLock() { if p.client == nil { p.client = p.makeClient(int(timeout)) } - ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, p.ctx, p.URL, p.User, p.Password, int(timeout), step, params) + ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, context.Background(), p.URL, p.User, p.Password, int(timeout), step, params) p.mtx.Unlock() break } else { @@ -592,15 +583,15 @@ func (p *PrometheusHttp) setMetrics(w *sync.WaitGroup, pm *PrometheusHttpMetric, } } - default: - // This approach is blocking. In plain words, queries in bounds of SAME config file - // will be executed one after another. Other config files will be running in parallel - p.mtx.Lock() - if p.client == nil { - p.client = p.makeClient(int(timeout)) - } - defer p.mtx.Unlock() - ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, p.ctx, p.URL, p.User, p.Password, int(timeout), step, params) + // default: + // // This approach is blocking. In plain words, queries in bounds of SAME config file + // // will be executed one after another. Other config files will be running in parallel + // p.mtx.Lock() + // if p.client == nil { + // p.client = p.makeClient(int(timeout)) + // } + // defer p.mtx.Unlock() + // ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, context.Background(), p.URL, p.User, p.Password, int(timeout), step, params) } } } @@ -693,7 +684,7 @@ func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchFindKey(obj interface{}, if ptt.input.cache == nil { return "" } - key := fmt.Sprintf("%s.%s.%s", ptt.tag, field, value) + key := fmt.Sprintf("%s.%s.%s.%s", ptt.name, ptt.tag, field, value) entry, err := ptt.input.cache.Get(key) if err == nil { @@ -1044,30 +1035,9 @@ func (p *PrometheusHttp) Printf(format string, v ...interface{}) { p.Log.Debugf(format, v) } -func (p *PrometheusHttp) Start(telegraf.Accumulator) error { - p.ensureContext() - return nil -} - -func (p *PrometheusHttp) Stop() { - if p.cancel != nil { - p.cancel() - p.cancel = nil - } - p.ctx = nil - - if p.cache != nil { - if err := p.cache.Close(); err != nil { - p.Log.Warnf("%s cache close error: %s", p.Name, err) - } - p.cache = nil - } -} - func (p *PrometheusHttp) Init() error { gid := utils.GoRoutineID() - p.ensureContext() if p.Interval <= 0 { p.Interval = config.Duration(time.Second) * 5 @@ -1120,7 +1090,7 @@ func (p *PrometheusHttp) Init() error { seconds := time.Duration(p.Timeout).Seconds() if p.CacheDuration <= 0 { - p.CacheDuration = config.Duration(time.Second * time.Duration(seconds)) + p.CacheDuration = config.Duration(time.Second * time.Duration(seconds) * 60) } config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) @@ -1145,7 +1115,7 @@ func (p *PrometheusHttp) Init() error { config.Verbose = true config.StatsEnabled = true - cache, err := bigcache.New(p.ctx, config) + cache, err := bigcache.NewBigCache(config) if err != nil { p.Log.Warnf("[%d] %s cache error: %s", gid, err) } From 7e39eb642af928322aaf42ab848068b964772dcb Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Thu, 2 Jul 2026 17:20:45 +0300 Subject: [PATCH 14/17] return blocking behavior --- .../inputs/prometheus_http/prometheus_http.go | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 8077391417df7..11db00b9ba587 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -532,7 +532,6 @@ func (p *PrometheusHttp) setMetrics(w *sync.WaitGroup, pm *PrometheusHttpMetric, } pm.uniques[hash] = true } - v, err := p.getTemplateValue(pm.template, value) if err != nil { p.Log.Error(err) @@ -551,8 +550,11 @@ func (p *PrometheusHttp) setMetrics(w *sync.WaitGroup, pm *PrometheusHttpMetric, } tags[k] = t } - + t1 := time.Now() tags = p.getExtraMetricTags(gid, tags, pm) + t2 := time.Since(t1) + + p.Log.Debugf("DBG! tags %v time %s", tags, t2) if pm.Round != nil { ratio := math.Pow(10, float64(*pm.Round)) @@ -566,7 +568,7 @@ func (p *PrometheusHttp) setMetrics(w *sync.WaitGroup, pm *PrometheusHttpMetric, case "v1": switch p.ExecutionType { - default: + case "concurrent": for { if p.mtx.TryLock() { if p.client == nil { @@ -583,15 +585,15 @@ func (p *PrometheusHttp) setMetrics(w *sync.WaitGroup, pm *PrometheusHttpMetric, } } - // default: - // // This approach is blocking. In plain words, queries in bounds of SAME config file - // // will be executed one after another. Other config files will be running in parallel - // p.mtx.Lock() - // if p.client == nil { - // p.client = p.makeClient(int(timeout)) - // } - // defer p.mtx.Unlock() - // ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, context.Background(), p.URL, p.User, p.Password, int(timeout), step, params) + default: + // This approach is blocking. In plain words, queries in bounds of SAME config file + // will be executed one after another. Other config files will be running in parallel + p.mtx.Lock() + if p.client == nil { + p.client = p.makeClient(int(timeout)) + } + defer p.mtx.Unlock() + ds = NewPrometheusHttpV1(p.client, p.Name, p.Log, context.Background(), p.URL, p.User, p.Password, int(timeout), step, params) } } } @@ -1111,7 +1113,7 @@ func (p *PrometheusHttp) Init() error { // } config.HardMaxCacheSize = maxSizeInMb - // config.Logger = p + config.Logger = p config.Verbose = true config.StatsEnabled = true From 27b62b07e1e404a4e895806897292812a2b74f42 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Fri, 3 Jul 2026 10:07:20 +0300 Subject: [PATCH 15/17] remove debug --- plugins/inputs/prometheus_http/prometheus_http.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 11db00b9ba587..ed4c00c14e621 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -550,11 +550,8 @@ func (p *PrometheusHttp) setMetrics(w *sync.WaitGroup, pm *PrometheusHttpMetric, } tags[k] = t } - t1 := time.Now() - tags = p.getExtraMetricTags(gid, tags, pm) - t2 := time.Since(t1) - p.Log.Debugf("DBG! tags %v time %s", tags, t2) + tags = p.getExtraMetricTags(gid, tags, pm) if pm.Round != nil { ratio := math.Pow(10, float64(*pm.Round)) From 8e82c811f36ed1643d7e20c837c1b497e6493707 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Sat, 4 Jul 2026 12:20:21 +0300 Subject: [PATCH 16/17] test cacheget --- .../inputs/prometheus_http/prometheus_http.go | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index ed4c00c14e621..6554f1600af89 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -18,6 +18,7 @@ import ( "sync" "time" + "github.com/Masterminds/sprig/v3" "github.com/allegro/bigcache/v3" "github.com/araddon/dateparse" "gopkg.in/yaml.v3" @@ -130,6 +131,7 @@ var description = "Collect data from Prometheus http api" var globalFiles = sync.Map{} var globalHashes = sync.Map{} +var sprigGet = sprig.TxtFuncMap()["get"].(func(map[string]interface{}, string) interface{}) const pluginName = "prometheus_http" @@ -689,10 +691,10 @@ func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchFindKey(obj interface{}, if err == nil { v1 := string(entry) if v1 == "nil" { - md := ptt.input.cache.KeyMetadata(key) - if md.RequestCount > 1000 { - ptt.input.cache.Delete(key) - } + // md := ptt.input.cache.KeyMetadata(key) + // if md.RequestCount > 1000 { + // ptt.input.cache.Delete(key) + // } return "" } return v1 @@ -739,6 +741,45 @@ func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchObjectByField(obj interfa return nil } +func (ptt *PrometheusHttpTextTemplate) fCacheGet(obj interface{}, value string) interface{} { + + if obj == nil || utils.IsEmpty(value) { + return "" + } + m, ok := obj.(map[string]interface{}) + if !ok { + return "" + } + if ptt.input.cache == nil { + return sprigGet(m, value) + } + key := fmt.Sprintf("%s.%s.%s.%s", "fget", ptt.name, ptt.tag, value) + + entry, err := ptt.input.cache.Get(key) + if err == nil { + var v1 any + if string(entry) == "nil" { + // md := ptt.input.cache.KeyMetadata(key) + // if md.RequestCount > 1000 { + // ptt.input.cache.Delete(key) + // } + return "" + } + json.Unmarshal(entry, &v1) + return v1 + } + + v := sprigGet(m, value) + if !utils.IsEmpty(v) { + v1, _ := json.Marshal(v) + ptt.input.cache.Set(key, []byte(v1)) + return v + } + ptt.input.cache.Set(key, []byte("nil")) + return v + +} + func (p *PrometheusHttp) getDefaultTemplate(m *PrometheusHttpMetric, name, tag, value string) *toolsRender.TextTemplate { if value == "" { @@ -750,6 +791,7 @@ func (p *PrometheusHttp) getDefaultTemplate(m *PrometheusHttpMetric, name, tag, //funcs["renderMetricTag"] = p.fRenderMetricTag funcs["regexMatchFindKey"] = ptt.fCacheRegexMatchFindKey funcs["regexMatchObjectByField"] = ptt.fCacheRegexMatchObjectByField + funcs["get"] = ptt.fCacheGet tpl, err := toolsRender.NewTextTemplate(toolsRender.TemplateOptions{ Name: fmt.Sprintf("%s_template", fmt.Sprintf("%s_%s", name, tag)), @@ -1093,7 +1135,7 @@ func (p *PrometheusHttp) Init() error { } config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) - config.CleanWindow = 0 + config.CleanWindow = time.Duration(p.Timeout) config.Shards = 32 config.MaxEntriesInWindow = lMetrics * maxltags From 7ce312364c23a4bbbdba38c6a026a67047d3f609 Mon Sep 17 00:00:00 2001 From: Ilia Savelov Date: Sat, 4 Jul 2026 15:20:49 +0300 Subject: [PATCH 17/17] rollback --- .../inputs/prometheus_http/prometheus_http.go | 52 ++----------------- 1 file changed, 5 insertions(+), 47 deletions(-) diff --git a/plugins/inputs/prometheus_http/prometheus_http.go b/plugins/inputs/prometheus_http/prometheus_http.go index 6554f1600af89..ed4c00c14e621 100644 --- a/plugins/inputs/prometheus_http/prometheus_http.go +++ b/plugins/inputs/prometheus_http/prometheus_http.go @@ -18,7 +18,6 @@ import ( "sync" "time" - "github.com/Masterminds/sprig/v3" "github.com/allegro/bigcache/v3" "github.com/araddon/dateparse" "gopkg.in/yaml.v3" @@ -131,7 +130,6 @@ var description = "Collect data from Prometheus http api" var globalFiles = sync.Map{} var globalHashes = sync.Map{} -var sprigGet = sprig.TxtFuncMap()["get"].(func(map[string]interface{}, string) interface{}) const pluginName = "prometheus_http" @@ -691,10 +689,10 @@ func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchFindKey(obj interface{}, if err == nil { v1 := string(entry) if v1 == "nil" { - // md := ptt.input.cache.KeyMetadata(key) - // if md.RequestCount > 1000 { - // ptt.input.cache.Delete(key) - // } + md := ptt.input.cache.KeyMetadata(key) + if md.RequestCount > 1000 { + ptt.input.cache.Delete(key) + } return "" } return v1 @@ -741,45 +739,6 @@ func (ptt *PrometheusHttpTextTemplate) fCacheRegexMatchObjectByField(obj interfa return nil } -func (ptt *PrometheusHttpTextTemplate) fCacheGet(obj interface{}, value string) interface{} { - - if obj == nil || utils.IsEmpty(value) { - return "" - } - m, ok := obj.(map[string]interface{}) - if !ok { - return "" - } - if ptt.input.cache == nil { - return sprigGet(m, value) - } - key := fmt.Sprintf("%s.%s.%s.%s", "fget", ptt.name, ptt.tag, value) - - entry, err := ptt.input.cache.Get(key) - if err == nil { - var v1 any - if string(entry) == "nil" { - // md := ptt.input.cache.KeyMetadata(key) - // if md.RequestCount > 1000 { - // ptt.input.cache.Delete(key) - // } - return "" - } - json.Unmarshal(entry, &v1) - return v1 - } - - v := sprigGet(m, value) - if !utils.IsEmpty(v) { - v1, _ := json.Marshal(v) - ptt.input.cache.Set(key, []byte(v1)) - return v - } - ptt.input.cache.Set(key, []byte("nil")) - return v - -} - func (p *PrometheusHttp) getDefaultTemplate(m *PrometheusHttpMetric, name, tag, value string) *toolsRender.TextTemplate { if value == "" { @@ -791,7 +750,6 @@ func (p *PrometheusHttp) getDefaultTemplate(m *PrometheusHttpMetric, name, tag, //funcs["renderMetricTag"] = p.fRenderMetricTag funcs["regexMatchFindKey"] = ptt.fCacheRegexMatchFindKey funcs["regexMatchObjectByField"] = ptt.fCacheRegexMatchObjectByField - funcs["get"] = ptt.fCacheGet tpl, err := toolsRender.NewTextTemplate(toolsRender.TemplateOptions{ Name: fmt.Sprintf("%s_template", fmt.Sprintf("%s_%s", name, tag)), @@ -1135,7 +1093,7 @@ func (p *PrometheusHttp) Init() error { } config := bigcache.DefaultConfig(time.Duration(p.CacheDuration)) - config.CleanWindow = time.Duration(p.Timeout) + config.CleanWindow = 0 config.Shards = 32 config.MaxEntriesInWindow = lMetrics * maxltags