Skip to content

Commit

Permalink
Fix concurrent map write panic in monitoring middleware (#14335)
Browse files Browse the repository at this point in the history
Fix panic due to monitoring middleware concurrent map write.
  • Loading branch information
carsonip authored Oct 14, 2024
1 parent 9292d4b commit 5cd8b7d
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
1 change: 1 addition & 0 deletions changelogs/head.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 11 additions & 10 deletions internal/beater/middleware/monitoring_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package middleware
import (
"context"
"net/http"
"sync"
"time"

"go.opentelemetry.io/otel"
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}

Expand All @@ -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()
Expand Down

0 comments on commit 5cd8b7d

Please sign in to comment.