Skip to content

Commit

Permalink
poc(ddtrace/tracer): migrate partialFlushMinSpans & partialFlushEnabl…
Browse files Browse the repository at this point in the history
…ed to knobs
  • Loading branch information
darccio committed Dec 12, 2024
1 parent 79a1f60 commit 589085a
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 44 deletions.
6 changes: 4 additions & 2 deletions ddtrace/tracer/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
"gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo"
"gopkg.in/DataDog/dd-trace-go.v1/internal/version"

"github.com/darccio/knobs"
)

// startupInfo contains various information about the status of the tracer on startup.
Expand Down Expand Up @@ -141,8 +143,8 @@ func logStartup(t *tracer) {
AgentFeatures: t.config.agent,
Integrations: t.config.integrations,
AppSec: appsec.Enabled(),
PartialFlushEnabled: t.config.partialFlushEnabled,
PartialFlushMinSpans: t.config.partialFlushMinSpans,
PartialFlushEnabled: knobs.GetScope(t.config.Scope, partialFlushEnabled),
PartialFlushMinSpans: knobs.GetScope(t.config.Scope, partialFlushMinSpans),
Orchestrion: t.config.orchestrionCfg,
FeatureFlags: featureFlags,
PropagationStyleInject: injectorNames,
Expand Down
66 changes: 39 additions & 27 deletions ddtrace/tracer/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"gopkg.in/DataDog/dd-trace-go.v1/internal/version"

"github.com/DataDog/datadog-go/v5/statsd"
"github.com/darccio/knobs"
)

var contribIntegrations = map[string]struct {
Expand Down Expand Up @@ -115,6 +116,8 @@ var (

// config holds the tracer configuration.
type config struct {
*knobs.Scope

// debug, when true, writes details to logs.
debug bool

Expand Down Expand Up @@ -252,15 +255,6 @@ type config struct {
// misconfiguration
spanTimeout time.Duration

// partialFlushMinSpans is the number of finished spans in a single trace to trigger a
// partial flush, or 0 if partial flushing is disabled.
// Value from DD_TRACE_PARTIAL_FLUSH_MIN_SPANS, default 1000.
partialFlushMinSpans int

// partialFlushEnabled specifices whether the tracer should enable partial flushing. Value
// from DD_TRACE_PARTIAL_FLUSH_ENABLED, default false.
partialFlushEnabled bool

// statsComputationEnabled enables client-side stats computation (aka trace metrics).
statsComputationEnabled bool

Expand Down Expand Up @@ -297,6 +291,39 @@ type config struct {
logDirectory string
}

var (
// partialFlushEnabled specifices whether the tracer should enable partial flushing. Value
// from DD_TRACE_PARTIAL_FLUSH_ENABLED, default false.
partialFlushEnabled = knobs.Register(&knobs.Definition[bool]{
Default: false,
EnvVars: []knobs.EnvVar{{Key: "DD_TRACE_PARTIAL_FLUSH_ENABLED"}},
Parse: knobs.ToBool,
})

// partialFlushMinSpans is the number of finished spans in a single trace to trigger a
// partial flush, or 0 if partial flushing is disabled.
// Value from DD_TRACE_PARTIAL_FLUSH_MIN_SPANS, default 1000.
partialFlushMinSpans = knobs.Register(&knobs.Definition[int]{
// TODO(partialFlush): consider logging a warning if DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
// is set, but DD_TRACE_PARTIAL_FLUSH_ENABLED is not true. Or just assume it should be enabled
// if it's explicitly set, and don't require both variables to be configured.
Default: 1000,
EnvVars: []knobs.EnvVar{{Key: "DD_TRACE_PARTIAL_FLUSH_MIN_SPANS"}},
Requires: []any{partialFlushEnabled},
Parse: func(v string) (int, error) {
i, _ := strconv.Atoi(v)
if i <= 0 {
log.Warn("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS=%d is not a valid value, setting to default %d", i, 1000)
return 0, knobs.ErrInvalidValue
} else if i >= traceMaxSize {
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)
return 0, knobs.ErrInvalidValue
}
return i, nil
},
})
)

// orchestrionConfig contains Orchestrion configuration.
type orchestrionConfig struct {
// Enabled indicates whether this tracer was instanciated via Orchestrion.
Expand All @@ -318,13 +345,11 @@ type StartOption func(*config)
// maxPropagatedTagsLength limits the size of DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH to prevent HTTP 413 responses.
const maxPropagatedTagsLength = 512

// partialFlushMinSpansDefault is the default number of spans for partial flushing, if enabled.
const partialFlushMinSpansDefault = 1000

// newConfig renders the tracer configuration based on defaults, environment variables
// and passed user opts.
func newConfig(opts ...StartOption) *config {
c := new(config)
c.Scope = knobs.NewScope()
c.sampler = NewAllSampler()
sampleRate := math.NaN()
if r := getDDorOtelConfig("sampleRate"); r != "" {
Expand Down Expand Up @@ -419,19 +444,6 @@ func newConfig(opts ...StartOption) *config {
}
c.statsComputationEnabled = internal.BoolEnv("DD_TRACE_STATS_COMPUTATION_ENABLED", false)
c.dataStreamsMonitoringEnabled = internal.BoolEnv("DD_DATA_STREAMS_ENABLED", false)
c.partialFlushEnabled = internal.BoolEnv("DD_TRACE_PARTIAL_FLUSH_ENABLED", false)
c.partialFlushMinSpans = internal.IntEnv("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS", partialFlushMinSpansDefault)
if c.partialFlushMinSpans <= 0 {
log.Warn("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS=%d is not a valid value, setting to default %d", c.partialFlushMinSpans, partialFlushMinSpansDefault)
c.partialFlushMinSpans = partialFlushMinSpansDefault
} else if c.partialFlushMinSpans >= traceMaxSize {
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)
c.partialFlushMinSpans = partialFlushMinSpansDefault
}
// TODO(partialFlush): consider logging a warning if DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
// is set, but DD_TRACE_PARTIAL_FLUSH_ENABLED is not true. Or just assume it should be enabled
// if it's explicitly set, and don't require both variables to be configured.

c.dynamicInstrumentationEnabled = internal.BoolEnv("DD_DYNAMIC_INSTRUMENTATION_ENABLED", false)

schemaVersionStr := os.Getenv("DD_TRACE_SPAN_ATTRIBUTE_SCHEMA")
Expand Down Expand Up @@ -1192,8 +1204,8 @@ func WithDebugSpansMode(timeout time.Duration) StartOption {
// is disabled by default.
func WithPartialFlushing(numSpans int) StartOption {
return func(c *config) {
c.partialFlushEnabled = true
c.partialFlushMinSpans = numSpans
knobs.SetScope(c.Scope, partialFlushEnabled, knobs.Code, true)
knobs.SetScope(c.Scope, partialFlushMinSpans, knobs.Code, numSpans)
}
}

Expand Down
29 changes: 15 additions & 14 deletions ddtrace/tracer/option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof"
"gopkg.in/DataDog/dd-trace-go.v1/internal/version"

"github.com/darccio/knobs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -1506,46 +1507,46 @@ func TestHostnameDisabled(t *testing.T) {
func TestPartialFlushing(t *testing.T) {
t.Run("None", func(t *testing.T) {
c := newConfig()
assert.False(t, c.partialFlushEnabled)
assert.Equal(t, partialFlushMinSpansDefault, c.partialFlushMinSpans)
assert.False(t, knobs.GetScope(c.Scope, partialFlushEnabled))
assert.Equal(t, 1000, knobs.GetScope(c.Scope, partialFlushMinSpans))
})
t.Run("Disabled-DefaultMinSpans", func(t *testing.T) {
t.Setenv("DD_TRACE_PARTIAL_FLUSH_ENABLED", "false")
c := newConfig()
assert.False(t, c.partialFlushEnabled)
assert.Equal(t, partialFlushMinSpansDefault, c.partialFlushMinSpans)
assert.False(t, knobs.GetScope(c.Scope, partialFlushEnabled))
assert.Equal(t, 1000, knobs.GetScope(c.Scope, partialFlushMinSpans))
})
t.Run("Default-SetMinSpans", func(t *testing.T) {
t.Setenv("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS", "10")
c := newConfig()
assert.False(t, c.partialFlushEnabled)
assert.Equal(t, 10, c.partialFlushMinSpans)
assert.False(t, knobs.GetScope(c.Scope, partialFlushEnabled))
assert.Equal(t, 10, knobs.GetScope(c.Scope, partialFlushMinSpans))
})
t.Run("Enabled-DefaultMinSpans", func(t *testing.T) {
t.Setenv("DD_TRACE_PARTIAL_FLUSH_ENABLED", "true")
c := newConfig()
assert.True(t, c.partialFlushEnabled)
assert.Equal(t, partialFlushMinSpansDefault, c.partialFlushMinSpans)
assert.True(t, knobs.GetScope(c.Scope, partialFlushEnabled))
assert.Equal(t, 1000, knobs.GetScope(c.Scope, partialFlushMinSpans))
})
t.Run("Enabled-SetMinSpans", func(t *testing.T) {
t.Setenv("DD_TRACE_PARTIAL_FLUSH_ENABLED", "true")
t.Setenv("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS", "10")
c := newConfig()
assert.True(t, c.partialFlushEnabled)
assert.Equal(t, 10, c.partialFlushMinSpans)
assert.True(t, knobs.GetScope(c.Scope, partialFlushEnabled))
assert.Equal(t, 10, knobs.GetScope(c.Scope, partialFlushMinSpans))
})
t.Run("Enabled-SetMinSpansNegative", func(t *testing.T) {
t.Setenv("DD_TRACE_PARTIAL_FLUSH_ENABLED", "true")
t.Setenv("DD_TRACE_PARTIAL_FLUSH_MIN_SPANS", "-1")
c := newConfig()
assert.True(t, c.partialFlushEnabled)
assert.Equal(t, partialFlushMinSpansDefault, c.partialFlushMinSpans)
assert.True(t, knobs.GetScope(c.Scope, partialFlushEnabled))
assert.Equal(t, 1000, knobs.GetScope(c.Scope, partialFlushMinSpans))
})
t.Run("WithPartialFlushOption", func(t *testing.T) {
c := newConfig()
WithPartialFlushing(20)(c)
assert.True(t, c.partialFlushEnabled)
assert.Equal(t, 20, c.partialFlushMinSpans)
assert.True(t, knobs.GetScope(c.Scope, partialFlushEnabled))
assert.Equal(t, 20, knobs.GetScope(c.Scope, partialFlushMinSpans))
})
}

Expand Down
4 changes: 3 additions & 1 deletion ddtrace/tracer/spancontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
"gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames"
"gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry"

"github.com/darccio/knobs"
)

var _ ddtrace.SpanContext = (*spanContext)(nil)
Expand Down Expand Up @@ -499,7 +501,7 @@ func (t *trace) finishedOne(s *span) {
return
}

doPartialFlush := tr.config.partialFlushEnabled && t.finished >= tr.config.partialFlushMinSpans
doPartialFlush := knobs.GetScope(tr.config.Scope, partialFlushEnabled) && t.finished >= knobs.GetScope(tr.config.Scope, partialFlushMinSpans)
if !doPartialFlush {
return // The trace hasn't completed and partial flushing will not occur
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ require (
github.com/bradfitz/gomemcache v0.0.0-20230611145640-acc696258285
github.com/confluentinc/confluent-kafka-go v1.9.2
github.com/confluentinc/confluent-kafka-go/v2 v2.2.0
github.com/darccio/knobs v0.0.0-20241211164423-8ba351cb0c0c
github.com/denisenkom/go-mssqldb v0.11.0
github.com/dimfeld/httptreemux/v5 v5.5.0
github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,8 @@ github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1S
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
github.com/darccio/knobs v0.0.0-20241211164423-8ba351cb0c0c h1:3h9o1zuYKNAyi5vpoZlFmmckCXsT+w/VB/PWDtz20EA=
github.com/darccio/knobs v0.0.0-20241211164423-8ba351cb0c0c/go.mod h1:nJ3ntDIyIQgqzTWF2QiL7eRNTy6iZJbBot3WcB+SymI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
Expand Down
1 change: 1 addition & 0 deletions internal/apps/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/DataDog/go-sqllexer v0.0.14 // indirect
github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.20.0 // indirect
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect
github.com/darccio/knobs v0.0.0-20241211164423-8ba351cb0c0c // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect
github.com/ebitengine/purego v0.6.0-alpha.5 // indirect
Expand Down
2 changes: 2 additions & 0 deletions internal/apps/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs=
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo=
github.com/darccio/knobs v0.0.0-20241211164423-8ba351cb0c0c h1:3h9o1zuYKNAyi5vpoZlFmmckCXsT+w/VB/PWDtz20EA=
github.com/darccio/knobs v0.0.0-20241211164423-8ba351cb0c0c/go.mod h1:nJ3ntDIyIQgqzTWF2QiL7eRNTy6iZJbBot3WcB+SymI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
Expand Down
1 change: 1 addition & 0 deletions internal/exectracetest/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ require (
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect
github.com/darccio/knobs v0.0.0-20241211164423-8ba351cb0c0c // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect
github.com/ebitengine/purego v0.6.0-alpha.5 // indirect
Expand Down
2 changes: 2 additions & 0 deletions internal/exectracetest/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs=
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo=
github.com/darccio/knobs v0.0.0-20241211164423-8ba351cb0c0c h1:3h9o1zuYKNAyi5vpoZlFmmckCXsT+w/VB/PWDtz20EA=
github.com/darccio/knobs v0.0.0-20241211164423-8ba351cb0c0c/go.mod h1:nJ3ntDIyIQgqzTWF2QiL7eRNTy6iZJbBot3WcB+SymI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
Expand Down

0 comments on commit 589085a

Please sign in to comment.