From ddf91dabcb601e9920d8a41d7977c9063441f6e5 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:58:58 +0000 Subject: [PATCH] Fix concurrent map write panic in monitoring middleware (#14335) (#14350) Fix panic due to monitoring middleware concurrent map write. (cherry picked from commit 5cd8b7d3edf2deb38a8fd21ae71a91e198c08f59) Co-authored-by: Carson Ip Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- changelogs/head.asciidoc | 1 + .../middleware/monitoring_middleware.go | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/changelogs/head.asciidoc b/changelogs/head.asciidoc index ab1a5e60bcd..d1ce40a63ee 100644 --- a/changelogs/head.asciidoc +++ b/changelogs/head.asciidoc @@ -7,6 +7,7 @@ https://github.com/elastic/apm-server/compare/8.15\...main[View commits] ==== Bug fixes - Track all bulk request response status codes {pull}13574[13574] +- Fix a concurrent map write panic in monitoring middleware {pull}14335[14335] [float] ==== Breaking Changes diff --git a/internal/beater/middleware/monitoring_middleware.go b/internal/beater/middleware/monitoring_middleware.go index 67c0125c285..e34b4b52ebc 100644 --- a/internal/beater/middleware/monitoring_middleware.go +++ b/internal/beater/middleware/monitoring_middleware.go @@ -20,6 +20,7 @@ package middleware import ( "context" "net/http" + "sync" "time" "go.opentelemetry.io/otel" @@ -37,8 +38,8 @@ type monitoringMiddleware struct { meter metric.Meter ints map[request.ResultID]*monitoring.Int - counters map[string]metric.Int64Counter - histograms map[string]metric.Int64Histogram + counters sync.Map + histograms sync.Map } func (m *monitoringMiddleware) Middleware() Middleware { @@ -79,23 +80,23 @@ func (m *monitoringMiddleware) inc(id request.ResultID) { func (m *monitoringMiddleware) getCounter(n string) metric.Int64Counter { name := "http.server." + n - if met, ok := m.counters[name]; ok { - return met + if met, ok := m.counters.Load(name); ok { + return met.(metric.Int64Counter) } nm, _ := m.meter.Int64Counter(name) - m.counters[name] = nm + m.counters.LoadOrStore(name, nm) return nm } func (m *monitoringMiddleware) getHistogram(n string, opts ...metric.Int64HistogramOption) metric.Int64Histogram { name := "http.server." + n - if met, ok := m.histograms[name]; ok { - return met + if met, ok := m.histograms.Load(name); ok { + return met.(metric.Int64Histogram) } nm, _ := m.meter.Int64Histogram(name, opts...) - m.histograms[name] = nm + m.histograms.LoadOrStore(name, nm) return nm } @@ -109,8 +110,8 @@ func MonitoringMiddleware(m map[request.ResultID]*monitoring.Int, mp metric.Mete mid := &monitoringMiddleware{ meter: mp.Meter("internal/beater/middleware"), ints: m, - counters: map[string]metric.Int64Counter{}, - histograms: map[string]metric.Int64Histogram{}, + counters: sync.Map{}, + histograms: sync.Map{}, } return mid.Middleware()