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

Add feature flag to allow enabling otel for internal metrics #4912

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- Deprecated `receiverhelper.WithMetrics` in favour of `component.WithMetricsReceiver`
- Deprecated `receiverhelper.WithLogs` in favour of `component.WithLogsReceiver`
- Deprecated `receiverhelper.NewFactory` in favour of `component.NewReceiverFactory`
- Change otel collector to enable open telemetry metrics through feature gate instead of a constant
- Remove support for legacy otlp/http port. (#4916)

### 💡 Enhancements 💡
Expand Down
2 changes: 2 additions & 0 deletions config/configtelemetry/configtelemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const (
levelDetailedStr = "detailed"
)

// Deprecated: UseOpenTelemetryForInternalMetrics has been deprecated. Uses feature flag in
// telemetry.useOtelForInternalMetrics to handle this feature
const UseOpenTelemetryForInternalMetrics = false
bogdandrutu marked this conversation as resolved.
Show resolved Hide resolved

// Level is the level of internal telemetry (metrics, logs, traces about the component itself)
Expand Down
28 changes: 27 additions & 1 deletion service/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/internal/testcomponents"
"go.opentelemetry.io/collector/internal/testutil"
"go.opentelemetry.io/collector/service/featuregate"
)

// TestCollector_StartAsGoRoutine must be the first unit test on the file,
Expand Down Expand Up @@ -80,7 +81,7 @@ func TestCollector_StartAsGoRoutine(t *testing.T) {
}, time.Second*2, time.Millisecond*200)
}

func TestCollector_Start(t *testing.T) {
func testCollectorStartHelper(t *testing.T) {
factories, err := testcomponents.NewDefaultFactories()
require.NoError(t, err)
var once sync.Once
Expand Down Expand Up @@ -135,6 +136,31 @@ func TestCollector_Start(t *testing.T) {
}, time.Second*2, time.Millisecond*200)
}

// as telemetry instance is initialized only once, we need to reset it before each test so the metrics endpoint can
// have correct handler spawned
func resetCollectorTelemetry() {
collectorTelemetry = &colTelemetry{}
}

func TestCollector_Start(t *testing.T) {
resetCollectorTelemetry()
testCollectorStartHelper(t)
}

func TestCollector_StartWithOtelInternalMetrics(t *testing.T) {
resetCollectorTelemetry()
originalFlag := featuregate.IsEnabled(useOtelForInternalMetricsfeatureGateID)
defer func() {
featuregate.Apply(map[string]bool{
useOtelForInternalMetricsfeatureGateID: originalFlag,
})
}()
featuregate.Apply(map[string]bool{
useOtelForInternalMetricsfeatureGateID: true,
})
testCollectorStartHelper(t)
}

// TestCollector_ShutdownNoop verifies that shutdown can be called even if a collector
// has yet to be started and it will execute without error.
func TestCollector_ShutdownNoop(t *testing.T) {
Expand Down
16 changes: 15 additions & 1 deletion service/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"go.opentelemetry.io/collector/internal/version"
semconv "go.opentelemetry.io/collector/model/semconv/v1.5.0"
"go.opentelemetry.io/collector/processor/batchprocessor"
"go.opentelemetry.io/collector/service/featuregate"
telemetry2 "go.opentelemetry.io/collector/service/internal/telemetry"
)

Expand All @@ -50,8 +51,21 @@ const AddCollectorVersionTag = true
const (
zapKeyTelemetryAddress = "address"
zapKeyTelemetryLevel = "level"

// useOtelForInternalMetricsfeatureGateID is the feature gate ID that controls whether the collector uses open
// telemetry for internal metrics.
useOtelForInternalMetricsfeatureGateID = "telemetry.useOtelForInternalMetrics"
bogdandrutu marked this conversation as resolved.
Show resolved Hide resolved
)

func init() {
//nolint:staticcheck
featuregate.Register(featuregate.Gate{
ID: useOtelForInternalMetricsfeatureGateID,
Description: "controls whether the collector to uses open telemetry for internal metrics",
splunkericl marked this conversation as resolved.
Show resolved Hide resolved
Enabled: configtelemetry.UseOpenTelemetryForInternalMetrics,
bogdandrutu marked this conversation as resolved.
Show resolved Hide resolved
})
}

type collectorTelemetryExporter interface {
init(col *Collector) error
shutdown() error
Expand Down Expand Up @@ -98,7 +112,7 @@ func (tel *colTelemetry) initOnce(col *Collector) error {
instanceID := instanceUUID.String()

var pe http.Handler
if configtelemetry.UseOpenTelemetryForInternalMetrics {
if featuregate.IsEnabled(useOtelForInternalMetricsfeatureGateID) {
bogdandrutu marked this conversation as resolved.
Show resolved Hide resolved
otelHandler, err := tel.initOpenTelemetry()
if err != nil {
return err
Expand Down