Skip to content

Commit 6b7054d

Browse files
committed
poc(ddtrace/tracer): migrate partialFlushMinSpans & partialFlushEnabled
1 parent 522fd00 commit 6b7054d

File tree

4 files changed

+61
-44
lines changed

4 files changed

+61
-44
lines changed

ddtrace/tracer/log.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
2020
"gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo"
2121
"gopkg.in/DataDog/dd-trace-go.v1/internal/version"
22+
23+
"github.com/darccio/knobs"
2224
)
2325

2426
// startupInfo contains various information about the status of the tracer on startup.
@@ -141,8 +143,8 @@ func logStartup(t *tracer) {
141143
AgentFeatures: t.config.agent,
142144
Integrations: t.config.integrations,
143145
AppSec: appsec.Enabled(),
144-
PartialFlushEnabled: t.config.partialFlushEnabled,
145-
PartialFlushMinSpans: t.config.partialFlushMinSpans,
146+
PartialFlushEnabled: knobs.GetScope(t.config.Scope, partialFlushEnabled),
147+
PartialFlushMinSpans: knobs.GetScope(t.config.Scope, partialFlushMinSpans),
146148
Orchestrion: t.config.orchestrionCfg,
147149
FeatureFlags: featureFlags,
148150
PropagationStyleInject: injectorNames,

ddtrace/tracer/option.go

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"gopkg.in/DataDog/dd-trace-go.v1/internal/version"
3838

3939
"github.com/DataDog/datadog-go/v5/statsd"
40+
"github.com/darccio/knobs"
4041
)
4142

4243
var contribIntegrations = map[string]struct {
@@ -115,6 +116,8 @@ var (
115116

116117
// config holds the tracer configuration.
117118
type config struct {
119+
*knobs.Scope
120+
118121
// debug, when true, writes details to logs.
119122
debug bool
120123

@@ -252,15 +255,6 @@ type config struct {
252255
// misconfiguration
253256
spanTimeout time.Duration
254257

255-
// partialFlushMinSpans is the number of finished spans in a single trace to trigger a
256-
// partial flush, or 0 if partial flushing is disabled.
257-
// Value from DD_TRACE_PARTIAL_FLUSH_MIN_SPANS, default 1000.
258-
partialFlushMinSpans int
259-
260-
// partialFlushEnabled specifices whether the tracer should enable partial flushing. Value
261-
// from DD_TRACE_PARTIAL_FLUSH_ENABLED, default false.
262-
partialFlushEnabled bool
263-
264258
// statsComputationEnabled enables client-side stats computation (aka trace metrics).
265259
statsComputationEnabled bool
266260

@@ -297,6 +291,39 @@ type config struct {
297291
logDirectory string
298292
}
299293

294+
var (
295+
// partialFlushEnabled specifices whether the tracer should enable partial flushing. Value
296+
// from DD_TRACE_PARTIAL_FLUSH_ENABLED, default false.
297+
partialFlushEnabled = knobs.Register(&knobs.Definition[bool]{
298+
Default: false,
299+
EnvVars: []knobs.EnvVar{{Key: "DD_TRACE_PARTIAL_FLUSH_ENABLED"}},
300+
Parse: knobs.ToBool,
301+
})
302+
303+
// partialFlushMinSpans is the number of finished spans in a single trace to trigger a
304+
// partial flush, or 0 if partial flushing is disabled.
305+
// Value from DD_TRACE_PARTIAL_FLUSH_MIN_SPANS, default 1000.
306+
partialFlushMinSpans = knobs.Register(&knobs.Definition[int]{
307+
// TODO(partialFlush): consider logging a warning if DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
308+
// is set, but DD_TRACE_PARTIAL_FLUSH_ENABLED is not true. Or just assume it should be enabled
309+
// if it's explicitly set, and don't require both variables to be configured.
310+
Default: 1000,
311+
EnvVars: []knobs.EnvVar{{Key: "DD_TRACE_PARTIAL_FLUSH_MIN_SPANS"}},
312+
Requires: []any{partialFlushEnabled},
313+
Parse: func(v string) (int, error) {
314+
i, _ := strconv.Atoi(v)
315+
if i <= 0 {
316+
log.Warn("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS=%d is not a valid value, setting to default %d", i, 1000)
317+
return 0, knobs.ErrInvalidValue
318+
} else if i >= traceMaxSize {
319+
log.Warn("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS=%d is above the max number of spans that can be kept in memory for a single trace (%d spans), so partial flushing will never trigger, setting to default %d", i, traceMaxSize, 1000)
320+
return 0, knobs.ErrInvalidValue
321+
}
322+
return i, nil
323+
},
324+
})
325+
)
326+
300327
// orchestrionConfig contains Orchestrion configuration.
301328
type orchestrionConfig struct {
302329
// Enabled indicates whether this tracer was instanciated via Orchestrion.
@@ -318,13 +345,11 @@ type StartOption func(*config)
318345
// maxPropagatedTagsLength limits the size of DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH to prevent HTTP 413 responses.
319346
const maxPropagatedTagsLength = 512
320347

321-
// partialFlushMinSpansDefault is the default number of spans for partial flushing, if enabled.
322-
const partialFlushMinSpansDefault = 1000
323-
324348
// newConfig renders the tracer configuration based on defaults, environment variables
325349
// and passed user opts.
326350
func newConfig(opts ...StartOption) *config {
327351
c := new(config)
352+
c.Scope = knobs.NewScope()
328353
c.sampler = NewAllSampler()
329354
sampleRate := math.NaN()
330355
if r := getDDorOtelConfig("sampleRate"); r != "" {
@@ -419,19 +444,6 @@ func newConfig(opts ...StartOption) *config {
419444
}
420445
c.statsComputationEnabled = internal.BoolEnv("DD_TRACE_STATS_COMPUTATION_ENABLED", false)
421446
c.dataStreamsMonitoringEnabled = internal.BoolEnv("DD_DATA_STREAMS_ENABLED", false)
422-
c.partialFlushEnabled = internal.BoolEnv("DD_TRACE_PARTIAL_FLUSH_ENABLED", false)
423-
c.partialFlushMinSpans = internal.IntEnv("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS", partialFlushMinSpansDefault)
424-
if c.partialFlushMinSpans <= 0 {
425-
log.Warn("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS=%d is not a valid value, setting to default %d", c.partialFlushMinSpans, partialFlushMinSpansDefault)
426-
c.partialFlushMinSpans = partialFlushMinSpansDefault
427-
} else if c.partialFlushMinSpans >= traceMaxSize {
428-
log.Warn("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS=%d is above the max number of spans that can be kept in memory for a single trace (%d spans), so partial flushing will never trigger, setting to default %d", c.partialFlushMinSpans, traceMaxSize, partialFlushMinSpansDefault)
429-
c.partialFlushMinSpans = partialFlushMinSpansDefault
430-
}
431-
// TODO(partialFlush): consider logging a warning if DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
432-
// is set, but DD_TRACE_PARTIAL_FLUSH_ENABLED is not true. Or just assume it should be enabled
433-
// if it's explicitly set, and don't require both variables to be configured.
434-
435447
c.dynamicInstrumentationEnabled = internal.BoolEnv("DD_DYNAMIC_INSTRUMENTATION_ENABLED", false)
436448

437449
schemaVersionStr := os.Getenv("DD_TRACE_SPAN_ATTRIBUTE_SCHEMA")
@@ -1192,8 +1204,8 @@ func WithDebugSpansMode(timeout time.Duration) StartOption {
11921204
// is disabled by default.
11931205
func WithPartialFlushing(numSpans int) StartOption {
11941206
return func(c *config) {
1195-
c.partialFlushEnabled = true
1196-
c.partialFlushMinSpans = numSpans
1207+
knobs.SetScope(c.Scope, partialFlushEnabled, knobs.Code, true)
1208+
knobs.SetScope(c.Scope, partialFlushMinSpans, knobs.Code, numSpans)
11971209
}
11981210
}
11991211

ddtrace/tracer/option_test.go

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof"
3535
"gopkg.in/DataDog/dd-trace-go.v1/internal/version"
3636

37+
"github.com/darccio/knobs"
3738
"github.com/stretchr/testify/assert"
3839
"github.com/stretchr/testify/require"
3940
)
@@ -1506,46 +1507,46 @@ func TestHostnameDisabled(t *testing.T) {
15061507
func TestPartialFlushing(t *testing.T) {
15071508
t.Run("None", func(t *testing.T) {
15081509
c := newConfig()
1509-
assert.False(t, c.partialFlushEnabled)
1510-
assert.Equal(t, partialFlushMinSpansDefault, c.partialFlushMinSpans)
1510+
assert.False(t, knobs.GetScope(c.Scope, partialFlushEnabled))
1511+
assert.Equal(t, 1000, knobs.GetScope(c.Scope, partialFlushMinSpans))
15111512
})
15121513
t.Run("Disabled-DefaultMinSpans", func(t *testing.T) {
15131514
t.Setenv("DD_TRACE_PARTIAL_FLUSH_ENABLED", "false")
15141515
c := newConfig()
1515-
assert.False(t, c.partialFlushEnabled)
1516-
assert.Equal(t, partialFlushMinSpansDefault, c.partialFlushMinSpans)
1516+
assert.False(t, knobs.GetScope(c.Scope, partialFlushEnabled))
1517+
assert.Equal(t, 1000, knobs.GetScope(c.Scope, partialFlushMinSpans))
15171518
})
15181519
t.Run("Default-SetMinSpans", func(t *testing.T) {
15191520
t.Setenv("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS", "10")
15201521
c := newConfig()
1521-
assert.False(t, c.partialFlushEnabled)
1522-
assert.Equal(t, 10, c.partialFlushMinSpans)
1522+
assert.False(t, knobs.GetScope(c.Scope, partialFlushEnabled))
1523+
assert.Equal(t, 10, knobs.GetScope(c.Scope, partialFlushMinSpans))
15231524
})
15241525
t.Run("Enabled-DefaultMinSpans", func(t *testing.T) {
15251526
t.Setenv("DD_TRACE_PARTIAL_FLUSH_ENABLED", "true")
15261527
c := newConfig()
1527-
assert.True(t, c.partialFlushEnabled)
1528-
assert.Equal(t, partialFlushMinSpansDefault, c.partialFlushMinSpans)
1528+
assert.True(t, knobs.GetScope(c.Scope, partialFlushEnabled))
1529+
assert.Equal(t, 1000, knobs.GetScope(c.Scope, partialFlushMinSpans))
15291530
})
15301531
t.Run("Enabled-SetMinSpans", func(t *testing.T) {
15311532
t.Setenv("DD_TRACE_PARTIAL_FLUSH_ENABLED", "true")
15321533
t.Setenv("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS", "10")
15331534
c := newConfig()
1534-
assert.True(t, c.partialFlushEnabled)
1535-
assert.Equal(t, 10, c.partialFlushMinSpans)
1535+
assert.True(t, knobs.GetScope(c.Scope, partialFlushEnabled))
1536+
assert.Equal(t, 10, knobs.GetScope(c.Scope, partialFlushMinSpans))
15361537
})
15371538
t.Run("Enabled-SetMinSpansNegative", func(t *testing.T) {
15381539
t.Setenv("DD_TRACE_PARTIAL_FLUSH_ENABLED", "true")
15391540
t.Setenv("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS", "-1")
15401541
c := newConfig()
1541-
assert.True(t, c.partialFlushEnabled)
1542-
assert.Equal(t, partialFlushMinSpansDefault, c.partialFlushMinSpans)
1542+
assert.True(t, knobs.GetScope(c.Scope, partialFlushEnabled))
1543+
assert.Equal(t, 1000, knobs.GetScope(c.Scope, partialFlushMinSpans))
15431544
})
15441545
t.Run("WithPartialFlushOption", func(t *testing.T) {
15451546
c := newConfig()
15461547
WithPartialFlushing(20)(c)
1547-
assert.True(t, c.partialFlushEnabled)
1548-
assert.Equal(t, 20, c.partialFlushMinSpans)
1548+
assert.True(t, knobs.GetScope(c.Scope, partialFlushEnabled))
1549+
assert.Equal(t, 20, knobs.GetScope(c.Scope, partialFlushMinSpans))
15491550
})
15501551
}
15511552

ddtrace/tracer/spancontext.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import (
2323
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
2424
"gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames"
2525
"gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry"
26+
27+
"github.com/darccio/knobs"
2628
)
2729

2830
var _ ddtrace.SpanContext = (*spanContext)(nil)
@@ -499,7 +501,7 @@ func (t *trace) finishedOne(s *span) {
499501
return
500502
}
501503

502-
doPartialFlush := tr.config.partialFlushEnabled && t.finished >= tr.config.partialFlushMinSpans
504+
doPartialFlush := knobs.GetScope(tr.config.Scope, partialFlushEnabled) && t.finished >= knobs.GetScope(tr.config.Scope, partialFlushMinSpans)
503505
if !doPartialFlush {
504506
return // The trace hasn't completed and partial flushing will not occur
505507
}

0 commit comments

Comments
 (0)