From 292c6bf02b36c4a1cee5aeed5601c9d773ad07d7 Mon Sep 17 00:00:00 2001 From: HNO3Miracle Date: Wed, 19 Aug 2026 05:57:55 +0800 Subject: [PATCH] influx2otel: Avoid runtime dependency on pdatautil Collector contrib imports influx2otel from its InfluxDB receiver, while influx2otel imports pdatautil from Collector contrib. This forms a package-level dependency cycle when the repositories are packaged as complete source trees. Use a deterministic, length-delimited attribute key for the two internal lookup maps instead. Keep pdatautil as an indirect test dependency through pdatatest. Signed-off-by: HNO3Miracle --- influx2otel/attribute_map_key_test.go | 26 +++++++++++++++ influx2otel/go.mod | 2 +- influx2otel/metrics.go | 33 ++++++++++++++----- influx2otel/metrics_telegraf_prometheus_v2.go | 3 +- 4 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 influx2otel/attribute_map_key_test.go diff --git a/influx2otel/attribute_map_key_test.go b/influx2otel/attribute_map_key_test.go new file mode 100644 index 00000000..b45c783c --- /dev/null +++ b/influx2otel/attribute_map_key_test.go @@ -0,0 +1,26 @@ +package influx2otel + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/pdata/pcommon" +) + +func TestAttributeMapKey(t *testing.T) { + first := pcommon.NewMap() + first.PutStr("service.name", "api") + first.PutStr("region", "west") + + second := pcommon.NewMap() + second.PutStr("region", "west") + second.PutStr("service.name", "api") + + require.Equal(t, attributeMapKey(first), attributeMapKey(second)) + + boundaryA := pcommon.NewMap() + boundaryA.PutStr("a", "bc") + boundaryB := pcommon.NewMap() + boundaryB.PutStr("ab", "c") + require.NotEqual(t, attributeMapKey(boundaryA), attributeMapKey(boundaryB)) +} diff --git a/influx2otel/go.mod b/influx2otel/go.mod index 00e1e42a..a5e29f8b 100644 --- a/influx2otel/go.mod +++ b/influx2otel/go.mod @@ -5,7 +5,6 @@ go 1.25.0 require ( github.com/influxdata/influxdb-observability/common v0.5.8 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.101.0 - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.101.0 github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/pdata v1.8.0 go.opentelemetry.io/collector/semconv v0.101.0 @@ -18,6 +17,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.101.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/net v0.55.0 // indirect diff --git a/influx2otel/metrics.go b/influx2otel/metrics.go index 7c37cf97..6a51fcdb 100644 --- a/influx2otel/metrics.go +++ b/influx2otel/metrics.go @@ -5,9 +5,9 @@ import ( "fmt" "math" "sort" + "strings" "time" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" semconv "go.opentelemetry.io/collector/semconv/v1.16.0" @@ -27,9 +27,9 @@ func NewLineProtocolToOtelMetrics(logger common.Logger) (*LineProtocolToOtelMetr func (c *LineProtocolToOtelMetrics) NewBatch() *MetricsBatch { return &MetricsBatch{ - rmByAttributes: make(map[[16]byte]pmetric.ResourceMetrics), - ilmByRMAttributesAndIL: make(map[[16]byte]map[string]pmetric.ScopeMetrics), - metricByRMIL: make(map[[16]byte]map[string]map[string]pmetric.Metric), + rmByAttributes: make(map[string]pmetric.ResourceMetrics), + ilmByRMAttributesAndIL: make(map[string]map[string]pmetric.ScopeMetrics), + metricByRMIL: make(map[string]map[string]map[string]pmetric.Metric), histogramDataPointsByMDPK: make(map[pmetric.Metric]map[dataPointKey]pmetric.HistogramDataPoint), summaryDataPointsByMDPK: make(map[pmetric.Metric]map[dataPointKey]pmetric.SummaryDataPoint), @@ -38,9 +38,9 @@ func (c *LineProtocolToOtelMetrics) NewBatch() *MetricsBatch { } type MetricsBatch struct { - rmByAttributes map[[16]byte]pmetric.ResourceMetrics - ilmByRMAttributesAndIL map[[16]byte]map[string]pmetric.ScopeMetrics - metricByRMIL map[[16]byte]map[string]map[string]pmetric.Metric + rmByAttributes map[string]pmetric.ResourceMetrics + ilmByRMAttributesAndIL map[string]map[string]pmetric.ScopeMetrics + metricByRMIL map[string]map[string]map[string]pmetric.Metric histogramDataPointsByMDPK map[pmetric.Metric]map[dataPointKey]pmetric.HistogramDataPoint summaryDataPointsByMDPK map[pmetric.Metric]map[dataPointKey]pmetric.SummaryDataPoint @@ -74,6 +74,23 @@ func (b *MetricsBatch) AddPoint(measurement string, tags map[string]string, fiel var errValueTypeUnknown = errors.New("value type unknown") +func attributeMapKey(attributes pcommon.Map) string { + keys := make([]string, 0, attributes.Len()) + attributes.Range(func(key string, _ pcommon.Value) bool { + keys = append(keys, key) + return true + }) + sort.Strings(keys) + + var key strings.Builder + for _, name := range keys { + value, _ := attributes.Get(name) + valueText := value.AsString() + fmt.Fprintf(&key, "%d:%s:%d:%d:%s", len(name), name, value.Type(), len(valueText), valueText) + } + return key.String() +} + func (b *MetricsBatch) lookupMetric(metricName string, tags map[string]string, vType common.InfluxMetricValueType) (pmetric.Metric, pcommon.Map, error) { var ilName, ilVersion string rAttributes := pcommon.NewMap() @@ -98,7 +115,7 @@ func (b *MetricsBatch) lookupMetric(metricName string, tags map[string]string, v } } - rKey := pdatautil.MapHash(rAttributes) + rKey := attributeMapKey(rAttributes) var resourceMetrics pmetric.ResourceMetrics if rm, found := b.rmByAttributes[rKey]; found { resourceMetrics = rm diff --git a/influx2otel/metrics_telegraf_prometheus_v2.go b/influx2otel/metrics_telegraf_prometheus_v2.go index ce32c9a9..c9a1e343 100644 --- a/influx2otel/metrics_telegraf_prometheus_v2.go +++ b/influx2otel/metrics_telegraf_prometheus_v2.go @@ -7,7 +7,6 @@ import ( "strings" "time" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/influxdata/influxdb-observability/common" @@ -64,7 +63,7 @@ func (b *MetricsBatch) inferMetricValueTypeV2(vType common.InfluxMetricValueType type dataPointKey string func newDataPointKey(ts time.Time, attributes pcommon.Map) dataPointKey { - return dataPointKey(fmt.Sprintf("%d:%s", ts.UnixNano(), pdatautil.MapHash(attributes))) + return dataPointKey(fmt.Sprintf("%d:%s", ts.UnixNano(), attributeMapKey(attributes))) } func (b *MetricsBatch) convertGaugeV2(tags map[string]string, fields map[string]interface{}, ts time.Time) error {