Skip to content

Commit

Permalink
[telemetry] mark useOtelForInternalMetrics stable (#9102)
Browse files Browse the repository at this point in the history
This marks the flag as stable. Leaving this as a draft until v0.92.0 is
released.

Closes #8962
Fixes #816

---------

Signed-off-by: Alex Boten <aboten@lightstep.com>
  • Loading branch information
Alex Boten committed Jan 16, 2024
1 parent 3a16592 commit 8344135
Show file tree
Hide file tree
Showing 47 changed files with 191 additions and 1,183 deletions.
25 changes: 25 additions & 0 deletions .chloggen/codeboten_mark-stable-otel.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: service

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: mark `telemetry.useOtelForInternalMetrics` as stable

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

# (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: []
1 change: 0 additions & 1 deletion cmd/mdatagen/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ require (
github.com/prometheus/procfs v0.12.0 // indirect
github.com/prometheus/statsd_exporter v0.22.7 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/collector v0.92.0 // indirect
go.opentelemetry.io/collector/config/configtelemetry v0.92.0 // indirect
go.opentelemetry.io/collector/consumer v0.92.0 // indirect
go.opentelemetry.io/collector/featuregate v1.0.1 // indirect
Expand Down
3 changes: 0 additions & 3 deletions component/componenttest/obsreporttest.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/configtelemetry"
"go.opentelemetry.io/collector/internal/obsreportconfig"
)

const (
Expand Down Expand Up @@ -154,7 +153,6 @@ func SetupTelemetry(id component.ID) (TestTelemetry, error) {
}
settings.ts.TracerProvider = tp
settings.ts.MetricsLevel = configtelemetry.LevelNormal
settings.views = obsreportconfig.AllViews(configtelemetry.LevelNormal)
err := view.Register(settings.views...)
if err != nil {
return settings, err
Expand Down Expand Up @@ -182,7 +180,6 @@ func SetupTelemetry(id component.ID) (TestTelemetry, error) {
settings.ts.MeterProvider = settings.meterProvider

settings.prometheusChecker = &prometheusChecker{
ocHandler: settings.ocExporter,
otelHandler: promhttp.HandlerFor(promRegOtel, promhttp.HandlerOpts{}),
}

Expand Down
8 changes: 1 addition & 7 deletions component/componenttest/otelprometheuschecker.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ import (
"go.uber.org/multierr"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/internal/obsreportconfig"
)

// prometheusChecker is used to assert exported metrics from a prometheus handler.
type prometheusChecker struct {
ocHandler http.Handler
otelHandler http.Handler
}

Expand Down Expand Up @@ -139,11 +137,7 @@ func (pc *prometheusChecker) checkCounter(expectedMetric string, value int64, at
// getMetric returns the metric time series that matches the given name, type and set of attributes
// it fetches data from the prometheus endpoint and parse them, ideally OTel Go should provide a MeterRecorder of some kind.
func (pc *prometheusChecker) getMetric(expectedName string, expectedType io_prometheus_client.MetricType, expectedAttrs []attribute.KeyValue) (*io_prometheus_client.Metric, error) {
handler := pc.ocHandler
if obsreportconfig.UseOtelForInternalMetricsfeatureGate.IsEnabled() {
handler = pc.otelHandler
}
parsed, err := fetchPrometheusMetrics(handler)
parsed, err := fetchPrometheusMetrics(pc.otelHandler)
if err != nil {
return nil, err
}
Expand Down
3 changes: 0 additions & 3 deletions component/componenttest/otelprometheuschecker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ func newStubPromChecker() (prometheusChecker, error) {
promResponse := strings.ReplaceAll(string(promBytes), "\r\n", "\n")

return prometheusChecker{
ocHandler: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(promResponse))
}),
otelHandler: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(promResponse))
}),
Expand Down
5 changes: 0 additions & 5 deletions component/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ require (
github.com/prometheus/common v0.46.0
github.com/stretchr/testify v1.8.4
go.opencensus.io v0.24.0
go.opentelemetry.io/collector v0.92.0
go.opentelemetry.io/collector/config/configtelemetry v0.92.0
go.opentelemetry.io/collector/confmap v0.92.0
go.opentelemetry.io/collector/pdata v1.0.1
Expand Down Expand Up @@ -68,7 +67,3 @@ retract (
v0.76.0 // Depends on retracted pdata v1.0.0-rc10 module, use v0.76.1
v0.69.0 // Release failed, use v0.69.1
)

replace go.opentelemetry.io/collector => ../

replace go.opentelemetry.io/collector/consumer => ../consumer
4 changes: 0 additions & 4 deletions config/configauth/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,3 @@ replace go.opentelemetry.io/collector/config/configtelemetry => ../configtelemet
replace go.opentelemetry.io/collector/extension => ../../extension

replace go.opentelemetry.io/collector/extension/auth => ../../extension/auth

replace go.opentelemetry.io/collector => ../..

replace go.opentelemetry.io/collector/consumer => ../../consumer
5 changes: 1 addition & 4 deletions docs/observability.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,10 @@ configuration of the OpenTelemetry SDK used to produce the Collector's internal
currently behind two feature gates:

```bash
--feature-gates=telemetry.useOtelForInternalMetrics
--feature-gates=telemetry.useOtelWithSDKConfigurationForInternalTelemetry
```

The `useOtelForInternalMetrics` feature gate changes the internal telemetry to use OpenTelemetry rather
than OpenCensus. This will become the default at some point [in the future][issue7454]. The second gate,
`useOtelWithSDKConfigurationForInternalTelemetry` enables the Collector to parse configuration
The gate `useOtelWithSDKConfigurationForInternalTelemetry` enables the Collector to parse configuration
that aligns with the [OpenTelemetry Configuration] schema. The support for this schema is still
experimental, but it does allow telemetry to be exported via OTLP.

Expand Down
5 changes: 0 additions & 5 deletions exporter/exporterhelper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"testing"

"github.com/stretchr/testify/require"
"go.opencensus.io/tag"
"go.opentelemetry.io/otel/codes"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.uber.org/zap"
Expand All @@ -29,10 +28,6 @@ var (
set.ID = defaultID
return set
}()
exporterTag, _ = tag.NewKey("exporter")
defaultExporterTags = []tag.Tag{
{Key: exporterTag, Value: "test"},
}
)

func newNoopObsrepSender(_ *ObsReport) requestSender {
Expand Down
78 changes: 3 additions & 75 deletions exporter/exporterhelper/obsexporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ package exporterhelper // import "go.opentelemetry.io/collector/exporter/exporte
import (
"context"

"go.opencensus.io/stats"
"go.opencensus.io/tag"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric"
Expand All @@ -18,7 +16,6 @@ import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/configtelemetry"
"go.opentelemetry.io/collector/exporter"
"go.opentelemetry.io/collector/internal/obsreportconfig"
"go.opentelemetry.io/collector/internal/obsreportconfig/obsmetrics"
)

Expand All @@ -30,11 +27,9 @@ const (
type ObsReport struct {
level configtelemetry.Level
spanNamePrefix string
mutators []tag.Mutator
tracer trace.Tracer
logger *zap.Logger

useOtelForMetrics bool
otelAttrs []attribute.KeyValue
sentSpans metric.Int64Counter
failedToSendSpans metric.Int64Counter
Expand All @@ -55,18 +50,16 @@ type ObsReportSettings struct {

// NewObsReport creates a new Exporter.
func NewObsReport(cfg ObsReportSettings) (*ObsReport, error) {
return newExporter(cfg, obsreportconfig.UseOtelForInternalMetricsfeatureGate.IsEnabled())
return newExporter(cfg)
}

func newExporter(cfg ObsReportSettings, useOtel bool) (*ObsReport, error) {
func newExporter(cfg ObsReportSettings) (*ObsReport, error) {
exp := &ObsReport{
level: cfg.ExporterCreateSettings.TelemetrySettings.MetricsLevel,
spanNamePrefix: obsmetrics.ExporterPrefix + cfg.ExporterID.String(),
mutators: []tag.Mutator{tag.Upsert(obsmetrics.TagKeyExporter, cfg.ExporterID.String(), tag.WithTTL(tag.TTLNoPropagation))},
tracer: cfg.ExporterCreateSettings.TracerProvider.Tracer(cfg.ExporterID.String()),
logger: cfg.ExporterCreateSettings.Logger,

useOtelForMetrics: useOtel,
otelAttrs: []attribute.KeyValue{
attribute.String(obsmetrics.ExporterKey, cfg.ExporterID.String()),
},
Expand All @@ -80,9 +73,6 @@ func newExporter(cfg ObsReportSettings, useOtel bool) (*ObsReport, error) {
}

func (or *ObsReport) createOtelMetrics(cfg ObsReportSettings) error {
if !or.useOtelForMetrics {
return nil
}
meter := cfg.ExporterCreateSettings.MeterProvider.Meter(exporterScope)

var errors, err error
Expand Down Expand Up @@ -195,18 +185,10 @@ func (or *ObsReport) startOp(ctx context.Context, operationSuffix string) contex
return ctx
}

func (or *ObsReport) recordMetrics(ctx context.Context, dataType component.DataType, numSent, numFailed int64) {
func (or *ObsReport) recordMetrics(ctx context.Context, dataType component.DataType, sent, failed int64) {
if or.level == configtelemetry.LevelNone {
return
}
if or.useOtelForMetrics {
or.recordWithOtel(ctx, dataType, numSent, numFailed)
} else {
or.recordWithOC(ctx, dataType, numSent, numFailed)
}
}

func (or *ObsReport) recordWithOtel(ctx context.Context, dataType component.DataType, sent int64, failed int64) {
var sentMeasure, failedMeasure metric.Int64Counter
switch dataType {
case component.DataTypeTraces:
Expand All @@ -224,34 +206,6 @@ func (or *ObsReport) recordWithOtel(ctx context.Context, dataType component.Data
failedMeasure.Add(ctx, failed, metric.WithAttributes(or.otelAttrs...))
}

func (or *ObsReport) recordWithOC(ctx context.Context, dataType component.DataType, sent int64, failed int64) {
var sentMeasure, failedMeasure *stats.Int64Measure
switch dataType {
case component.DataTypeTraces:
sentMeasure = obsmetrics.ExporterSentSpans
failedMeasure = obsmetrics.ExporterFailedToSendSpans
case component.DataTypeMetrics:
sentMeasure = obsmetrics.ExporterSentMetricPoints
failedMeasure = obsmetrics.ExporterFailedToSendMetricPoints
case component.DataTypeLogs:
sentMeasure = obsmetrics.ExporterSentLogRecords
failedMeasure = obsmetrics.ExporterFailedToSendLogRecords
}

if failed > 0 {
_ = stats.RecordWithTags(
ctx,
or.mutators,
sentMeasure.M(sent),
failedMeasure.M(failed))
} else {
_ = stats.RecordWithTags(
ctx,
or.mutators,
sentMeasure.M(sent))
}
}

func endSpan(ctx context.Context, err error, numSent, numFailedToSend int64, sentItemsKey, failedToSendItemsKey string) {
span := trace.SpanFromContext(ctx)
// End the span according to errors.
Expand All @@ -275,32 +229,6 @@ func toNumItems(numExportedItems int, err error) (int64, int64) {
}

func (or *ObsReport) recordEnqueueFailure(ctx context.Context, dataType component.DataType, failed int64) {
if or.useOtelForMetrics {
or.recordEnqueueFailureWithOtel(ctx, dataType, failed)
} else {
or.recordEnqueueFailureWithOC(ctx, dataType, failed)
}
}

func (or *ObsReport) recordEnqueueFailureWithOC(ctx context.Context, dataType component.DataType, failed int64) {
var failedMeasure *stats.Int64Measure
switch dataType {
case component.DataTypeTraces:
failedMeasure = obsmetrics.ExporterFailedToEnqueueSpans
case component.DataTypeMetrics:
failedMeasure = obsmetrics.ExporterFailedToEnqueueMetricPoints
case component.DataTypeLogs:
failedMeasure = obsmetrics.ExporterFailedToEnqueueLogRecords
}
if failed > 0 {
_ = stats.RecordWithTags(
ctx,
or.mutators,
failedMeasure.M(failed))
}
}

func (or *ObsReport) recordEnqueueFailureWithOtel(ctx context.Context, dataType component.DataType, failed int64) {
var enqueueFailedMeasure metric.Int64Counter
switch dataType {
case component.DataTypeTraces:
Expand Down
31 changes: 8 additions & 23 deletions exporter/exporterhelper/obsexporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/component/componenttest"
"go.opentelemetry.io/collector/exporter"
"go.opentelemetry.io/collector/featuregate"
"go.opentelemetry.io/collector/internal/obsreportconfig"
"go.opentelemetry.io/collector/internal/obsreportconfig/obsmetrics"
)

Expand All @@ -28,14 +26,14 @@ var (
)

func TestExportTraceDataOp(t *testing.T) {
testTelemetry(t, exporterID, func(t *testing.T, tt componenttest.TestTelemetry, useOtel bool) {
testTelemetry(t, exporterID, func(t *testing.T, tt componenttest.TestTelemetry) {
parentCtx, parentSpan := tt.TelemetrySettings().TracerProvider.Tracer("test").Start(context.Background(), t.Name())
defer parentSpan.End()

obsrep, err := newExporter(ObsReportSettings{
ExporterID: exporterID,
ExporterCreateSettings: exporter.CreateSettings{ID: exporterID, TelemetrySettings: tt.TelemetrySettings(), BuildInfo: component.NewDefaultBuildInfo()},
}, useOtel)
})
require.NoError(t, err)

params := []testParams{
Expand Down Expand Up @@ -76,14 +74,14 @@ func TestExportTraceDataOp(t *testing.T) {
}

func TestExportMetricsOp(t *testing.T) {
testTelemetry(t, exporterID, func(t *testing.T, tt componenttest.TestTelemetry, useOtel bool) {
testTelemetry(t, exporterID, func(t *testing.T, tt componenttest.TestTelemetry) {
parentCtx, parentSpan := tt.TelemetrySettings().TracerProvider.Tracer("test").Start(context.Background(), t.Name())
defer parentSpan.End()

obsrep, err := newExporter(ObsReportSettings{
ExporterID: exporterID,
ExporterCreateSettings: exporter.CreateSettings{ID: exporterID, TelemetrySettings: tt.TelemetrySettings(), BuildInfo: component.NewDefaultBuildInfo()},
}, useOtel)
})
require.NoError(t, err)

params := []testParams{
Expand Down Expand Up @@ -125,14 +123,14 @@ func TestExportMetricsOp(t *testing.T) {
}

func TestExportLogsOp(t *testing.T) {
testTelemetry(t, exporterID, func(t *testing.T, tt componenttest.TestTelemetry, useOtel bool) {
testTelemetry(t, exporterID, func(t *testing.T, tt componenttest.TestTelemetry) {
parentCtx, parentSpan := tt.TelemetrySettings().TracerProvider.Tracer("test").Start(context.Background(), t.Name())
defer parentSpan.End()

obsrep, err := newExporter(ObsReportSettings{
ExporterID: exporterID,
ExporterCreateSettings: exporter.CreateSettings{ID: exporterID, TelemetrySettings: tt.TelemetrySettings(), BuildInfo: component.NewDefaultBuildInfo()},
}, useOtel)
})
require.NoError(t, err)

params := []testParams{
Expand Down Expand Up @@ -238,25 +236,12 @@ type testParams struct {
err error
}

func testTelemetry(t *testing.T, id component.ID, testFunc func(t *testing.T, tt componenttest.TestTelemetry, useOtel bool)) {
t.Run("WithOC", func(t *testing.T) {
originalValue := obsreportconfig.UseOtelForInternalMetricsfeatureGate.IsEnabled()
require.NoError(t, featuregate.GlobalRegistry().Set(obsreportconfig.UseOtelForInternalMetricsfeatureGate.ID(), false))
defer func() {
require.NoError(t, featuregate.GlobalRegistry().Set(obsreportconfig.UseOtelForInternalMetricsfeatureGate.ID(), originalValue))
}()
tt, err := componenttest.SetupTelemetry(id)
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) })

testFunc(t, tt, false)
})

func testTelemetry(t *testing.T, id component.ID, testFunc func(t *testing.T, tt componenttest.TestTelemetry)) {
t.Run("WithOTel", func(t *testing.T) {
tt, err := componenttest.SetupTelemetry(id)
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) })

testFunc(t, tt, true)
testFunc(t, tt)
})
}

0 comments on commit 8344135

Please sign in to comment.