Skip to content

Commit f12d297

Browse files
committed
Add EnableTypeAndUnitLabels flag to add type and unit label
Signed-off-by: SungJin1212 <[email protected]>
1 parent 52b9672 commit f12d297

File tree

6 files changed

+113
-26
lines changed

6 files changed

+113
-26
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* [CHANGE] StoreGateway/Alertmanager: Add default 5s connection timeout on client. #6603
55
* [CHANGE] Ingester: Remove EnableNativeHistograms config flag and instead gate keep through new per-tenant limit at ingestion. #6718
66
* [CHANGE] Validate a tenantID when to use a single tenant resolver. #6727
7+
* [FEATURE] Distributor: Add an experimental `-distributor.otlp.enable-type-and-unit-labels` flag to add `__type__` and `__unit__` labels for OTLP metrics. #6969
78
* [FEATURE] Distributor: Add an experimental `-distributor.otlp.allow-delta-temporality` flag to ingest delta temporality otlp metrics. #6934
89
* [FEATURE] Query Frontend: Add dynamic interval size for query splitting. This is enabled by configuring experimental flags `querier.max-shards-per-query` and/or `querier.max-fetched-data-duration-per-query`. The split interval size is dynamically increased to maintain a number of shards and total duration fetched below the configured values. #6458
910
* [FEATURE] Querier/Ruler: Add `query_partial_data` and `rules_partial_data` limits to allow queries/rules to be evaluated with data from a single zone, if other zones are not available. #6526

docs/configuration/config-file-reference.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3265,6 +3265,11 @@ otlp:
32653265
# EXPERIMENTAL: If true, delta temporality otlp metrics to be ingested.
32663266
# CLI flag: -distributor.otlp.allow-delta-temporality
32673267
[allow_delta_temporality: <boolean> | default = false]
3268+
3269+
# EXPERIMENTAL: If true, the '__type__' and '__unit__' labels are added for
3270+
# the OTLP metrics.
3271+
# CLI flag: -distributor.otlp.enable-type-and-unit-labels
3272+
[enable_type_and_unit_labels: <boolean> | default = false]
32683273
```
32693274

32703275
### `etcd_config`

docs/configuration/v1-guarantees.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ Currently experimental features are:
118118
- `alertmanager-sharding-ring.final-sleep` (duration) CLI flag
119119
- OTLP Receiver
120120
- Ingest delta temporality OTLP metrics (`-distributor.otlp.allow-delta-temporality=true`)
121+
- Add `__type__` and `__unit__` labels (`-distributor.otlp.enable-type-and-unit-labels`)
121122
- Persistent tokens in the Ruler Ring:
122123
- `-ruler.ring.tokens-file-path` (path) CLI flag
123124
- Native Histograms

pkg/distributor/distributor.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,10 @@ type InstanceLimits struct {
193193
}
194194

195195
type OTLPConfig struct {
196-
ConvertAllAttributes bool `yaml:"convert_all_attributes"`
197-
DisableTargetInfo bool `yaml:"disable_target_info"`
198-
AllowDeltaTemporality bool `yaml:"allow_delta_temporality"`
196+
ConvertAllAttributes bool `yaml:"convert_all_attributes"`
197+
DisableTargetInfo bool `yaml:"disable_target_info"`
198+
AllowDeltaTemporality bool `yaml:"allow_delta_temporality"`
199+
EnableTypeAndUnitLabels bool `yaml:"enable_type_and_unit_labels"`
199200
}
200201

201202
// RegisterFlags adds the flags required to config this to the given FlagSet
@@ -224,6 +225,7 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
224225
f.BoolVar(&cfg.OTLPConfig.ConvertAllAttributes, "distributor.otlp.convert-all-attributes", false, "If true, all resource attributes are converted to labels.")
225226
f.BoolVar(&cfg.OTLPConfig.DisableTargetInfo, "distributor.otlp.disable-target-info", false, "If true, a target_info metric is not ingested. (refer to: https://github.com/prometheus/OpenMetrics/blob/main/specification/OpenMetrics.md#supporting-target-metadata-in-both-push-based-and-pull-based-systems)")
226227
f.BoolVar(&cfg.OTLPConfig.AllowDeltaTemporality, "distributor.otlp.allow-delta-temporality", false, "EXPERIMENTAL: If true, delta temporality otlp metrics to be ingested.")
228+
f.BoolVar(&cfg.OTLPConfig.EnableTypeAndUnitLabels, "distributor.otlp.enable-type-and-unit-labels", false, "EXPERIMENTAL: If true, the '__type__' and '__unit__' labels are added for the OTLP metrics.")
227229
}
228230

229231
// Validate config and returns error on failure

pkg/util/push/otlp.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,10 @@ func decodeOTLPWriteRequest(ctx context.Context, r *http.Request, maxSize int) (
178178
func convertToPromTS(ctx context.Context, pmetrics pmetric.Metrics, cfg distributor.OTLPConfig, overrides *validation.Overrides, userID string, logger log.Logger) ([]prompb.TimeSeries, []prompb.MetricMetadata, error) {
179179
promConverter := prometheusremotewrite.NewPrometheusConverter()
180180
settings := prometheusremotewrite.Settings{
181-
AddMetricSuffixes: true,
182-
DisableTargetInfo: cfg.DisableTargetInfo,
183-
AllowDeltaTemporality: cfg.AllowDeltaTemporality,
181+
AddMetricSuffixes: true,
182+
DisableTargetInfo: cfg.DisableTargetInfo,
183+
AllowDeltaTemporality: cfg.AllowDeltaTemporality,
184+
EnableTypeAndUnitLabels: cfg.EnableTypeAndUnitLabels,
184185
}
185186

186187
var annots annotations.Annotations

pkg/util/push/otlp_test.go

Lines changed: 97 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"time"
1414

1515
"github.com/go-kit/log"
16+
"github.com/prometheus/prometheus/model/labels"
1617
"github.com/prometheus/prometheus/prompb"
1718
"github.com/stretchr/testify/assert"
1819
"github.com/stretchr/testify/require"
@@ -27,6 +28,80 @@ import (
2728
"github.com/cortexproject/cortex/pkg/util/validation"
2829
)
2930

31+
func TestOTLP_EnableTypeAndUnitLabels(t *testing.T) {
32+
logger := log.NewNopLogger()
33+
ctx := context.Background()
34+
ts := time.Now()
35+
36+
tests := []struct {
37+
description string
38+
enableTypeAndUnitLabels bool
39+
allowDeltaTemporality bool
40+
otlpSeries pmetric.Metric
41+
expectedLabels labels.Labels
42+
expectedMetadata prompb.MetricMetadata
43+
}{
44+
{
45+
description: "[enableTypeAndUnitLabels: true], the '__type__' label should be attached with the gauge type",
46+
enableTypeAndUnitLabels: true,
47+
otlpSeries: createOtelSum("test", "seconds", pmetric.AggregationTemporalityCumulative, ts),
48+
expectedLabels: labels.FromMap(map[string]string{
49+
"__name__": "test_seconds",
50+
"__type__": "gauge",
51+
"__unit__": "seconds",
52+
"test_label": "test_value",
53+
}),
54+
expectedMetadata: createPromMetadata("test_seconds", "seconds", prompb.MetricMetadata_GAUGE),
55+
},
56+
{
57+
description: "[enableTypeAndUnitLabels: true], the '__type__' label should not be attached with the unknown type ",
58+
enableTypeAndUnitLabels: true,
59+
allowDeltaTemporality: true,
60+
otlpSeries: createOtelSum("test", "seconds", pmetric.AggregationTemporalityDelta, ts),
61+
expectedLabels: labels.FromMap(map[string]string{
62+
"__name__": "test_seconds",
63+
"__unit__": "seconds",
64+
"test_label": "test_value",
65+
}),
66+
expectedMetadata: createPromMetadata("test_seconds", "seconds", prompb.MetricMetadata_UNKNOWN),
67+
},
68+
{
69+
description: "[enableTypeAndUnitLabels: false]",
70+
enableTypeAndUnitLabels: false,
71+
otlpSeries: createOtelSum("test", "seconds", pmetric.AggregationTemporalityCumulative, ts),
72+
expectedLabels: labels.FromMap(map[string]string{
73+
"__name__": "test_seconds",
74+
"test_label": "test_value",
75+
}),
76+
expectedMetadata: createPromMetadata("test_seconds", "seconds", prompb.MetricMetadata_GAUGE),
77+
},
78+
}
79+
80+
for _, test := range tests {
81+
t.Run(test.description, func(t *testing.T) {
82+
cfg := distributor.OTLPConfig{
83+
EnableTypeAndUnitLabels: test.enableTypeAndUnitLabels,
84+
AllowDeltaTemporality: test.allowDeltaTemporality,
85+
}
86+
metrics := pmetric.NewMetrics()
87+
rm := metrics.ResourceMetrics().AppendEmpty()
88+
sm := rm.ScopeMetrics().AppendEmpty()
89+
90+
test.otlpSeries.CopyTo(sm.Metrics().AppendEmpty())
91+
92+
limits := validation.Limits{}
93+
overrides := validation.NewOverrides(limits, nil)
94+
promSeries, metadata, err := convertToPromTS(ctx, metrics, cfg, overrides, "user-1", logger)
95+
require.NoError(t, err)
96+
require.Equal(t, 1, len(promSeries))
97+
require.Equal(t, prompb.FromLabels(test.expectedLabels, nil), promSeries[0].Labels)
98+
99+
require.Equal(t, 1, len(metadata))
100+
require.Equal(t, test.expectedMetadata, metadata[0])
101+
})
102+
}
103+
}
104+
30105
func TestOTLP_AllowDeltaTemporality(t *testing.T) {
31106
logger := log.NewNopLogger()
32107
ctx := context.Background()
@@ -44,24 +119,24 @@ func TestOTLP_AllowDeltaTemporality(t *testing.T) {
44119
description: "[allowDeltaTemporality: false] cumulative type should be converted",
45120
allowDeltaTemporality: false,
46121
otlpSeries: []pmetric.Metric{
47-
createOtelSum("test_1", pmetric.AggregationTemporalityCumulative, ts),
48-
createOtelSum("test_2", pmetric.AggregationTemporalityCumulative, ts),
122+
createOtelSum("test_1", "", pmetric.AggregationTemporalityCumulative, ts),
123+
createOtelSum("test_2", "", pmetric.AggregationTemporalityCumulative, ts),
49124
},
50125
expectedSeries: []prompb.TimeSeries{
51126
createPromFloatSeries("test_1", ts),
52127
createPromFloatSeries("test_2", ts),
53128
},
54129
expectedMetadata: []prompb.MetricMetadata{
55-
createPromMetadata("test_1", prompb.MetricMetadata_GAUGE),
56-
createPromMetadata("test_2", prompb.MetricMetadata_GAUGE),
130+
createPromMetadata("test_1", "", prompb.MetricMetadata_GAUGE),
131+
createPromMetadata("test_2", "", prompb.MetricMetadata_GAUGE),
57132
},
58133
},
59134
{
60135
description: "[allowDeltaTemporality: false] delta type should not be converted",
61136
allowDeltaTemporality: false,
62137
otlpSeries: []pmetric.Metric{
63-
createOtelSum("test_1", pmetric.AggregationTemporalityDelta, ts),
64-
createOtelSum("test_2", pmetric.AggregationTemporalityDelta, ts),
138+
createOtelSum("test_1", "", pmetric.AggregationTemporalityDelta, ts),
139+
createOtelSum("test_2", "", pmetric.AggregationTemporalityDelta, ts),
65140
},
66141
expectedSeries: []prompb.TimeSeries{},
67142
expectedMetadata: []prompb.MetricMetadata{},
@@ -71,30 +146,30 @@ func TestOTLP_AllowDeltaTemporality(t *testing.T) {
71146
description: "[allowDeltaTemporality: true] delta type should be converted",
72147
allowDeltaTemporality: true,
73148
otlpSeries: []pmetric.Metric{
74-
createOtelSum("test_1", pmetric.AggregationTemporalityDelta, ts),
75-
createOtelSum("test_2", pmetric.AggregationTemporalityDelta, ts),
149+
createOtelSum("test_1", "", pmetric.AggregationTemporalityDelta, ts),
150+
createOtelSum("test_2", "", pmetric.AggregationTemporalityDelta, ts),
76151
},
77152
expectedSeries: []prompb.TimeSeries{
78153
createPromFloatSeries("test_1", ts),
79154
createPromFloatSeries("test_2", ts),
80155
},
81156
expectedMetadata: []prompb.MetricMetadata{
82-
createPromMetadata("test_1", prompb.MetricMetadata_UNKNOWN),
83-
createPromMetadata("test_2", prompb.MetricMetadata_UNKNOWN),
157+
createPromMetadata("test_1", "", prompb.MetricMetadata_UNKNOWN),
158+
createPromMetadata("test_2", "", prompb.MetricMetadata_UNKNOWN),
84159
},
85160
},
86161
{
87162
description: "[allowDeltaTemporality: false] mixed delta and cumulative, should be converted only for cumulative type",
88163
allowDeltaTemporality: false,
89164
otlpSeries: []pmetric.Metric{
90-
createOtelSum("test_1", pmetric.AggregationTemporalityDelta, ts),
91-
createOtelSum("test_2", pmetric.AggregationTemporalityCumulative, ts),
165+
createOtelSum("test_1", "", pmetric.AggregationTemporalityDelta, ts),
166+
createOtelSum("test_2", "", pmetric.AggregationTemporalityCumulative, ts),
92167
},
93168
expectedSeries: []prompb.TimeSeries{
94169
createPromFloatSeries("test_2", ts),
95170
},
96171
expectedMetadata: []prompb.MetricMetadata{
97-
createPromMetadata("test_2", prompb.MetricMetadata_GAUGE),
172+
createPromMetadata("test_2", "", prompb.MetricMetadata_GAUGE),
98173
},
99174
expectedErr: `invalid temporality and type combination for metric "test_1"`,
100175
},
@@ -110,8 +185,8 @@ func TestOTLP_AllowDeltaTemporality(t *testing.T) {
110185
createPromNativeHistogramSeries("test_2", prompb.Histogram_UNKNOWN, ts),
111186
},
112187
expectedMetadata: []prompb.MetricMetadata{
113-
createPromMetadata("test_1", prompb.MetricMetadata_HISTOGRAM),
114-
createPromMetadata("test_2", prompb.MetricMetadata_HISTOGRAM),
188+
createPromMetadata("test_1", "", prompb.MetricMetadata_HISTOGRAM),
189+
createPromMetadata("test_2", "", prompb.MetricMetadata_HISTOGRAM),
115190
},
116191
},
117192
{
@@ -137,8 +212,8 @@ func TestOTLP_AllowDeltaTemporality(t *testing.T) {
137212
createPromNativeHistogramSeries("test_2", prompb.Histogram_GAUGE, ts),
138213
},
139214
expectedMetadata: []prompb.MetricMetadata{
140-
createPromMetadata("test_1", prompb.MetricMetadata_UNKNOWN),
141-
createPromMetadata("test_2", prompb.MetricMetadata_UNKNOWN),
215+
createPromMetadata("test_1", "", prompb.MetricMetadata_UNKNOWN),
216+
createPromMetadata("test_2", "", prompb.MetricMetadata_UNKNOWN),
142217
},
143218
},
144219
{
@@ -152,7 +227,7 @@ func TestOTLP_AllowDeltaTemporality(t *testing.T) {
152227
createPromNativeHistogramSeries("test_2", prompb.Histogram_UNKNOWN, ts),
153228
},
154229
expectedMetadata: []prompb.MetricMetadata{
155-
createPromMetadata("test_2", prompb.MetricMetadata_HISTOGRAM),
230+
createPromMetadata("test_2", "", prompb.MetricMetadata_HISTOGRAM),
156231
},
157232
expectedErr: `invalid temporality and type combination for metric "test_1"`,
158233
},
@@ -184,9 +259,10 @@ func TestOTLP_AllowDeltaTemporality(t *testing.T) {
184259
}
185260
}
186261

187-
func createPromMetadata(name string, metadataType prompb.MetricMetadata_MetricType) prompb.MetricMetadata {
262+
func createPromMetadata(name, unit string, metadataType prompb.MetricMetadata_MetricType) prompb.MetricMetadata {
188263
return prompb.MetricMetadata{
189264
Type: metadataType,
265+
Unit: unit,
190266
MetricFamilyName: name,
191267
}
192268
}
@@ -221,10 +297,11 @@ func createPromFloatSeries(name string, ts time.Time) prompb.TimeSeries {
221297
}
222298

223299
// copied from: https://github.com/prometheus/prometheus/blob/v3.5.0/storage/remote/otlptranslator/prometheusremotewrite/metrics_to_prw.go
224-
func createOtelSum(name string, temporality pmetric.AggregationTemporality, ts time.Time) pmetric.Metric {
300+
func createOtelSum(name, unit string, temporality pmetric.AggregationTemporality, ts time.Time) pmetric.Metric {
225301
metrics := pmetric.NewMetricSlice()
226302
m := metrics.AppendEmpty()
227303
m.SetName(name)
304+
m.SetUnit(unit)
228305
sum := m.SetEmptySum()
229306
sum.SetAggregationTemporality(temporality)
230307
dp := sum.DataPoints().AppendEmpty()

0 commit comments

Comments
 (0)