Skip to content

Commit e7f6893

Browse files
committed
poc(ddtrace/tracer): migrate enabled (RC)
1 parent 34f6128 commit e7f6893

File tree

7 files changed

+64
-30
lines changed

7 files changed

+64
-30
lines changed

ddtrace/tracer/option.go

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ var (
119119
type config struct {
120120
*knobs.Scope
121121

122+
dynamic struct {
123+
// enabled reports whether tracing is enabled.
124+
enabled dynamicConfig[bool]
125+
}
122126

123127
// debug, when true, writes details to logs.
124128
debug bool
@@ -235,9 +239,6 @@ type config struct {
235239
// profilerEndpoints specifies whether profiler endpoint filtering is enabled.
236240
profilerEndpoints bool
237241

238-
// enabled reports whether tracing is enabled.
239-
enabled dynamicConfig[bool]
240-
241242
// enableHostnameDetection specifies whether the tracer should enable hostname detection.
242243
enableHostnameDetection bool
243244

@@ -295,6 +296,26 @@ var (
295296
)
296297

297298
var (
299+
enabled = knobs.Register(&knobs.Definition[bool]{
300+
Default: true,
301+
EnvVars: []knobs.EnvVar{
302+
{
303+
Key: "DD_TRACE_ENABLED",
304+
},
305+
{
306+
Key: "OTEL_TRACES_EXPORTER",
307+
Transform: mapEnabled,
308+
},
309+
},
310+
Parse: func(s string) (bool, error) {
311+
if s == "" {
312+
// Short-circuit if the value is empty, to avoid parsing errors.
313+
return true, nil
314+
}
315+
return strconv.ParseBool(s)
316+
},
317+
})
318+
298319
// globalSampleRate holds sample rate read from environment variables.
299320
globalSampleRate = knobs.Register(&knobs.Definition[float64]{
300321
Default: math.NaN(),
@@ -450,9 +471,10 @@ func newConfig(opts ...StartOption) *config {
450471
c.runtimeMetricsV2 = internal.BoolEnv("DD_RUNTIME_METRICS_V2_ENABLED", false)
451472
c.debug = internal.BoolVal(getDDorOtelConfig("debugMode"), false)
452473
c.logDirectory = os.Getenv("DD_TRACE_LOG_DIRECTORY")
453-
c.enabled = newDynamicConfig("tracing_enabled", internal.BoolVal(getDDorOtelConfig("enabled"), true), func(b bool) bool { return true }, equal[bool])
474+
c.dynamic.enabled = newDynamicConfig("tracing_enabled", knobs.GetScope(c.Scope, enabled), func(b bool) bool { knobs.SetScope(c.Scope, enabled, knobs.Code, b); return true }, equal[bool])
454475
if _, ok := os.LookupEnv("DD_TRACE_ENABLED"); ok {
455-
c.enabled.cfgOrigin = telemetry.OriginEnvVar
476+
// TODO: shouldn't we track this for the OTEL_TRACES_EXPORTER case?
477+
c.dynamic.enabled.cfgOrigin = telemetry.OriginEnvVar
456478
}
457479
c.profilerEndpoints = internal.BoolEnv(traceprof.EndpointEnvVar, true)
458480
c.profilerHotspots = internal.BoolEnv(traceprof.CodeHotspotsEnvVar, true)
@@ -567,7 +589,7 @@ func newConfig(opts ...StartOption) *config {
567589
log.SetLevel(log.LevelDebug)
568590
}
569591
// if using stdout or traces are disabled, agent is disabled
570-
agentDisabled := c.logToStdout || !c.enabled.current
592+
agentDisabled := c.logToStdout || !knobs.GetScope(c.Scope, enabled)
571593
c.agent = loadAgentFeatures(agentDisabled, c.agentURL, c.httpClient)
572594
info, ok := debug.ReadBuildInfo()
573595
if !ok {
@@ -1169,7 +1191,7 @@ func WithHostname(name string) StartOption {
11691191
// WithTraceEnabled allows specifying whether tracing will be enabled
11701192
func WithTraceEnabled(enabled bool) StartOption {
11711193
return func(c *config) {
1172-
c.enabled = newDynamicConfig("tracing_enabled", enabled, func(b bool) bool { return true }, equal[bool])
1194+
c.dynamic.enabled.update(enabled, telemetry.OriginCode)
11731195
}
11741196
}
11751197

ddtrace/tracer/option_test.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -637,17 +637,19 @@ func TestTracerOptionsDefaults(t *testing.T) {
637637
tracer := newTracer(WithAgentTimeout(2))
638638
defer tracer.Stop()
639639
c := tracer.config
640-
assert.True(t, c.enabled.current)
641-
assert.Equal(t, c.enabled.cfgOrigin, telemetry.OriginDefault)
640+
assert.True(t, c.dynamic.enabled.current)
641+
assert.True(t, knobs.GetScope(c.Scope, enabled))
642+
assert.Equal(t, c.dynamic.enabled.cfgOrigin, telemetry.OriginDefault)
642643
})
643644

644645
t.Run("override", func(t *testing.T) {
645646
t.Setenv("DD_TRACE_ENABLED", "false")
646647
tracer := newTracer(WithAgentTimeout(2))
647648
defer tracer.Stop()
648649
c := tracer.config
649-
assert.False(t, c.enabled.current)
650-
assert.Equal(t, c.enabled.cfgOrigin, telemetry.OriginEnvVar)
650+
assert.False(t, c.dynamic.enabled.current)
651+
assert.False(t, knobs.GetScope(c.Scope, enabled))
652+
assert.Equal(t, c.dynamic.enabled.cfgOrigin, telemetry.OriginEnvVar)
651653
})
652654
})
653655

@@ -1365,21 +1367,24 @@ func TestWithTraceEnabled(t *testing.T) {
13651367
t.Run("WithTraceEnabled", func(t *testing.T) {
13661368
assert := assert.New(t)
13671369
c := newConfig(WithTraceEnabled(false))
1368-
assert.False(c.enabled.current)
1370+
assert.False(c.dynamic.enabled.current)
1371+
assert.False(knobs.GetScope(c.Scope, enabled))
13691372
})
13701373

13711374
t.Run("otel-env", func(t *testing.T) {
13721375
assert := assert.New(t)
13731376
t.Setenv("OTEL_TRACES_EXPORTER", "none")
13741377
c := newConfig()
1375-
assert.False(c.enabled.current)
1378+
assert.False(c.dynamic.enabled.current)
1379+
assert.False(knobs.GetScope(c.Scope, enabled))
13761380
})
13771381

13781382
t.Run("dd-env", func(t *testing.T) {
13791383
assert := assert.New(t)
13801384
t.Setenv("DD_TRACE_ENABLED", "false")
13811385
c := newConfig()
1382-
assert.False(c.enabled.current)
1386+
assert.False(c.dynamic.enabled.current)
1387+
assert.False(knobs.GetScope(c.Scope, enabled))
13831388
})
13841389

13851390
t.Run("override-chain", func(t *testing.T) {
@@ -1388,10 +1393,12 @@ func TestWithTraceEnabled(t *testing.T) {
13881393
t.Setenv("OTEL_TRACES_EXPORTER", "none")
13891394
t.Setenv("DD_TRACE_ENABLED", "true")
13901395
c := newConfig()
1391-
assert.True(c.enabled.current)
1396+
assert.True(c.dynamic.enabled.current)
1397+
assert.True(knobs.GetScope(c.Scope, enabled))
13921398
// tracer option overrides dd env
13931399
c = newConfig(WithTraceEnabled(false))
1394-
assert.False(c.enabled.current)
1400+
assert.False(c.dynamic.enabled.current)
1401+
assert.False(knobs.GetScope(c.Scope, enabled))
13951402
})
13961403
}
13971404

ddtrace/tracer/remote_config.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ func (t *tracer) onRemoteConfigUpdate(u remoteconfig.ProductUpdate) map[string]s
181181
if updated {
182182
telemConfigs = append(telemConfigs, t.config.globalTags.toTelemetry())
183183
}
184-
if !t.config.enabled.current {
184+
if !t.config.dynamic.enabled.current {
185185
log.Debug("APM Tracing is disabled. Restart the service to enable it.")
186186
}
187187
if len(telemConfigs) > 0 {
@@ -233,11 +233,11 @@ func (t *tracer) onRemoteConfigUpdate(u remoteconfig.ProductUpdate) map[string]s
233233
telemConfigs = append(telemConfigs, t.config.globalTags.toTelemetry())
234234
}
235235
if c.LibConfig.Enabled != nil {
236-
if t.config.enabled.current == true && *c.LibConfig.Enabled == false {
236+
if t.config.dynamic.enabled.current == true && *c.LibConfig.Enabled == false {
237237
log.Debug("Disabled APM Tracing through RC. Restart the service to enable it.")
238-
t.config.enabled.handleRC(c.LibConfig.Enabled)
239-
telemConfigs = append(telemConfigs, t.config.enabled.toTelemetry())
240-
} else if t.config.enabled.current == false && *c.LibConfig.Enabled == true {
238+
t.config.dynamic.enabled.handleRC(c.LibConfig.Enabled)
239+
telemConfigs = append(telemConfigs, t.config.dynamic.enabled.toTelemetry())
240+
} else if t.config.dynamic.enabled.current == false && *c.LibConfig.Enabled == true {
241241
log.Debug("APM Tracing is disabled. Restart the service to enable it.")
242242
}
243243
}

ddtrace/tracer/remote_config_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/telemetrytest"
1919

2020
"github.com/DataDog/datadog-agent/pkg/remoteconfig/state"
21+
"github.com/darccio/knobs"
2122
"github.com/stretchr/testify/assert"
2223
"github.com/stretchr/testify/require"
2324
)
@@ -395,7 +396,7 @@ func TestOnRemoteConfigUpdate(t *testing.T) {
395396

396397
applyStatus := tr.onRemoteConfigUpdate(input)
397398
require.Equal(t, state.ApplyStateAcknowledged, applyStatus["path"].State)
398-
require.Equal(t, false, tr.config.enabled.current)
399+
require.Equal(t, false, tr.config.dynamic.enabled.current)
399400
headers := TextMapCarrier{
400401
traceparentHeader: "00-12345678901234567890123456789012-1234567890123456-01",
401402
tracestateHeader: "dd=s:2;o:rum;t.usr.id:baz64~~",
@@ -417,7 +418,7 @@ func TestOnRemoteConfigUpdate(t *testing.T) {
417418
input = remoteconfig.ProductUpdate{"path": nil}
418419
applyStatus = tr.onRemoteConfigUpdate(input)
419420
require.Equal(t, state.ApplyStateAcknowledged, applyStatus["path"].State)
420-
require.Equal(t, false, tr.config.enabled.current)
421+
require.Equal(t, false, knobs.GetScope(tr.config.Scope, enabled))
421422

422423
// turning tracing back explicitly is not allowed
423424
input = remoteconfig.ProductUpdate{
@@ -427,7 +428,8 @@ func TestOnRemoteConfigUpdate(t *testing.T) {
427428
}
428429
applyStatus = tr.onRemoteConfigUpdate(input)
429430
require.Equal(t, state.ApplyStateAcknowledged, applyStatus["path"].State)
430-
require.Equal(t, false, tr.config.enabled.current)
431+
require.Equal(t, false, tr.config.dynamic.enabled.current)
432+
require.Equal(t, false, knobs.GetScope(tr.config.Scope, enabled))
431433

432434
telemetryClient.AssertNumberOfCalls(t, "ConfigChange", 1)
433435
})

ddtrace/tracer/span.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames"
3333
"gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof"
3434

35+
"github.com/darccio/knobs"
3536
"github.com/tinylib/msgp/msgp"
3637
"golang.org/x/xerrors"
3738

@@ -548,7 +549,7 @@ func (s *span) finish(finishTime int64) {
548549

549550
keep := true
550551
if t, ok := internal.GetGlobalTracer().(*tracer); ok {
551-
if !t.config.enabled.current {
552+
if !knobs.GetScope(t.config.Scope, enabled) {
552553
return
553554
}
554555
// we have an active tracer

ddtrace/tracer/telemetry.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"strings"
1111

1212
"gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry"
13+
14+
"github.com/darccio/knobs"
1315
)
1416

1517
var additionalConfigs []telemetry.Configuration
@@ -63,7 +65,7 @@ func startTelemetry(c *config) {
6365
{Name: "trace_span_attribute_schema", Value: c.spanAttributeSchemaVersion},
6466
{Name: "trace_peer_service_defaults_enabled", Value: c.peerServiceDefaultsEnabled},
6567
{Name: "orchestrion_enabled", Value: c.orchestrionCfg.Enabled},
66-
{Name: "trace_enabled", Value: c.enabled.current, Origin: c.enabled.cfgOrigin},
68+
{Name: "trace_enabled", Value: knobs.GetScope(c.Scope, enabled), Origin: c.dynamic.enabled.cfgOrigin},
6769
{Name: "trace_log_directory", Value: c.logDirectory},
6870
c.traceSampleRate.toTelemetry(),
6971
c.headerAsTags.toTelemetry(),

ddtrace/tracer/tracer.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ func Start(opts ...StartOption) {
152152
}
153153
defer telemetry.Time(telemetry.NamespaceGeneral, "init_time", nil, true)()
154154
t := newTracer(opts...)
155-
if !t.config.enabled.current {
155+
if !knobs.GetScope(t.config.Scope, enabled) {
156156
// TODO: instrumentation telemetry client won't get started
157157
// if tracing is disabled, but we still want to capture this
158158
// telemetry information. Will be fixed when the tracer and profiler
@@ -500,7 +500,7 @@ func (t *tracer) pushChunk(trace *chunk) {
500500

501501
// StartSpan creates, starts, and returns a new Span with the given `operationName`.
502502
func (t *tracer) StartSpan(operationName string, options ...ddtrace.StartSpanOption) ddtrace.Span {
503-
if !t.config.enabled.current {
503+
if !knobs.GetScope(t.config.Scope, enabled) {
504504
return internal.NoopSpan{}
505505
}
506506
var opts ddtrace.StartSpanConfig
@@ -716,7 +716,7 @@ func (t *tracer) Stop() {
716716

717717
// Inject uses the configured or default TextMap Propagator.
718718
func (t *tracer) Inject(ctx ddtrace.SpanContext, carrier interface{}) error {
719-
if !t.config.enabled.current {
719+
if !knobs.GetScope(t.config.Scope, enabled) {
720720
return nil
721721
}
722722
t.updateSampling(ctx)
@@ -755,7 +755,7 @@ func (t *tracer) updateSampling(ctx ddtrace.SpanContext) {
755755

756756
// Extract uses the configured or default TextMap Propagator.
757757
func (t *tracer) Extract(carrier interface{}) (ddtrace.SpanContext, error) {
758-
if !t.config.enabled.current {
758+
if !knobs.GetScope(t.config.Scope, enabled) {
759759
return internal.NoopSpanContext{}, nil
760760
}
761761
return t.config.propagator.Extract(carrier)

0 commit comments

Comments
 (0)