From d018e6ebbd2b9082253dccd3ca6f57ae7d8fb1a1 Mon Sep 17 00:00:00 2001 From: Paschalis Tsilias Date: Thu, 23 May 2024 11:55:31 +0200 Subject: [PATCH] otelcol: decouple otel/alloy component IDs (#882) Signed-off-by: Paschalis Tsilias --- CHANGELOG.md | 3 ++ internal/component/otelcol/auth/auth.go | 20 ++++++++++++- internal/component/otelcol/auth/auth_test.go | 30 +++++++++++++++++++ .../otelcol/receiver/prometheus/prometheus.go | 6 ---- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4d91b324a..6aae180841 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,9 @@ Main (unreleased) - Fix error on boot when using IPv6 advertise addresses without explicitly specifying a port. (@matthewpi) + +- Fix an issue where having long component labels (>63 chars) on otelcol.auth + components lead to a panic. (@tpaschalis) ### Other changes diff --git a/internal/component/otelcol/auth/auth.go b/internal/component/otelcol/auth/auth.go index 0281db889c..a404962806 100644 --- a/internal/component/otelcol/auth/auth.go +++ b/internal/component/otelcol/auth/auth.go @@ -7,6 +7,8 @@ package auth import ( "context" + "fmt" + "hash/fnv" "os" "strings" @@ -168,7 +170,7 @@ func (a *Auth) Update(args component.Arguments) error { components = append(components, ext) } - cTypeStr := strings.ReplaceAll(strings.ReplaceAll(a.opts.ID, ".", "_"), "/", "_") + cTypeStr := NormalizeType(a.opts.ID) // Inform listeners that our handler changed. a.opts.OnStateChange(Exports{ @@ -187,3 +189,19 @@ func (a *Auth) Update(args component.Arguments) error { func (a *Auth) CurrentHealth() component.Health { return a.sched.CurrentHealth() } + +func getHash(in string) string { + fnvHash := fnv.New32() + fnvHash.Write([]byte(in)) + return fmt.Sprintf("%x", fnvHash.Sum(nil)) +} + +func NormalizeType(in string) string { + res := strings.ReplaceAll(strings.ReplaceAll(in, ".", "_"), "/", "_") + + if len(res) > 63 { + res = res[:40] + getHash(res) + } + + return res +} diff --git a/internal/component/otelcol/auth/auth_test.go b/internal/component/otelcol/auth/auth_test.go index 464e659f45..8659c31013 100644 --- a/internal/component/otelcol/auth/auth_test.go +++ b/internal/component/otelcol/auth/auth_test.go @@ -2,6 +2,7 @@ package auth_test import ( "context" + "regexp" "testing" "time" @@ -93,3 +94,32 @@ func (fa fakeAuthArgs) Extensions() map[otelcomponent.ID]otelextension.Extension func (fa fakeAuthArgs) Exporters() map[otelcomponent.DataType]map[otelcomponent.ID]otelcomponent.Component { return nil } + +func TestNormalizeType(t *testing.T) { + type tc struct { + input string + expected string + } + testcases := []tc{ + {"foo", "foo"}, + {"foo1", "foo1"}, + {"fooBar", "fooBar"}, + + {"foo.bar", "foo_bar"}, + {"foo/bar", "foo_bar"}, + {"foo.bar/baz", "foo_bar_baz"}, + {"foo/bar_baz", "foo_bar_baz"}, + + {"thisStringsConstructedSoThatItsLengthIsSetToBeAtSixtyThreeChars", "thisStringsConstructedSoThatItsLengthIsSetToBeAtSixtyThreeChars"}, + {"whileThisOneHeresConstructedSoThatItsSizeIsEqualToSixtyFourChars", "whileThisOneHeresConstructedSoThatItsSiz2d7fa5d2"}, + } + + // https://github.com/open-telemetry/opentelemetry-collector/blob/e09b25f7d1b4090a9b7b73ef7d3c514592331554/component/config.go#L127-L131 + var typeRegexp = regexp.MustCompile(`^[a-zA-Z][0-9a-zA-Z_]{0,62}$`) + + for _, tt := range testcases { + actual := auth.NormalizeType(tt.input) + require.Equal(t, tt.expected, actual) + require.True(t, typeRegexp.MatchString(actual)) + } +} diff --git a/internal/component/otelcol/receiver/prometheus/prometheus.go b/internal/component/otelcol/receiver/prometheus/prometheus.go index c429405d9e..89775aaa78 100644 --- a/internal/component/otelcol/receiver/prometheus/prometheus.go +++ b/internal/component/otelcol/receiver/prometheus/prometheus.go @@ -5,7 +5,6 @@ import ( "context" "os" "regexp" - "strings" "sync" "time" @@ -117,12 +116,7 @@ func (c *Component) Update(newConfig component.Arguments) error { gcInterval = 5 * time.Minute ) - cTypeStr := strings.ReplaceAll(strings.ReplaceAll(c.opts.ID, ".", "_"), "/", "_") - settings := otelreceiver.CreateSettings{ - - ID: otelcomponent.NewID(otelcomponent.MustNewType(cTypeStr)), - TelemetrySettings: otelcomponent.TelemetrySettings{ Logger: zapadapter.New(c.opts.Logger),