Skip to content

Commit b734609

Browse files
mergify[bot]faec
andauthored
[9.1](backport #46018) Remove all remaining NewRegistry method calls (#46222)
* Remove all remaining NewRegistry method calls (#46018) The `NewRegistry` method in `elastic-agent-libs` is inherently unsafe, especially in concurrent code: calling `NewRegistry` on a name that already exists causes a panic, but checking whether the name exists first is not atomic. The recently added `GetOrCreateRegistry` method is a safe alternative that checks the name's existence and initializes it atomically, and never panics. This PR replaces all remaining `NewRegistry` calls with `GetOrCreateRegistry`. (cherry picked from commit bf7a774) # Conflicts: # libbeat/monitoring/inputmon/input_test.go * fix merge --------- Co-authored-by: Fae Charlton <[email protected]>
1 parent 2528f35 commit b734609

File tree

22 files changed

+59
-49
lines changed

22 files changed

+59
-49
lines changed

auditbeat/module/auditd/audit_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const (
6565
)
6666

6767
var (
68-
auditdMetrics = monitoring.Default.NewRegistry(moduleName)
68+
auditdMetrics = monitoring.Default.GetOrCreateRegistry(moduleName)
6969
reassemblerGapsMetric = monitoring.NewInt(auditdMetrics, "reassembler_seq_gaps")
7070
kernelLostMetric = monitoring.NewInt(auditdMetrics, "kernel_lost")
7171
userspaceLostMetric = monitoring.NewInt(auditdMetrics, "userspace_lost")

filebeat/input/log/harvester.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import (
6060
)
6161

6262
var (
63-
harvesterMetrics = monitoring.Default.NewRegistry("filebeat.harvester")
63+
harvesterMetrics = monitoring.Default.GetOrCreateRegistry("filebeat.harvester")
6464
filesMetrics = monitoring.GetNamespace("dataset").GetRegistry()
6565

6666
harvesterStarted = monitoring.NewInt(harvesterMetrics, "started")
@@ -178,7 +178,7 @@ func (h *Harvester) open() error {
178178
case harvester.LogType, harvester.DockerType, harvester.ContainerType:
179179
return h.openFile()
180180
default:
181-
return fmt.Errorf("Invalid harvester type: %+v", h.config)
181+
return fmt.Errorf("invalid harvester type: %+v", h.config)
182182
}
183183
}
184184

@@ -217,7 +217,7 @@ func (h *Harvester) Setup() error {
217217
}
218218

219219
func newHarvesterProgressMetrics(id string) *harvesterProgressMetrics {
220-
r := filesMetrics.NewRegistry(id)
220+
r := filesMetrics.GetOrCreateRegistry(id)
221221
return &harvesterProgressMetrics{
222222
metricsRegistry: r,
223223
filename: monitoring.NewString(r, "name"),
@@ -444,7 +444,7 @@ func (h *Harvester) onMessage(
444444
// Check if json fields exist
445445
var jsonFields mapstr.M
446446
if f, ok := fields["json"]; ok {
447-
jsonFields = f.(mapstr.M)
447+
jsonFields, _ = f.(mapstr.M)
448448
}
449449

450450
var meta mapstr.M

heartbeat/hbregistry/hbregistry.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ package hbregistry
2020
import "github.com/elastic/elastic-agent-libs/monitoring"
2121

2222
// StatsRegistry contains a singleton instance of the heartbeat stats registry
23-
var StatsRegistry = monitoring.Default.NewRegistry("heartbeat")
23+
var StatsRegistry = monitoring.Default.GetOrCreateRegistry("heartbeat")
2424

2525
// SchedulerRegistry holds scheduler stats
26-
var SchedulerRegistry = StatsRegistry.NewRegistry("scheduler")
26+
var SchedulerRegistry = StatsRegistry.GetOrCreateRegistry("scheduler")
2727

2828
// TelemetryRegistry contains a singleton instance of the heartbeat telemetry registry
29-
var TelemetryRegistry = monitoring.GetNamespace("state").GetRegistry().NewRegistry("heartbeat")
29+
var TelemetryRegistry = monitoring.GetNamespace("state").GetRegistry().GetOrCreateRegistry("heartbeat")

heartbeat/monitors/plugin/regrecord.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ type CountersRecorder struct {
5353
}
5454

5555
func NewPluginCountersRecorder(pluginName string, rootRegistry *monitoring.Registry) RegistryRecorder {
56-
pluginRegistry := rootRegistry.NewRegistry(pluginName)
56+
pluginRegistry := rootRegistry.GetOrCreateRegistry(pluginName)
5757
return CountersRecorder{
5858
monitoring.NewInt(pluginRegistry, "monitor_starts"),
5959
monitoring.NewInt(pluginRegistry, "monitor_stops"),
@@ -87,7 +87,7 @@ func newRootGaugeRecorder(r *monitoring.Registry) RegistryRecorder {
8787
}
8888

8989
func newPluginGaugeRecorder(pluginName string, rootRegistry *monitoring.Registry) RegistryRecorder {
90-
pluginRegistry := rootRegistry.NewRegistry(pluginName)
90+
pluginRegistry := rootRegistry.GetOrCreateRegistry(pluginName)
9191
return newRootGaugeRecorder(pluginRegistry)
9292
}
9393

libbeat/cmd/instance/beat.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ func (b *Beat) createBeater(bt beat.Creator) (beat.Beater, error) {
358358
}
359359

360360
// Report central management state
361-
mgmt := b.Monitoring.StateRegistry().NewRegistry("management")
361+
mgmt := b.Monitoring.StateRegistry().GetOrCreateRegistry("management")
362362
monitoring.NewBool(mgmt, "enabled").Set(b.Manager.Enabled())
363363

364364
log.Debug("Initializing output plugins")
@@ -1287,7 +1287,7 @@ func (b *Beat) registerClusterUUIDFetching() {
12871287

12881288
// Build and return a callback to fetch the Elasticsearch cluster_uuid for monitoring
12891289
func (b *Beat) clusterUUIDFetchingCallback() elasticsearch.ConnectCallback {
1290-
elasticsearchRegistry := b.Monitoring.StateRegistry().NewRegistry("outputs.elasticsearch")
1290+
elasticsearchRegistry := b.Monitoring.StateRegistry().GetOrCreateRegistry("outputs.elasticsearch")
12911291
clusterUUIDRegVar := monitoring.NewString(elasticsearchRegistry, "cluster_uuid")
12921292

12931293
callback := func(esClient *eslegclient.Connection) error {
@@ -1324,7 +1324,7 @@ func (b *Beat) setupMonitoring(settings Settings) (report.Reporter, error) {
13241324

13251325
// Expose monitoring.cluster_uuid in state API
13261326
if monitoringClusterUUID != "" {
1327-
monitoringRegistry := b.Monitoring.StateRegistry().NewRegistry("monitoring")
1327+
monitoringRegistry := b.Monitoring.StateRegistry().GetOrCreateRegistry("monitoring")
13281328
clusterUUIDRegVar := monitoring.NewString(monitoringRegistry, "cluster_uuid")
13291329
clusterUUIDRegVar.Set(monitoringClusterUUID)
13301330
}

libbeat/monitoring/inputmon/httphandler_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestHandler(t *testing.T) {
5959

6060
// Register legacy metrics without id or input. This must be ignored.
6161
{
62-
legacy := parent.NewRegistry("f49c0680-fc5f-4b78-bd98-7b16628f9a77")
62+
legacy := parent.GetOrCreateRegistry("f49c0680-fc5f-4b78-bd98-7b16628f9a77")
6363
monitoring.NewString(legacy, "name").Set("/var/log/wifi.log")
6464
monitoring.NewTimestamp(legacy, "last_event_published_time").Set(time.Now())
6565
}

libbeat/monitoring/inputmon/input.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func NewInputRegistry(inputType, inputID string, optionalParent *monitoring.Regi
7070
// that isn't at the top-level.
7171
reg = findInputRegistryWithID(parentRegistry, inputID)
7272
if reg == nil {
73-
reg = parentRegistry.NewRegistry(registryID)
73+
reg = parentRegistry.GetOrCreateRegistry(registryID)
7474
} else {
7575
log.Warnw(fmt.Sprintf(
7676
"parent metrics registry already contains a %q registry, reusing it",
@@ -143,7 +143,15 @@ func NewMetricsRegistry(
143143
registryID := sanitizeID(inputID)
144144
reg := parent.GetRegistry(registryID)
145145
if reg == nil {
146-
reg = parent.NewRegistry(registryID)
146+
// Technically this is a race: the previous GetRegistry is not atomic with
147+
// this GetOrCreateRegistry, so if someone else is adding the same id at this
148+
// exact moment we might take this branch inappropriately. However, the
149+
// consequences in that case are metrics for two inputs with the same id
150+
// being inappropriately reported under the same registry, whereas the
151+
// consequences if we called NewRegistry here are a panic.
152+
// (We should also never have two inputs with the same id in the first
153+
// place, but it's worth being cautious.)
154+
reg = parent.GetOrCreateRegistry(registryID)
147155
} else {
148156
// Null route metrics for duplicated ID.
149157
reg = monitoring.NewRegistry()

libbeat/monitoring/inputmon/input_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func TestMetricSnapshotJSON(t *testing.T) {
105105
monitoring.NewInt(reg, "events_pipeline_total").Set(10)
106106

107107
// simulate a duplicated ID in the local and global namespace.
108-
reg = globalRegistry().NewRegistry(inputID)
108+
reg = globalRegistry().GetOrCreateRegistry(inputID)
109109
monitoring.NewString(reg, "id").Set(inputID)
110110
monitoring.NewString(reg, "input").Set(inputType)
111111
monitoring.NewBool(reg, "should_be_overwritten").Set(true)
@@ -139,12 +139,12 @@ func TestMetricSnapshotJSON(t *testing.T) {
139139

140140
// ==== registries in the global registries which aren't input metrics ===
141141
// unrelated registry in the global namespace, should be ignored.
142-
reg = globalRegistry().NewRegistry("another-registry")
142+
reg = globalRegistry().GetOrCreateRegistry("another-registry")
143143
monitoring.NewInt(reg, "foo3_total").Set(100)
144144
defer globalRegistry().Remove("another-registry")
145145

146146
// another input registry missing required information.
147-
reg = globalRegistry().NewRegistry("yet-another-registry")
147+
reg = globalRegistry().GetOrCreateRegistry("yet-another-registry")
148148
monitoring.NewString(reg, "id").Set("some-id")
149149
monitoring.NewInt(reg, "foo3_total").Set(100)
150150
defer globalRegistry().Remove("yet-another-registry")
@@ -339,7 +339,7 @@ func TestCancelMetricsRegistry(t *testing.T) {
339339
inputID := "input-ID"
340340
inputType := "input-type"
341341

342-
_ = parent.NewRegistry(inputID)
342+
_ = parent.GetOrCreateRegistry(inputID)
343343
got := parent.GetRegistry(inputID)
344344
require.NotNil(t, got, "metrics registry not found on parent")
345345

libbeat/processors/add_host_metadata/add_host_metadata.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func init() {
5050
processors.RegisterPlugin(processorName, New)
5151
jsprocessor.RegisterPlugin("AddHostMetadata", New)
5252

53-
reg = monitoring.Default.NewRegistry(logName, monitoring.DoNotReport)
53+
reg = monitoring.Default.GetOrCreateRegistry(logName, monitoring.DoNotReport)
5454
}
5555

5656
type metrics struct {

libbeat/processors/dns/dns.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func New(cfg *conf.C, log *logp.Logger) (beat.Processor, error) {
5959
// Logging and metrics (each processor instance has a unique ID).
6060
var (
6161
id = int(instanceID.Add(1))
62-
metrics = monitoring.Default.NewRegistry(logName+"."+strconv.Itoa(id), monitoring.DoNotReport)
62+
metrics = monitoring.Default.GetOrCreateRegistry(logName+"."+strconv.Itoa(id), monitoring.DoNotReport)
6363
)
6464

6565
log = log.Named(logName).With("instance_id", id)
@@ -69,7 +69,7 @@ func New(cfg *conf.C, log *logp.Logger) (beat.Processor, error) {
6969
return nil, err
7070
}
7171

72-
cache, err := newLookupCache(metrics.NewRegistry("cache"), c.cacheConfig, resolver)
72+
cache, err := newLookupCache(metrics.GetOrCreateRegistry("cache"), c.cacheConfig, resolver)
7373
if err != nil {
7474
return nil, err
7575
}

0 commit comments

Comments
 (0)