Skip to content

Commit

Permalink
Handle non-string attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
lkwronski committed Apr 24, 2024
1 parent 78d1718 commit a9a6cd4
Show file tree
Hide file tree
Showing 13 changed files with 538 additions and 5 deletions.
27 changes: 27 additions & 0 deletions .chloggen/lkwronski.issue-30314-count-connector.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: connector/count

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Fix handling of non-string attributes in the count connector

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [30314]

# (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:

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
2 changes: 1 addition & 1 deletion connector/countconnector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ connectors:
If attributes are specified for custom metrics, a separate count will be generated for each unique
set of attribute values. Each count will be emitted as a data point on the same metric.

Optionally, include a `default_value` for an attribute, to count data that does not contain the attribute.
Optionally, include a `default_value` for an attribute, to count data that does not contain the attribute. The `default_value` value can be of type string, integer, or float.

```yaml
receivers:
Expand Down
2 changes: 1 addition & 1 deletion connector/countconnector/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type MetricInfo struct {

type AttributeConfig struct {
Key string `mapstructure:"key"`
DefaultValue string `mapstructure:"default_value"`
DefaultValue any `mapstructure:"default_value"`
}

func (c *Config) Validate() error {
Expand Down
47 changes: 47 additions & 0 deletions connector/countconnector/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,53 @@ func TestLoadConfig(t *testing.T) {
},
},
},
{
name: "default_values",
expect: &Config{
Spans: map[string]MetricInfo{
defaultMetricNameSpans: {
Description: defaultMetricDescSpans,
},
},
SpanEvents: map[string]MetricInfo{
defaultMetricNameSpanEvents: {
Description: defaultMetricDescSpanEvents,
},
},
Metrics: map[string]MetricInfo{
defaultMetricNameMetrics: {
Description: defaultMetricDescMetrics,
},
},
DataPoints: map[string]MetricInfo{
defaultMetricNameDataPoints: {
Description: defaultMetricDescDataPoints,
},
},
Logs: map[string]MetricInfo{
"my.logrecord.count": {
Description: "My log record count with default values.",
},
"limited.logrecord.count": {
Description: "Limited log record count.",
Attributes: []AttributeConfig{
{
Key: "env",
DefaultValue: "local",
},
{
Key: "http_code",
DefaultValue: int(200),
},
{
Key: "request_success",
DefaultValue: float64(0.85),
},
},
},
},
},
},
}

for _, tc := range testCases {
Expand Down
34 changes: 34 additions & 0 deletions connector/countconnector/connector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,40 @@ func TestMetricsToMetrics(t *testing.T) {
},
},
},
{
name: "int_attribute_value",
cfg: &Config{
DataPoints: map[string]MetricInfo{
"datapoint.count.by_attr": {
Description: "Data point count by int attribute",
Attributes: []AttributeConfig{
{
Key: "datapoint.int",
},
},
},
},
},
},
{
name: "default_int_attribute_value",
cfg: &Config{
DataPoints: map[string]MetricInfo{
"datapoint.count.by_attr": {
Description: "Data point count by default int attribute",
Attributes: []AttributeConfig{
{
Key: "datapoint.int",
},
{
Key: "datapoint.optional_int",
DefaultValue: 10,
},
},
},
},
},
},
}

for _, tc := range testCases {
Expand Down
26 changes: 23 additions & 3 deletions connector/countconnector/counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,29 @@ func (c *counter[K]) update(ctx context.Context, attrs pcommon.Map, tCtx K) erro
countAttrs := pcommon.NewMap()
for _, attr := range md.attrs {
if attrVal, ok := attrs.Get(attr.Key); ok {
countAttrs.PutStr(attr.Key, attrVal.Str())
} else if attr.DefaultValue != "" {
countAttrs.PutStr(attr.Key, attr.DefaultValue)
switch typeAttr := attrVal.Type(); typeAttr {
case pcommon.ValueTypeInt:
countAttrs.PutInt(attr.Key, attrVal.Int())
case pcommon.ValueTypeDouble:
countAttrs.PutDouble(attr.Key, attrVal.Double())
default:
countAttrs.PutStr(attr.Key, attrVal.Str())
}
} else if attr.DefaultValue != nil {
switch v := attr.DefaultValue.(type) {
case string:
if v != "" {
countAttrs.PutStr(attr.Key, v)
}
case int:
if v != 0 {
countAttrs.PutInt(attr.Key, int64(v))
}
case float64:
if v != 0 {
countAttrs.PutDouble(attr.Key, float64(v))
}
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions connector/countconnector/testdata/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,16 @@
- key: env
- key: component
default_value: other
count/default_values:
logs:
my.logrecord.count:
description: My log record count with default values.
limited.logrecord.count:
description: Limited log record count.
attributes:
- key: env
default_value: "local"
- key: http_code
default_value: 200
- key: request_success
default_value: 0.85
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
resourceMetrics:
- resource:
attributes:
- key: resource.int
value:
intValue: 1
- key: resource.optional_int
value:
intValue: 2
scopeMetrics:
- metrics:
- description: Data point count by default int attribute
name: datapoint.count.by_attr
sum:
aggregationTemporality: 1
dataPoints:
- asInt: "1"
attributes:
- key: datapoint.int
value:
intValue: 10
- key: datapoint.optional_int
value:
intValue: 4
- asInt: "5"
attributes:
- key: datapoint.int
value:
intValue: 1
- key: datapoint.optional_int
value:
intValue: 4
- asInt: "6"
attributes:
- key: datapoint.int
value:
intValue: 1
- key: datapoint.optional_int
value:
intValue: 2
- asInt: "6"
attributes:
- key: datapoint.int
value:
intValue: 10
- key: datapoint.optional_int
value:
intValue: 10
timeUnixNano: "1678391923821179000"
isMonotonic: true
scope:
name: otelcol/countconnector
Loading

0 comments on commit a9a6cd4

Please sign in to comment.