1// Copyright The OpenTelemetry Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package main
16
17import (
18	"fmt"
19)
20
21var (
22	_ MetricData = &gauge{}
23	_ MetricData = &sum{}
24	_ MetricData = &histogram{}
25)
26
27type ymlMetricData struct {
28	MetricData `yaml:"-"`
29}
30
31// UnmarshalYAML converts the metrics.data map based on metrics.data.type.
32func (e *ymlMetricData) UnmarshalYAML(unmarshal func(interface{}) error) error {
33	var m struct {
34		Type string `yaml:"type"`
35	}
36
37	if err := unmarshal(&m); err != nil {
38		return err
39	}
40
41	var md MetricData
42
43	switch m.Type {
44	case "gauge":
45		md = &gauge{}
46	case "sum":
47		md = &sum{}
48	case "histogram":
49		md = &histogram{}
50	default:
51		return fmt.Errorf("metric data %q type invalid", m.Type)
52	}
53
54	if err := unmarshal(md); err != nil {
55		return fmt.Errorf("unable to unmarshal data for type %q: %v", m.Type, err)
56	}
57
58	e.MetricData = md
59
60	return nil
61}
62
63// MetricData is generic interface for all metric datatypes.
64type MetricData interface {
65	Type() string
66	HasMonotonic() bool
67	HasAggregated() bool
68}
69
70// Aggregated defines a metric aggregation type.
71type Aggregated struct {
72	// Aggregation describes if the aggregator reports delta changes
73	// since last report time, or cumulative changes since a fixed start time.
74	Aggregation string `yaml:"aggregation" validate:"oneof=delta cumulative"`
75}
76
77// Type gets the metric aggregation type.
78func (agg Aggregated) Type() string {
79	switch agg.Aggregation {
80	case "delta":
81		return "pdata.AggregationTemporalityDelta"
82	case "cumulative":
83		return "pdata.AggregationTemporalityCumulative"
84	default:
85		return "pdata.AggregationTemporalityUnknown"
86	}
87}
88
89// Mono defines the metric monotonicity.
90type Mono struct {
91	// Monotonic is true if the sum is monotonic.
92	Monotonic bool `yaml:"monotonic"`
93}
94
95type gauge struct {
96}
97
98func (d gauge) Type() string {
99	return "Gauge"
100}
101
102func (d gauge) HasMonotonic() bool {
103	return false
104}
105
106func (d gauge) HasAggregated() bool {
107	return false
108}
109
110type sum struct {
111	Aggregated `yaml:",inline"`
112	Mono       `yaml:",inline"`
113}
114
115func (d sum) Type() string {
116	return "Sum"
117}
118
119func (d sum) HasMonotonic() bool {
120	return true
121}
122
123func (d sum) HasAggregated() bool {
124	return true
125}
126
127type histogram struct {
128	Aggregated `yaml:",inline"`
129}
130
131func (d histogram) Type() string {
132	return "Histogram"
133}
134
135func (d histogram) HasMonotonic() bool {
136	return false
137}
138
139func (d histogram) HasAggregated() bool {
140	return true
141}
142