Skip to content

Commit 0cba399

Browse files
authored
[chore] Validate metadata.yaml units against UCUM specification (#15530)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description Validate metrics units using `github.com/iimos/ucum`. Depends on open-telemetry/opentelemetry-collector-contrib/pull/49453 <!--Authorship attestation. See AGENTS.md for details. AI agents must not check this box on behalf of the user; the human author must check it themselves before the PR is ready for review.--> #### Authorship - [x] I, a human, wrote this pull request description myself. <!--Please delete paragraphs that you did not use before submitting.-->
1 parent fe96e04 commit 0cba399

6 files changed

Lines changed: 55 additions & 2 deletions

File tree

cmd/mdatagen/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.25.0
44

55
require (
66
github.com/google/go-cmp v0.7.0
7+
github.com/iimos/ucum v0.0.3
78
github.com/spf13/cobra v1.10.2
89
github.com/stretchr/testify v1.11.1
910
go.opentelemetry.io/collector/component v1.62.0

cmd/mdatagen/go.sum

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/mdatagen/internal/metric.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"regexp"
1010
"strings"
1111

12+
"github.com/iimos/ucum"
1213
"golang.org/x/text/cases"
1314
"golang.org/x/text/language"
1415

@@ -96,6 +97,10 @@ func (m *Metric) validate(metricName MetricName, semConvVersion string) error {
9697
}
9798
if m.Unit == nil {
9899
errs = errors.Join(errs, errors.New(`missing metric unit`))
100+
} else if *m.Unit != "" {
101+
if _, err := ucum.Parse([]byte(*m.Unit)); err != nil {
102+
errs = errors.Join(errs, fmt.Errorf("invalid metric unit %q: %w", *m.Unit, err))
103+
}
99104
}
100105
if m.Sum != nil {
101106
errs = errors.Join(errs, m.Sum.Validate())

cmd/mdatagen/internal/metric_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,54 @@ import (
99
"github.com/stretchr/testify/assert"
1010
"github.com/stretchr/testify/require"
1111

12+
"go.opentelemetry.io/collector/component"
1213
"go.opentelemetry.io/collector/pdata/pmetric"
1314
)
1415

16+
func TestMetricValidateUnit(t *testing.T) {
17+
strPtr := func(s string) *string { return &s }
18+
newMetric := func(unit *string) *Metric {
19+
return &Metric{
20+
Signal: Signal{
21+
Description: "a metric",
22+
Stability: component.StabilityLevelBeta,
23+
},
24+
Unit: unit,
25+
Sum: &Sum{
26+
MetricValueType: MetricValueType{pmetric.NumberDataPointValueTypeInt},
27+
Mono: Mono{Monotonic: true},
28+
},
29+
}
30+
}
31+
tests := []struct {
32+
name string
33+
unit *string
34+
wantErr string
35+
}{
36+
{name: "valid seconds", unit: strPtr("s")},
37+
{name: "valid dimensionless", unit: strPtr("1")},
38+
{name: "valid bytes", unit: strPtr("By")},
39+
{name: "valid percent", unit: strPtr("%")},
40+
{name: "valid annotation", unit: strPtr("{packets}")},
41+
{name: "valid compound", unit: strPtr("By/s")},
42+
{name: "empty unit allowed", unit: strPtr("")},
43+
{name: "missing unit", unit: nil, wantErr: "missing metric unit"},
44+
{name: "non-ucum micro sign", unit: strPtr("µs"), wantErr: `invalid metric unit "µs"`},
45+
{name: "unknown unit", unit: strPtr("bytes"), wantErr: `invalid metric unit "bytes"`},
46+
}
47+
for _, tt := range tests {
48+
t.Run(tt.name, func(t *testing.T) {
49+
err := newMetric(tt.unit).validate("metric.name", "")
50+
if tt.wantErr != "" {
51+
require.Error(t, err)
52+
assert.ErrorContains(t, err, tt.wantErr)
53+
} else {
54+
require.NoError(t, err)
55+
}
56+
})
57+
}
58+
}
59+
1560
func TestValidateSemConvMetricURL(t *testing.T) {
1661
validURL := "https://github.com/open-telemetry/semantic-conventions/blob/v1.37.2/docs/system/system-metrics.md#metric-systemcputime"
1762
tests := []struct {

cmd/mdatagen/internal/testdata/invalid_telemetry_missing_value_type_for_histogram.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ telemetry:
88
metrics:
99
sampling_decision_latency:
1010
description: Latency (in microseconds) of a given sampling policy
11-
unit: µs
11+
unit: us
1212
enabled: true
1313
histogram:

cmd/mdatagen/internal/testdata/with_telemetry.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ telemetry:
1212
metrics:
1313
sampling_decision_latency:
1414
description: Latency (in microseconds) of a given sampling policy
15-
unit: µs
15+
unit: us
1616
enabled: true
1717
stability: alpha
1818
histogram:

0 commit comments

Comments
 (0)