Skip to content

Commit e2173c6

Browse files
committed
add validation for metrics url
Signed-off-by: ChrsMark <[email protected]>
1 parent 61b57cd commit e2173c6

File tree

6 files changed

+52
-10
lines changed

6 files changed

+52
-10
lines changed

cmd/mdatagen/internal/metadata.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ func (md *Metadata) validateMetricsAndEvents() error {
122122
var errs error
123123
usedAttrs := map[AttributeName]bool{}
124124
errs = errors.Join(errs,
125-
validateMetrics(md.Metrics, md.Attributes, usedAttrs),
126-
validateMetrics(md.Telemetry.Metrics, md.Attributes, usedAttrs),
125+
validateMetrics(md.Metrics, md.Attributes, usedAttrs, md.SemConvVersion),
126+
validateMetrics(md.Telemetry.Metrics, md.Attributes, usedAttrs, md.SemConvVersion),
127127
validateEvents(md.Events, md.Attributes, usedAttrs),
128128
md.validateAttributes(usedAttrs))
129129
return errs
@@ -166,10 +166,10 @@ func (md *Metadata) supportsSignal(signal string) bool {
166166
return false
167167
}
168168

169-
func validateMetrics(metrics map[MetricName]Metric, attributes map[AttributeName]Attribute, usedAttrs map[AttributeName]bool) error {
169+
func validateMetrics(metrics map[MetricName]Metric, attributes map[AttributeName]Attribute, usedAttrs map[AttributeName]bool, semConvVersion string) error {
170170
var errs error
171171
for mn, m := range metrics {
172-
if err := m.validate(); err != nil {
172+
if err := m.validate(mn, semConvVersion); err != nil {
173173
errs = errors.Join(errs, fmt.Errorf(`metric "%v": %w`, mn, err))
174174
continue
175175
}

cmd/mdatagen/internal/metric.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package internal // import "go.opentelemetry.io/collector/cmd/mdatagen/internal"
66
import (
77
"errors"
88
"fmt"
9+
"regexp"
910
"strings"
1011

1112
"golang.org/x/text/cases"
@@ -16,6 +17,8 @@ import (
1617
"go.opentelemetry.io/collector/pdata/pmetric"
1718
)
1819

20+
var reNonAlnum = regexp.MustCompile(`[^a-z0-9]+`)
21+
1922
type MetricName string
2023

2124
func (mn MetricName) Render() (string, error) {
@@ -62,7 +65,7 @@ func (s Stability) String() string {
6265
return fmt.Sprintf(" [%s]", s.Level)
6366
}
6467

65-
func (m *Metric) validate() error {
68+
func (m *Metric) validate(metricName MetricName, semConvVersion string) error {
6669
var errs error
6770
if m.Sum == nil && m.Gauge == nil && m.Histogram == nil {
6871
errs = errors.Join(errs, errors.New("missing metric type key, "+
@@ -84,9 +87,48 @@ func (m *Metric) validate() error {
8487
if m.Gauge != nil {
8588
errs = errors.Join(errs, m.Gauge.Validate())
8689
}
90+
if m.SemanticConvention != nil {
91+
if err := validateSemConvMetricURL(m.SemanticConvention.SemanticConventionRef, semConvVersion, string(metricName)); err != nil {
92+
errs = errors.Join(errs, err)
93+
}
94+
}
8795
return errs
8896
}
8997

98+
func metricAnchor(metricName string) string {
99+
m := strings.ToLower(strings.TrimSpace(metricName))
100+
m = reNonAlnum.ReplaceAllString(m, "")
101+
return "metric-" + m
102+
}
103+
104+
// validateSemConvMetricURL verifies the URL matches exactly:
105+
// https://github.com/open-telemetry/semantic-conventions/blob/<semConvVersion>/*#metric-<metricName>
106+
func validateSemConvMetricURL(rawURL, semConvVersion, metricName string) error {
107+
if strings.TrimSpace(rawURL) == "" {
108+
return fmt.Errorf("url is empty")
109+
}
110+
if strings.TrimSpace(semConvVersion) == "" {
111+
return fmt.Errorf("semConvVersion is empty")
112+
}
113+
if strings.TrimSpace(metricName) == "" {
114+
return fmt.Errorf("metricName is empty")
115+
}
116+
semConvVersion = "v" + semConvVersion
117+
118+
anchor := metricAnchor(metricName)
119+
// Build a strict regex that enforces https, repo, blob, given version, any doc path, and exact anchor.
120+
pattern := fmt.Sprintf(`^https://github\.com/open-telemetry/semantic-conventions/blob/%s/[^#\s]+#%s$`,
121+
regexp.QuoteMeta(semConvVersion),
122+
regexp.QuoteMeta(anchor),
123+
)
124+
re := regexp.MustCompile(pattern)
125+
if !re.MatchString(rawURL) {
126+
return fmt.Errorf("invalid semantic-conventions URL: want https://github.com/open-telemetry/semantic-conventions/blob/%s/*#%s, got %q",
127+
semConvVersion, anchor, rawURL)
128+
}
129+
return nil
130+
}
131+
90132
func (m *Metric) Unmarshal(parser *confmap.Conf) error {
91133
if !parser.IsSet("enabled") {
92134
return errors.New("missing required field: `enabled`")

cmd/mdatagen/internal/samplescraper/documentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ The metric will be become optional soon.
6868
6969
| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | Semantic Convention |
7070
| ---- | ----------- | ---------- | ----------------------- | --------- | --------- | ------------------- |
71-
| s | Sum | Int | Cumulative | true | beta | [system.cpu.time](https://github.com/open-telemetry/semantic-conventions/blob/v1.35.0/docs/system/system-metrics.md#metric-systemcputime) |
71+
| s | Sum | Int | Cumulative | true | beta | [system.cpu.time](https://github.com/open-telemetry/semantic-conventions/blob/v1.37.0/docs/system/system-metrics.md#metric-systemcputime) |
7272
7373
## Optional Metrics
7474

cmd/mdatagen/internal/samplescraper/internal/metadata/generated_logs.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/mdatagen/internal/samplescraper/internal/metadata/generated_metrics.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/mdatagen/internal/samplescraper/metadata.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
type: sample
44
github_project: open-telemetry/opentelemetry-collector
55

6-
sem_conv_version: 1.9.0
6+
sem_conv_version: 1.37.0
77

88
status:
99
disable_codecov_badge: true
@@ -112,7 +112,7 @@ metrics:
112112
monotonic: true
113113
aggregation_temporality: cumulative
114114
semantic_convention:
115-
semconv_ref: https://github.com/open-telemetry/semantic-conventions/blob/v1.35.0/docs/system/system-metrics.md#metric-systemcputime
115+
semconv_ref: https://github.com/open-telemetry/semantic-conventions/blob/v1.37.0/docs/system/system-metrics.md#metric-systemcputime
116116
default.metric:
117117
enabled: true
118118
description: Monotonic cumulative sum int metric enabled by default.

0 commit comments

Comments
 (0)