Skip to content

Commit

Permalink
[pkg/otlp/metrics] Add WithSplatArrayAttributes
Browse files Browse the repository at this point in the history
  • Loading branch information
mx-psi committed May 17, 2024
1 parent 90e0f33 commit 2daa9eb
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 13 deletions.
17 changes: 17 additions & 0 deletions .chloggen/mx-psi_splat-tags.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component (e.g. pkg/quantile)
component: pkg/otlp/metrics

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add `WithSplatArrayAttributes` translator option

# The PR related to this change
issues: [329]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
- This option destructures an array valued attribute into multiple tags with the same key and different values.
17 changes: 17 additions & 0 deletions .chloggen/mx-psi_splat-tags2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: breaking

# The name of the component (e.g. pkg/quantile)
component: pkg/otlp/metrics

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add `splat` option to `WithAttributeMap`

# The PR related to this change
issues: [329]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
- This option destructures an array valued attribute into multiple tags with the same key and different values.
9 changes: 9 additions & 0 deletions pkg/otlp/metrics/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type translatorConfig struct {
InitialCumulMonoValueMode InitialCumulMonoValueMode
InstrumentationLibraryMetadataAsTags bool
InstrumentationScopeMetadataAsTags bool
SplatArrayAttributes bool

originProduct OriginProduct

Expand Down Expand Up @@ -215,3 +216,11 @@ func WithInitialCumulMonoValueMode(mode InitialCumulMonoValueMode) TranslatorOpt
return nil
}
}

// WithSplatArrayAttributes destructures an array attribute into multiple Datadog tags.
func WithSplatArrayAttributes() TranslatorOption {
return func(t *translatorConfig) error {
t.SplatArrayAttributes = true
return nil
}
}
17 changes: 12 additions & 5 deletions pkg/otlp/metrics/dimensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,18 @@ func (d *Dimensions) OriginProductDetail() OriginProductDetail {
}

// getTags maps an attributeMap into a slice of Datadog tags
func getTags(labels pcommon.Map) []string {
func getTags(labels pcommon.Map, splat bool) []string {
tags := make([]string, 0, labels.Len())
labels.Range(func(key string, value pcommon.Value) bool {
v := value.AsString()
tags = append(tags, utils.FormatKeyValueTag(key, v))
if splat && value.Type() == pcommon.ValueTypeSlice {
for i := 0; i < value.Slice().Len(); i++ {
v := value.Slice().At(i).AsString()
tags = append(tags, utils.FormatKeyValueTag(key, v))
}
} else {
v := value.AsString()
tags = append(tags, utils.FormatKeyValueTag(key, v))
}
return true
})
return tags
Expand All @@ -106,8 +113,8 @@ func (d *Dimensions) AddTags(tags ...string) *Dimensions {
}

// WithAttributeMap creates a new metricDimensions struct with additional tags from attributes.
func (d *Dimensions) WithAttributeMap(labels pcommon.Map) *Dimensions {
return d.AddTags(getTags(labels)...)
func (d *Dimensions) WithAttributeMap(labels pcommon.Map, splat bool) *Dimensions {
return d.AddTags(getTags(labels, splat)...)
}

// WithSuffix creates a new dimensions struct with an extra name suffix.
Expand Down
23 changes: 20 additions & 3 deletions pkg/otlp/metrics/dimensions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,29 @@ func TestWithAttributeMap(t *testing.T) {
"key1": "val1",
"key2": "val2",
"key3": "",
"key4": []any{"val4a", "val4b"},
})

dims := Dimensions{}
assert.ElementsMatch(t,
dims.WithAttributeMap(attributes).tags,
[...]string{"key1:val1", "key2:val2", "key3:n/a"},
dims.WithAttributeMap(attributes, false).tags,
[...]string{"key1:val1", "key2:val2", "key3:n/a", `key4:["val4a","val4b"]`},
)
}

func TestWithAttributeMapSplat(t *testing.T) {
attributes := pcommon.NewMap()
attributes.FromRaw(map[string]interface{}{
"key1": "val1",
"key2": "val2",
"key3": "",
"key4": []any{"val4a", "val4b"},
})

dims := Dimensions{}
assert.ElementsMatch(t,
dims.WithAttributeMap(attributes, true).tags,
[...]string{"key1:val1", "key2:val2", "key3:n/a", "key4:val4a", "key4:val4b"},
)
}

Expand Down Expand Up @@ -115,7 +132,7 @@ func TestAllFieldsAreCopied(t *testing.T) {
newDims := dims.
AddTags("tagThree:c").
WithSuffix("suffix").
WithAttributeMap(attributes)
WithAttributeMap(attributes, false)

assert.Equal(t, "example.name.suffix", newDims.Name())
assert.Equal(t, "hostname", newDims.Host())
Expand Down
2 changes: 1 addition & 1 deletion pkg/otlp/metrics/exponential_histograms_translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (t *Translator) mapExponentialHistogramMetrics(
p := slice.At(i)
startTs := uint64(p.StartTimestamp())
ts := uint64(p.Timestamp())
pointDims := dims.WithAttributeMap(p.Attributes())
pointDims := dims.WithAttributeMap(p.Attributes(), t.cfg.SplatArrayAttributes)

histInfo := histogramInfo{ok: true}

Expand Down
8 changes: 4 additions & 4 deletions pkg/otlp/metrics/metrics_translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func (t *Translator) mapNumberMetrics(

for i := 0; i < slice.Len(); i++ {
p := slice.At(i)
pointDims := dims.WithAttributeMap(p.Attributes())
pointDims := dims.WithAttributeMap(p.Attributes(), t.cfg.SplatArrayAttributes)
var val float64
switch p.ValueType() {
case pmetric.NumberDataPointValueTypeDouble:
Expand Down Expand Up @@ -205,7 +205,7 @@ func (t *Translator) mapNumberMonotonicMetrics(
p := slice.At(i)
ts := uint64(p.Timestamp())
startTs := uint64(p.StartTimestamp())
pointDims := dims.WithAttributeMap(p.Attributes())
pointDims := dims.WithAttributeMap(p.Attributes(), t.cfg.SplatArrayAttributes)

var val float64
switch p.ValueType() {
Expand Down Expand Up @@ -452,7 +452,7 @@ func (t *Translator) mapHistogramMetrics(
p := slice.At(i)
startTs := uint64(p.StartTimestamp())
ts := uint64(p.Timestamp())
pointDims := dims.WithAttributeMap(p.Attributes())
pointDims := dims.WithAttributeMap(p.Attributes(), t.cfg.SplatArrayAttributes)

histInfo := histogramInfo{ok: true}

Expand Down Expand Up @@ -556,7 +556,7 @@ func (t *Translator) mapSummaryMetrics(
p := slice.At(i)
startTs := uint64(p.StartTimestamp())
ts := uint64(p.Timestamp())
pointDims := dims.WithAttributeMap(p.Attributes())
pointDims := dims.WithAttributeMap(p.Attributes(), t.cfg.SplatArrayAttributes)

// count and sum are increasing; we treat them as cumulative monotonic sums.
{
Expand Down

0 comments on commit 2daa9eb

Please sign in to comment.