Skip to content

Commit

Permalink
[exporter/prometheusremotewrite] deprecate export_created_metric (#36214
Browse files Browse the repository at this point in the history
)

#### Description

Deprecate export_created_metric config option

#### Link to tracking issue
Fixes #35003

---------

Co-authored-by: Arthur Silva Sens <arthursens2005@gmail.com>
Co-authored-by: David Ashpole <dashpole@google.com>
  • Loading branch information
3 people authored Nov 18, 2024
1 parent b14856e commit b97b1b6
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 16 deletions.
25 changes: 25 additions & 0 deletions .chloggen/35003-deprecate-export_created_metric.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: deprecation

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

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Deprecate configuration option `export_created metric`

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

# (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: Disable the exporter.prometheusremotewriteexporter.deprecateCreatedMetric feature gate to temporarily re-enable the created metric.

# 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]
2 changes: 1 addition & 1 deletion exporter/prometheusremotewriteexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ The following settings can be optionally configured:
- `enabled` (default = false): If `enabled` is `true`, all the resource attributes will be converted to metric labels by default.
- `target_info`: customize `target_info` metric
- `enabled` (default = true): If `enabled` is `true`, a `target_info` metric will be generated for each resource metric (see https://github.com/open-telemetry/opentelemetry-specification/pull/2381).
- `export_created_metric`:
- `export_created_metric`: `WARNING` Deprecated and planned for removal in v0.116.0. See [related issue](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/35003) for more information.
- `enabled` (default = false): If `enabled` is `true`, a `_created` metric is
exported for Summary, Histogram, and Monotonic Sum metric points if
`StartTimeUnixNano` is set.
Expand Down
2 changes: 2 additions & 0 deletions exporter/prometheusremotewriteexporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type Config struct {
TargetInfo *TargetInfo `mapstructure:"target_info,omitempty"`

// CreatedMetric allows customizing creation of _created metrics
// Deprecated[0.114.0]: The feature doesn't provide the expected behavior. Use Prometheus remote-write v2 to enable sending Created Timestamps.
// This feature is planned to be removed in v0.116.0
CreatedMetric *CreatedMetric `mapstructure:"export_created_metric,omitempty"`

// AddMetricSuffixes controls whether unit and type suffixes are added to metrics on export
Expand Down
4 changes: 4 additions & 0 deletions exporter/prometheusremotewriteexporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ func newPRWExporter(cfg *Config, set exporter.Settings) (*prwExporter, error) {
batchTimeSeriesState: newBatchTimeSericesState(),
}

if prwe.exporterSettings.ExportCreatedMetric {
prwe.settings.Logger.Warn("export_created_metric is deprecated and will be removed in a future release")
}

prwe.wal = newWAL(cfg.WAL, prwe.export)
return prwe, nil
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/translator/prometheusremotewrite/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ go 1.22.0
require (
github.com/cespare/xxhash/v2 v2.3.0
github.com/google/go-cmp v0.6.0
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.113.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheus v0.113.0
github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.113.0
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.112.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheus v0.112.0
github.com/prometheus/common v0.60.1
github.com/prometheus/prometheus v0.54.1
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/collector/featuregate v1.19.1-0.20241115165626-8b99b8023ca3
go.opentelemetry.io/collector/pdata v1.19.1-0.20241115165626-8b99b8023ca3
go.opentelemetry.io/collector/semconv v0.113.1-0.20241115165626-8b99b8023ca3
go.uber.org/goleak v1.3.0
Expand All @@ -26,7 +28,6 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
go.opentelemetry.io/collector/featuregate v1.19.1-0.20241115165626-8b99b8023ca3 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.19.0 // indirect
Expand Down
12 changes: 10 additions & 2 deletions pkg/translator/prometheusremotewrite/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/prometheus/prometheus/model/timestamp"
"github.com/prometheus/prometheus/model/value"
"github.com/prometheus/prometheus/prompb"
"go.opentelemetry.io/collector/featuregate"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/pmetric"
conventions "go.opentelemetry.io/collector/semconv/v1.25.0"
Expand All @@ -41,6 +42,13 @@ const (
infoType = "info"
)

var exportCreatedMetricGate = featuregate.GlobalRegistry().MustRegister(
"exporter.prometheusremotewriteexporter.deprecateCreatedMetric",
featuregate.StageAlpha,
featuregate.WithRegisterDescription("Feature gate used to control the deprecation of created metrics."),
featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/35003"),
)

type bucketBoundsData struct {
ts *prompb.TimeSeries
bound float64
Expand Down Expand Up @@ -275,7 +283,7 @@ func (c *prometheusConverter) addHistogramDataPoints(dataPoints pmetric.Histogra
c.addExemplars(pt, bucketBounds)

startTimestamp := pt.StartTimestamp()
if settings.ExportCreatedMetric && startTimestamp != 0 {
if settings.ExportCreatedMetric && startTimestamp != 0 && !exportCreatedMetricGate.IsEnabled() {
labels := createLabels(baseName+createdSuffix, baseLabels)
c.addTimeSeriesIfNeeded(labels, startTimestamp, pt.Timestamp())
}
Expand Down Expand Up @@ -431,7 +439,7 @@ func (c *prometheusConverter) addSummaryDataPoints(dataPoints pmetric.SummaryDat
}

startTimestamp := pt.StartTimestamp()
if settings.ExportCreatedMetric && startTimestamp != 0 {
if settings.ExportCreatedMetric && startTimestamp != 0 && !exportCreatedMetricGate.IsEnabled() {
createdLabels := createLabels(baseName+createdSuffix, baseLabels)
c.addTimeSeriesIfNeeded(createdLabels, startTimestamp, pt.Timestamp())
}
Expand Down
110 changes: 100 additions & 10 deletions pkg/translator/prometheusremotewrite/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"go.opentelemetry.io/collector/pdata/pmetric"
conventions "go.opentelemetry.io/collector/semconv/v1.25.0"

"github.com/open-telemetry/opentelemetry-collector-contrib/internal/common/testutil"
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/testdata"
prometheustranslator "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheus"
)
Expand Down Expand Up @@ -677,12 +678,14 @@ func TestMostRecentTimestampInMetric(t *testing.T) {
func TestPrometheusConverter_AddSummaryDataPoints(t *testing.T) {
ts := pcommon.Timestamp(time.Now().UnixNano())
tests := []struct {
name string
metric func() pmetric.Metric
want func() map[uint64]*prompb.TimeSeries
name string
isGateEnabled bool
metric func() pmetric.Metric
want func() map[uint64]*prompb.TimeSeries
}{
{
name: "summary with start time",
name: "summary with start time",
isGateEnabled: false,
metric: func() pmetric.Metric {
metric := pmetric.NewMetric()
metric.SetName("test_summary")
Expand Down Expand Up @@ -727,14 +730,52 @@ func TestPrometheusConverter_AddSummaryDataPoints(t *testing.T) {
},
},
{
name: "summary without start time",
name: "summary without start time",
isGateEnabled: false,
metric: func() pmetric.Metric {
metric := pmetric.NewMetric()
metric.SetName("test_summary")
metric.SetEmptySummary()

dp := metric.Summary().DataPoints().AppendEmpty()
dp.SetTimestamp(ts)

return metric
},
want: func() map[uint64]*prompb.TimeSeries {
labels := []prompb.Label{
{Name: model.MetricNameLabel, Value: "test_summary" + countStr},
}
sumLabels := []prompb.Label{
{Name: model.MetricNameLabel, Value: "test_summary" + sumStr},
}
return map[uint64]*prompb.TimeSeries{
timeSeriesSignature(labels): {
Labels: labels,
Samples: []prompb.Sample{
{Value: 0, Timestamp: convertTimeStamp(ts)},
},
},
timeSeriesSignature(sumLabels): {
Labels: sumLabels,
Samples: []prompb.Sample{
{Value: 0, Timestamp: convertTimeStamp(ts)},
},
},
}
},
},
{
name: "summary with exportCreatedMetricGate enabled",
isGateEnabled: true,
metric: func() pmetric.Metric {
metric := pmetric.NewMetric()
metric.SetName("test_summary")
metric.SetEmptySummary()

dp := metric.Summary().DataPoints().AppendEmpty()
dp.SetTimestamp(ts)
dp.SetStartTimestamp(ts)

return metric
},
Expand Down Expand Up @@ -764,6 +805,10 @@ func TestPrometheusConverter_AddSummaryDataPoints(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
oldValue := exportCreatedMetricGate.IsEnabled()
testutil.SetFeatureGateForTest(t, exportCreatedMetricGate, tt.isGateEnabled)
defer testutil.SetFeatureGateForTest(t, exportCreatedMetricGate, oldValue)

metric := tt.metric()
converter := newPrometheusConverter()

Expand All @@ -785,12 +830,14 @@ func TestPrometheusConverter_AddSummaryDataPoints(t *testing.T) {
func TestPrometheusConverter_AddHistogramDataPoints(t *testing.T) {
ts := pcommon.Timestamp(time.Now().UnixNano())
tests := []struct {
name string
metric func() pmetric.Metric
want func() map[uint64]*prompb.TimeSeries
name string
isGateEnabled bool
metric func() pmetric.Metric
want func() map[uint64]*prompb.TimeSeries
}{
{
name: "histogram with start time",
name: "histogram with start time",
isGateEnabled: false,
metric: func() pmetric.Metric {
metric := pmetric.NewMetric()
metric.SetName("test_hist")
Expand Down Expand Up @@ -836,7 +883,8 @@ func TestPrometheusConverter_AddHistogramDataPoints(t *testing.T) {
},
},
{
name: "histogram without start time",
name: "histogram without start time",
isGateEnabled: false,
metric: func() pmetric.Metric {
metric := pmetric.NewMetric()
metric.SetName("test_hist")
Expand Down Expand Up @@ -871,9 +919,51 @@ func TestPrometheusConverter_AddHistogramDataPoints(t *testing.T) {
}
},
},
{
name: "histogram with exportCreatedMetricGate enabled",
isGateEnabled: true,
metric: func() pmetric.Metric {
metric := pmetric.NewMetric()
metric.SetName("test_hist")
metric.SetEmptyHistogram().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)

pt := metric.Histogram().DataPoints().AppendEmpty()
pt.SetTimestamp(ts)
pt.SetStartTimestamp(ts)

return metric
},
want: func() map[uint64]*prompb.TimeSeries {
labels := []prompb.Label{
{Name: model.MetricNameLabel, Value: "test_hist" + countStr},
}
infLabels := []prompb.Label{
{Name: model.MetricNameLabel, Value: "test_hist_bucket"},
{Name: model.BucketLabel, Value: "+Inf"},
}
return map[uint64]*prompb.TimeSeries{
timeSeriesSignature(infLabels): {
Labels: infLabels,
Samples: []prompb.Sample{
{Value: 0, Timestamp: convertTimeStamp(ts)},
},
},
timeSeriesSignature(labels): {
Labels: labels,
Samples: []prompb.Sample{
{Value: 0, Timestamp: convertTimeStamp(ts)},
},
},
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
oldValue := exportCreatedMetricGate.IsEnabled()
testutil.SetFeatureGateForTest(t, exportCreatedMetricGate, tt.isGateEnabled)
defer testutil.SetFeatureGateForTest(t, exportCreatedMetricGate, oldValue)

metric := tt.metric()
converter := newPrometheusConverter()

Expand Down

0 comments on commit b97b1b6

Please sign in to comment.