Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[chore] Refactor mdatagen unmarshaling to use less custom Unmarshalers #9760

Merged
merged 1 commit into from Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/mdatagen/loader_test.go
Expand Up @@ -249,7 +249,7 @@ func TestLoadMetadata(t *testing.T) {
},
{
name: "testdata/unknown_value_type.yaml",
wantErr: "1 error(s) decoding:\n\n* error decoding 'metrics[system.cpu.time]': 1 error(s) decoding:\n\n* error decoding 'sum': 1 error(s) decoding:\n\n* error decoding 'value_type': invalid value_type: \"unknown\"",
wantErr: "1 error(s) decoding:\n\n* error decoding 'metrics[system.cpu.time]': 1 error(s) decoding:\n\n* error decoding 'sum': invalid value_type: \"unknown\"",
},
{
name: "testdata/no_aggregation.yaml",
Expand All @@ -259,7 +259,7 @@ func TestLoadMetadata(t *testing.T) {
{
name: "testdata/invalid_aggregation.yaml",
want: metadata{},
wantErr: "1 error(s) decoding:\n\n* error decoding 'metrics[default.metric]': 1 error(s) decoding:\n\n* error decoding 'sum': 1 error(s) decoding:\n\n* error decoding 'aggregation_temporality': invalid aggregation: \"invalidaggregation\"",
wantErr: "1 error(s) decoding:\n\n* error decoding 'metrics[default.metric]': 1 error(s) decoding:\n\n* error decoding 'sum': invalid aggregation: \"invalidaggregation\"",
},
{
name: "testdata/invalid_type_attr.yaml",
Expand Down
52 changes: 15 additions & 37 deletions cmd/mdatagen/metricdata.go
Expand Up @@ -28,18 +28,20 @@ type MetricData interface {
type AggregationTemporality struct {
// Aggregation describes if the aggregator reports delta changes
// since last report time, or cumulative changes since a fixed start time.
Aggregation pmetric.AggregationTemporality
Aggregation pmetric.AggregationTemporality `mapstructure:"aggregation_temporality"`
}

// UnmarshalText implements the encoding.TextUnmarshaler interface.
func (agg *AggregationTemporality) UnmarshalText(text []byte) error {
switch vtStr := string(text); vtStr {
func (agg *AggregationTemporality) Unmarshal(parser *confmap.Conf) error {
if !parser.IsSet("aggregation_temporality") {
return errors.New("missing required field: `aggregation_temporality`")
}
switch vt := parser.Get("aggregation_temporality"); vt {
case "cumulative":
agg.Aggregation = pmetric.AggregationTemporalityCumulative
case "delta":
agg.Aggregation = pmetric.AggregationTemporalityDelta
default:
return fmt.Errorf("invalid aggregation: %q", vtStr)
return fmt.Errorf("invalid aggregation: %q", vt)
}
return nil
}
Expand Down Expand Up @@ -73,36 +75,31 @@ func (mit MetricInputType) String() string {
// MetricValueType defines the metric number type.
type MetricValueType struct {
// ValueType is type of the metric number, options are "double", "int".
ValueType pmetric.NumberDataPointValueType
ValueType pmetric.NumberDataPointValueType `mapstructure:"value_type"`
}

func (mvt *MetricValueType) Unmarshal(parser *confmap.Conf) error {
if !parser.IsSet("value_type") {
return errors.New("missing required field: `value_type`")
}
return nil
}

// UnmarshalText implements the encoding.TextUnmarshaler interface.
func (mvt *MetricValueType) UnmarshalText(text []byte) error {
switch vtStr := string(text); vtStr {
switch vt := parser.Get("value_type"); vt {
case "int":
mvt.ValueType = pmetric.NumberDataPointValueTypeInt
case "double":
mvt.ValueType = pmetric.NumberDataPointValueTypeDouble
default:
return fmt.Errorf("invalid value_type: %q", vtStr)
return fmt.Errorf("invalid value_type: %q", vt)
}
return nil
}

// Type returns name of the datapoint type.
func (mvt MetricValueType) String() string {
func (mvt *MetricValueType) String() string {
return mvt.ValueType.String()
}

// BasicType returns name of a golang basic type for the datapoint type.
func (mvt MetricValueType) BasicType() string {
func (mvt *MetricValueType) BasicType() string {
switch mvt.ValueType {
case pmetric.NumberDataPointValueTypeInt:
return "int64"
Expand All @@ -116,18 +113,10 @@ func (mvt MetricValueType) BasicType() string {
}

type gauge struct {
MetricValueType `mapstructure:"value_type"`
MetricValueType `mapstructure:",squash"`
MetricInputType `mapstructure:",squash"`
}

// Unmarshal is a custom unmarshaler for gauge. Needed mostly to avoid MetricValueType.Unmarshal inheritance.
func (d *gauge) Unmarshal(parser *confmap.Conf) error {
if err := d.MetricValueType.Unmarshal(parser); err != nil {
return err
}
return parser.Unmarshal(d, confmap.WithIgnoreUnused())
}

func (d gauge) Type() string {
return "Gauge"
}
Expand All @@ -141,23 +130,12 @@ func (d gauge) HasAggregated() bool {
}

type sum struct {
AggregationTemporality `mapstructure:"aggregation_temporality"`
AggregationTemporality `mapstructure:",squash"`
Mono `mapstructure:",squash"`
MetricValueType `mapstructure:"value_type"`
MetricValueType `mapstructure:",squash"`
MetricInputType `mapstructure:",squash"`
}

// Unmarshal is a custom unmarshaler for sum. Needed mostly to avoid MetricValueType.Unmarshal inheritance.
func (d *sum) Unmarshal(parser *confmap.Conf) error {
if !parser.IsSet("aggregation_temporality") {
return errors.New("missing required field: `aggregation_temporality`")
}
if err := d.MetricValueType.Unmarshal(parser); err != nil {
return err
}
return parser.Unmarshal(d, confmap.WithIgnoreUnused())
}

// TODO: Currently, this func will not be called because of https://github.com/open-telemetry/opentelemetry-collector/issues/6671. Uncomment function and
// add a test case to Test_loadMetadata for file no_monotonic.yaml once the issue is solved.
//
Expand Down