Skip to content

Commit f6e045a

Browse files
[8.19](backport #44244) fix panic when running 2 filestream inputs with same ID (#44267)
* inputmon: NewMetricsRegistry returns new registry for existing ID (#44244) inputmon.NewMetricsRegistry now returns a new, unregistered metrics registry if one already exists for the given input ID. This change prevents a panic that previously occurred if an attempt was made to register a duplicate metric or registry on the registry instance associated with that ID. (cherry picked from commit 02cc67d) * fix import: use logp instead of logptest --------- Co-authored-by: Anderson Queiroz <[email protected]>
1 parent 5c52662 commit f6e045a

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

libbeat/monitoring/inputmon/input.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ func MetricSnapshotJSON(reg *monitoring.Registry) ([]byte, error) {
116116
// any '.' is replaced by '_'. The new registry is initialized with
117117
// 'id: inputID' and 'input: inputType'.
118118
//
119+
// If there is already a registry with the same name on parent, a new registry
120+
// not associated with parent will be returned.
121+
//
119122
// Call CancelMetricsRegistry to remove it from the parent registry and free up
120123
// the associated resources.
121124
func NewMetricsRegistry(
@@ -129,8 +132,10 @@ func NewMetricsRegistry(
129132
if reg == nil {
130133
reg = parent.NewRegistry(registryID)
131134
} else {
135+
// Null route metrics for duplicated ID.
136+
reg = monitoring.NewRegistry()
132137
log.Warnw(fmt.Sprintf(
133-
"parent metrics registry already contains a %q registry, reusing it",
138+
"parent metrics registry already contains a %q registry, returning an unregistered registry. Metrics won't be available for this input instance",
134139
registryID),
135140
"registry_id", registryID,
136141
"input_type", inputType,

libbeat/monitoring/inputmon/input_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727

2828
"github.com/elastic/elastic-agent-libs/logp"
2929
"github.com/elastic/elastic-agent-libs/monitoring"
30+
"github.com/elastic/elastic-agent-libs/monitoring/adapter"
3031
)
3132

3233
func TestNewInputMonitor(t *testing.T) {
@@ -220,6 +221,42 @@ func TestNewMetricsRegistry(t *testing.T) {
220221
assert.Equal(t, inputType, vals.Strings["input"])
221222
}
222223

224+
func TestNewMetricsRegistry_duplicatedInputID(t *testing.T) {
225+
parent := monitoring.NewRegistry()
226+
inputID := "input-inputID"
227+
inputType := "input-type"
228+
metricName := "foo_total"
229+
goMetricsRegistryName := "bar_registry"
230+
231+
// 1st call, create the registry
232+
got := NewMetricsRegistry(
233+
inputID,
234+
inputType,
235+
parent,
236+
logp.NewTestingLogger(t, "test"))
237+
238+
require.NotNil(t, got, "new metrics registry should not be nil")
239+
assert.Equal(t, parent.GetRegistry(inputID), got)
240+
// register a metric to the registry
241+
monitoring.NewInt(got, metricName)
242+
adapter.NewGoMetrics(got, goMetricsRegistryName, adapter.Accept)
243+
244+
// 2nd call, return an unregistered registry
245+
got = NewMetricsRegistry(
246+
inputID,
247+
inputType,
248+
parent,
249+
logp.NewTestingLogger(t, "test"))
250+
require.NotNil(t, got, "new metrics registry should not be nil")
251+
assert.NotEqual(t, parent.GetRegistry(inputID), got,
252+
"should get an unregistered registry, but found the registry on parent")
253+
assert.NotPanics(t, func() {
254+
// register the same metric again
255+
monitoring.NewInt(got, metricName)
256+
adapter.NewGoMetrics(got, goMetricsRegistryName, adapter.Accept)
257+
}, "the registry should be a new and empty registry")
258+
}
259+
223260
func TestCancelMetricsRegistry(t *testing.T) {
224261
parent := monitoring.NewRegistry()
225262
inputID := "input-ID"

0 commit comments

Comments
 (0)