Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .chloggen/mdatagen_add_semconv_ref.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

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

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: mdatagen

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Introduce semantic convention reference for signal in metadata schema

# One or more tracking issues or pull requests related to the change
issues: [13297]

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

# 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]
17 changes: 16 additions & 1 deletion cmd/mdatagen/internal/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestLoadMetadata(t *testing.T) {
GithubProject: "open-telemetry/opentelemetry-collector",
GeneratedPackageName: "metadata",
Type: "sample",
SemConvVersion: "1.9.0",
SemConvVersion: "1.37.0",
PackageName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/samplereceiver",
Status: &Status{
DisableCodeCov: true,
Expand Down Expand Up @@ -237,6 +237,21 @@ func TestLoadMetadata(t *testing.T) {
Mono: Mono{Monotonic: true},
},
},
"system.cpu.time": {
Signal: Signal{
Enabled: true,
Stability: Stability{Level: "beta"},
SemanticConvention: &SemanticConvention{SemanticConventionRef: "https://github.com/open-telemetry/semantic-conventions/blob/v1.37.0/docs/system/system-metrics.md#metric-systemcputime"},
Description: "Monotonic cumulative sum int metric enabled by default.",
ExtendedDocumentation: "The metric will be become optional soon.",
},
Unit: strPtr("s"),
Sum: &Sum{
MetricValueType: MetricValueType{pmetric.NumberDataPointValueTypeInt},
AggregationTemporality: AggregationTemporality{Aggregation: pmetric.AggregationTemporalityCumulative},
Mono: Mono{Monotonic: true},
},
},
"optional.metric": {
Signal: Signal{
Enabled: false,
Expand Down
15 changes: 11 additions & 4 deletions cmd/mdatagen/internal/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ func (md *Metadata) validateMetricsAndEvents() error {
var errs error
usedAttrs := map[AttributeName]bool{}
errs = errors.Join(errs,
validateMetrics(md.Metrics, md.Attributes, usedAttrs),
validateMetrics(md.Telemetry.Metrics, md.Attributes, usedAttrs),
validateMetrics(md.Metrics, md.Attributes, usedAttrs, md.SemConvVersion),
validateMetrics(md.Telemetry.Metrics, md.Attributes, usedAttrs, md.SemConvVersion),
validateEvents(md.Events, md.Attributes, usedAttrs),
md.validateAttributes(usedAttrs))
return errs
Expand Down Expand Up @@ -172,10 +172,10 @@ func (md *Metadata) supportsSignal(signal string) bool {
return false
}

func validateMetrics(metrics map[MetricName]Metric, attributes map[AttributeName]Attribute, usedAttrs map[AttributeName]bool) error {
func validateMetrics(metrics map[MetricName]Metric, attributes map[AttributeName]Attribute, usedAttrs map[AttributeName]bool, semConvVersion string) error {
var errs error
for mn, m := range metrics {
if err := m.validate(); err != nil {
if err := m.validate(mn, semConvVersion); err != nil {
errs = errors.Join(errs, fmt.Errorf(`metric "%v": %w`, mn, err))
continue
}
Expand Down Expand Up @@ -284,6 +284,10 @@ func (mvt ValueType) Primitive() string {
}
}

type SemanticConvention struct {
SemanticConventionRef string `mapstructure:"semconv_ref"`
}

type Warnings struct {
// A warning that will be displayed if the field is enabled in user config.
IfEnabled string `mapstructure:"if_enabled"`
Expand Down Expand Up @@ -371,6 +375,9 @@ type Signal struct {
// Description of the signal.
Description string `mapstructure:"description"`

// The semantic convention reference of the signal.
SemanticConvention *SemanticConvention `mapstructure:"semantic_convention"`

// The stability level of the signal.
Stability Stability `mapstructure:"stability"`

Expand Down
44 changes: 43 additions & 1 deletion cmd/mdatagen/internal/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import (
"errors"
"fmt"
"regexp"
"strings"

"golang.org/x/text/cases"
Expand All @@ -16,6 +17,8 @@
"go.opentelemetry.io/collector/pdata/pmetric"
)

var reNonAlnum = regexp.MustCompile(`[^a-z0-9]+`)

type MetricName string

func (mn MetricName) Render() (string, error) {
Expand Down Expand Up @@ -62,7 +65,7 @@
return fmt.Sprintf(" [%s]", s.Level)
}

func (m *Metric) validate() error {
func (m *Metric) validate(metricName MetricName, semConvVersion string) error {
var errs error
if m.Sum == nil && m.Gauge == nil && m.Histogram == nil {
errs = errors.Join(errs, errors.New("missing metric type key, "+
Expand All @@ -84,9 +87,48 @@
if m.Gauge != nil {
errs = errors.Join(errs, m.Gauge.Validate())
}
if m.SemanticConvention != nil {
if err := validateSemConvMetricURL(m.SemanticConvention.SemanticConventionRef, semConvVersion, string(metricName)); err != nil {
errs = errors.Join(errs, err)
}
}
return errs
}

func metricAnchor(metricName string) string {
m := strings.ToLower(strings.TrimSpace(metricName))
m = reNonAlnum.ReplaceAllString(m, "")
return "metric-" + m
}

// validateSemConvMetricURL verifies the URL matches exactly:
// https://github.com/open-telemetry/semantic-conventions/blob/<semConvVersion>/*#metric-<metricName>
func validateSemConvMetricURL(rawURL, semConvVersion, metricName string) error {
if strings.TrimSpace(rawURL) == "" {
return errors.New("url is empty")
}
if strings.TrimSpace(semConvVersion) == "" {
return errors.New("semConvVersion is empty")
}
if strings.TrimSpace(metricName) == "" {
return errors.New("metricName is empty")
}
semConvVersion = "v" + semConvVersion

anchor := metricAnchor(metricName)
// Build a strict regex that enforces https, repo, blob, given version, any doc path, and exact anchor.
pattern := fmt.Sprintf(`^https://github\.com/open-telemetry/semantic-conventions/blob/%s/[^#\s]+#%s$`,
regexp.QuoteMeta(semConvVersion),
regexp.QuoteMeta(anchor),
)
re := regexp.MustCompile(pattern)
if !re.MatchString(rawURL) {
return errors.New(fmt.Sprintf("invalid semantic-conventions URL: want https://github.com/open-telemetry/semantic-conventions/blob/%s/*#%s, got %q",

Check failure on line 126 in cmd/mdatagen/internal/metric.go

View workflow job for this annotation

GitHub Actions / CodeQL-Build

errorf: should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...) (revive)

Check failure on line 126 in cmd/mdatagen/internal/metric.go

View workflow job for this annotation

GitHub Actions / lint

errorf: should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...) (revive)
semConvVersion, anchor, rawURL))
}
return nil
}

func (m *Metric) Unmarshal(parser *confmap.Conf) error {
if !parser.IsSet("enabled") {
return errors.New("missing required field: `enabled`")
Expand Down
10 changes: 10 additions & 0 deletions cmd/mdatagen/internal/samplereceiver/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ Monotonic cumulative sum int metric with string input_type enabled by default.
| slice_attr | Attribute with a slice value. | Any Slice | false |
| map_attr | Attribute with a map value. | Any Map | false |

### system.cpu.time

Monotonic cumulative sum int metric enabled by default.

The metric will be become optional soon.

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | Semantic Convention |
| ---- | ----------- | ---------- | ----------------------- | --------- | --------- | ------------------- |
| 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) |

## Optional Metrics

The following metrics are not emitted by default. Each of them can be enabled by applying the following configuration:
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading