diff --git a/ddtrace/tracer/metrics.go b/ddtrace/tracer/metrics.go index 8f1738d724..584ac2b94f 100644 --- a/ddtrace/tracer/metrics.go +++ b/ddtrace/tracer/metrics.go @@ -8,7 +8,6 @@ package tracer import ( "runtime" "runtime/debug" - "sync/atomic" "time" "gopkg.in/DataDog/dd-trace-go.v1/internal/log" @@ -99,9 +98,9 @@ func (t *tracer) reportHealthMetrics(interval time.Duration) { for { select { case <-ticker.C: - t.config.statsd.Count("datadog.tracer.spans_started", atomic.SwapInt64(&t.spansStarted, 0), nil, 1) - t.config.statsd.Count("datadog.tracer.spans_finished", atomic.SwapInt64(&t.spansFinished, 0), nil, 1) - t.config.statsd.Count("datadog.tracer.traces_dropped", atomic.SwapInt64(&t.tracesDropped, 0), []string{"reason:trace_too_large"}, 1) + t.config.statsd.Count("datadog.tracer.spans_started", t.spansStarted.Swap(0), nil, 1) + t.config.statsd.Count("datadog.tracer.spans_finished", t.spansFinished.Swap(0), nil, 1) + t.config.statsd.Count("datadog.tracer.traces_dropped", t.tracesDropped.Swap(0), []string{"reason:trace_too_large"}, 1) case <-t.stop: return } diff --git a/ddtrace/tracer/payload.go b/ddtrace/tracer/payload.go index 2107ac0635..32e8defeb2 100644 --- a/ddtrace/tracer/payload.go +++ b/ddtrace/tracer/payload.go @@ -9,9 +9,9 @@ import ( "bytes" "encoding/binary" "io" - "sync/atomic" "github.com/tinylib/msgp/msgp" + uatomic "go.uber.org/atomic" ) // payload is a wrapper on top of the msgpack encoder which allows constructing an @@ -36,7 +36,7 @@ type payload struct { off int // count specifies the number of items in the stream. - count uint64 + count uatomic.Uint64 // buf holds the sequence of msgpack-encoded items. buf bytes.Buffer @@ -58,14 +58,15 @@ func (p *payload) push(t spanList) error { if err := msgp.Encode(&p.buf, t); err != nil { return err } - atomic.AddUint64(&p.count, 1) + //atomic.AddUint64(&p.count, 1) + p.count.Inc() p.updateHeader() return nil } // itemCount returns the number of items available in the srteam. func (p *payload) itemCount() int { - return int(atomic.LoadUint64(&p.count)) + return int(p.count.Load()) } // size returns the payload size in bytes. After the first read the value becomes @@ -102,7 +103,7 @@ const ( // updateHeader updates the payload header based on the number of items currently // present in the stream. func (p *payload) updateHeader() { - n := atomic.LoadUint64(&p.count) + n := p.count.Load() switch { case n <= 15: p.header[7] = msgpackArrayFix + byte(n) diff --git a/ddtrace/tracer/payload_test.go b/ddtrace/tracer/payload_test.go index 73d72ea0af..006a2556c8 100644 --- a/ddtrace/tracer/payload_test.go +++ b/ddtrace/tracer/payload_test.go @@ -96,7 +96,7 @@ func benchmarkPayloadThroughput(count int) func(*testing.B) { reset := func() { p.header = make([]byte, 8) p.off = 8 - p.count = 0 + p.count.Store(0) p.buf.Reset() } for i := 0; i < b.N; i++ { diff --git a/ddtrace/tracer/span.go b/ddtrace/tracer/span.go index 1567ec0015..6b7be312e9 100644 --- a/ddtrace/tracer/span.go +++ b/ddtrace/tracer/span.go @@ -19,7 +19,6 @@ import ( "strconv" "strings" "sync" - "sync/atomic" "time" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" @@ -221,13 +220,15 @@ func (s *span) setTagError(value interface{}, cfg errorConfig) { if yes { if s.Error == 0 { // new error - atomic.AddInt64(&s.context.errors, 1) + //atomic.AddInt64(&s.context.errors, 1) + s.context.errors.Inc() } s.Error = 1 } else { if s.Error > 0 { // flip from active to inactive - atomic.AddInt64(&s.context.errors, -1) + //atomic.AddInt64(&s.context.errors, -1) + s.context.errors.Dec() } s.Error = 0 } @@ -518,7 +519,7 @@ func shouldKeep(s *span) bool { // positive sampling priorities stay return true } - if atomic.LoadInt64(&s.context.errors) > 0 { + if s.context.errors.Load() > 0 { // traces with any span containing an error get kept return true } diff --git a/ddtrace/tracer/span_test.go b/ddtrace/tracer/span_test.go index acf1ab05ff..432118fb2c 100644 --- a/ddtrace/tracer/span_test.go +++ b/ddtrace/tracer/span_test.go @@ -11,7 +11,6 @@ import ( "math" "os" "strings" - "sync/atomic" "testing" "time" @@ -122,7 +121,8 @@ func TestShouldDrop(t *testing.T) { s := newSpan("", "", "", 1, 1, 0) s.SetTag(ext.SamplingPriority, tt.prio) s.SetTag(ext.EventSampleRate, tt.rate) - atomic.StoreInt64(&s.context.errors, tt.errors) + //atomic.StoreInt64(&s.context.errors, tt.errors) + s.context.errors.Store(tt.errors) assert.Equal(t, shouldKeep(s), tt.want) }) } diff --git a/ddtrace/tracer/spancontext.go b/ddtrace/tracer/spancontext.go index c7ee376c1f..2b91e951a4 100644 --- a/ddtrace/tracer/spancontext.go +++ b/ddtrace/tracer/spancontext.go @@ -8,12 +8,13 @@ package tracer import ( "strconv" "sync" - "sync/atomic" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/internal" "gopkg.in/DataDog/dd-trace-go.v1/internal/log" "gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames" + + uatomic "go.uber.org/atomic" ) var _ ddtrace.SpanContext = (*spanContext)(nil) @@ -25,9 +26,9 @@ var _ ddtrace.SpanContext = (*spanContext)(nil) type spanContext struct { // the below group should propagate only locally - trace *trace // reference to the trace that this span belongs too - span *span // reference to the span that hosts this context - errors int64 // number of spans with errors in this trace + trace *trace // reference to the trace that this span belongs too + span *span // reference to the span that hosts this context + errors uatomic.Int64 // number of spans with errors in this trace // the below group should propagate cross-process @@ -36,8 +37,8 @@ type spanContext struct { mu sync.RWMutex // guards below fields baggage map[string]string - hasBaggage int32 // atomic int for quick checking presence of baggage. 0 indicates no baggage, otherwise baggage exists. - origin string // e.g. "synthetics" + hasBaggage uatomic.Int32 // atomic int for quick checking presence of baggage. 0 indicates no baggage, otherwise baggage exists. + origin string // e.g. "synthetics" } // newSpanContext creates a new SpanContext to serve as context for the given @@ -80,7 +81,7 @@ func (c *spanContext) TraceID() uint64 { return c.traceID } // ForeachBaggageItem implements ddtrace.SpanContext. func (c *spanContext) ForeachBaggageItem(handler func(k, v string) bool) { - if atomic.LoadInt32(&c.hasBaggage) == 0 { + if c.hasBaggage.Load() == 0 { return } c.mu.RLock() @@ -110,14 +111,14 @@ func (c *spanContext) setBaggageItem(key, val string) { c.mu.Lock() defer c.mu.Unlock() if c.baggage == nil { - atomic.StoreInt32(&c.hasBaggage, 1) + c.hasBaggage.Store(1) c.baggage = make(map[string]string, 1) } c.baggage[key] = val } func (c *spanContext) baggageItem(key string) string { - if atomic.LoadInt32(&c.hasBaggage) == 0 { + if c.hasBaggage.Load() == 0 { return "" } c.mu.RLock() @@ -136,12 +137,14 @@ func (c *spanContext) meta(key string) (val string, ok bool) { func (c *spanContext) finish() { c.trace.finishedOne(c.span) } // samplingDecision is the decision to send a trace to the agent or not. -type samplingDecision int64 +type samplingDecision struct { + uatomic.Int64 +} const ( // decisionNone is the default state of a trace. // If no decision is made about the trace, the trace won't be sent to the agent. - decisionNone samplingDecision = iota + decisionNone int64 = iota // decisionDrop prevents the trace from being sent to the agent. decisionDrop // decisionKeep ensures the trace will be sent to the agent. @@ -208,11 +211,11 @@ func (t *trace) setSamplingPriority(p int, sampler samplernames.SamplerName, rat } func (t *trace) keep() { - atomic.CompareAndSwapInt64((*int64)(&t.samplingDecision), int64(decisionNone), int64(decisionKeep)) + t.samplingDecision.CompareAndSwap(decisionNone, decisionKeep) } func (t *trace) drop() { - atomic.CompareAndSwapInt64((*int64)(&t.samplingDecision), int64(decisionNone), int64(decisionDrop)) + t.samplingDecision.CompareAndSwap(decisionNone, decisionDrop) } func (t *trace) setTag(key, value string) { @@ -279,7 +282,8 @@ func (t *trace) push(sp *span) { t.spans = nil // GC log.Error("trace buffer full (%d), dropping trace", traceMaxSize) if haveTracer { - atomic.AddInt64(&tr.tracesDropped, 1) + //atomic.AddInt64(&tr.tracesDropped, 1) + tr.tracesDropped.Inc() } return } @@ -288,7 +292,8 @@ func (t *trace) push(sp *span) { } t.spans = append(t.spans, sp) if haveTracer { - atomic.AddInt64(&tr.spansStarted, 1) + //atomic.AddInt64(&tr.spansStarted, 1) + tr.spansStarted.Inc() } } @@ -338,9 +343,12 @@ func (t *trace) finishedOne(s *span) { return } // we have a tracer that can receive completed traces. - atomic.AddInt64(&tr.spansFinished, int64(len(t.spans))) + //atomic.AddInt64(&tr.spansFinished, int64(len(t.spans))) + tr.spansFinished.Add(int64(len(t.spans))) + var decision samplingDecision + decision.Store(t.samplingDecision.Load()) tr.pushTrace(&finishedTrace{ spans: t.spans, - decision: samplingDecision(atomic.LoadInt64((*int64)(&t.samplingDecision))), + decision: decision, }) } diff --git a/ddtrace/tracer/spancontext_test.go b/ddtrace/tracer/spancontext_test.go index 22c7821c77..cb876a0f5c 100644 --- a/ddtrace/tracer/spancontext_test.go +++ b/ddtrace/tracer/spancontext_test.go @@ -12,11 +12,12 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" "gopkg.in/DataDog/dd-trace-go.v1/internal/log" "gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames" + + "github.com/stretchr/testify/assert" + uatomic "go.uber.org/atomic" ) func setupteardown(start, max int) func() { @@ -305,13 +306,13 @@ func TestSpanContextParent(t *testing.T) { for name, parentCtx := range map[string]*spanContext{ "basic": &spanContext{ baggage: map[string]string{"A": "A", "B": "B"}, - hasBaggage: 1, + hasBaggage: *uatomic.NewInt32(1), trace: newTrace(), }, "nil-trace": &spanContext{}, "priority": &spanContext{ baggage: map[string]string{"A": "A", "B": "B"}, - hasBaggage: 1, + hasBaggage: *uatomic.NewInt32(1), trace: &trace{ spans: []*span{newBasicSpan("abc")}, priority: func() *float64 { v := new(float64); *v = 2; return v }(), @@ -319,10 +320,10 @@ func TestSpanContextParent(t *testing.T) { }, "sampling_decision": &spanContext{ baggage: map[string]string{"A": "A", "B": "B"}, - hasBaggage: 1, + hasBaggage: *uatomic.NewInt32(1), trace: &trace{ spans: []*span{newBasicSpan("abc")}, - samplingDecision: decisionKeep, + samplingDecision: samplingDecision{*uatomic.NewInt64(decisionKeep)}, }, }, "origin": &spanContext{ @@ -386,7 +387,7 @@ func TestSpanContextIterator(t *testing.T) { assert := assert.New(t) got := make(map[string]string) - ctx := spanContext{baggage: map[string]string{"key": "value"}, hasBaggage: 1} + ctx := spanContext{baggage: map[string]string{"key": "value"}, hasBaggage: *uatomic.NewInt32(1)} ctx.ForeachBaggageItem(func(k, v string) bool { got[k] = v return true @@ -434,7 +435,7 @@ func (tp *testLogger) Reset() { } func BenchmarkBaggageItemPresent(b *testing.B) { - ctx := spanContext{baggage: map[string]string{"key": "value"}, hasBaggage: 1} + ctx := spanContext{baggage: map[string]string{"key": "value"}, hasBaggage: *uatomic.NewInt32(1)} for n := 0; n < b.N; n++ { ctx.ForeachBaggageItem(func(k, v string) bool { return true diff --git a/ddtrace/tracer/stats.go b/ddtrace/tracer/stats.go index 99029de556..453b4f720b 100644 --- a/ddtrace/tracer/stats.go +++ b/ddtrace/tracer/stats.go @@ -9,9 +9,9 @@ package tracer import ( "sync" - "sync/atomic" "time" + uatomic "go.uber.org/atomic" "gopkg.in/DataDog/dd-trace-go.v1/internal/log" "github.com/DataDog/datadog-go/v5/statsd" @@ -52,7 +52,7 @@ type concentrator struct { buckets map[int64]*rawBucket // stopped reports whether the concentrator is stopped (when non-zero) - stopped uint64 + stopped uatomic.Uint64 wg sync.WaitGroup // waits for any active goroutines bucketSize int64 // the size of a bucket in nanoseconds @@ -63,10 +63,12 @@ type concentrator struct { // newConcentrator creates a new concentrator using the given tracer // configuration c. It creates buckets of bucketSize nanoseconds duration. func newConcentrator(c *config, bucketSize int64) *concentrator { + var stopped uatomic.Uint64 + stopped.Store(1) return &concentrator{ In: make(chan *aggregableSpan, 10000), bucketSize: bucketSize, - stopped: 1, + stopped: stopped, buckets: make(map[int64]*rawBucket), cfg: c, } @@ -79,7 +81,7 @@ func alignTs(ts, bucketSize int64) int64 { return ts - ts%bucketSize } // Start starts the concentrator. A started concentrator needs to be stopped // in order to gracefully shut down, using Stop. func (c *concentrator) Start() { - if atomic.SwapUint64(&c.stopped, 0) == 0 { + if c.stopped.Swap(0) == 0 { // already running log.Warn("(*concentrator).Start called more than once. This is likely a programming error.") return @@ -149,7 +151,7 @@ func (c *concentrator) add(s *aggregableSpan) { // Stop stops the concentrator and blocks until the operation completes. func (c *concentrator) Stop() { - if atomic.SwapUint64(&c.stopped, 1) > 0 { + if c.stopped.Swap(1) > 0 { return } close(c.stop) diff --git a/ddtrace/tracer/stats_test.go b/ddtrace/tracer/stats_test.go index 6c58e657e4..0c1ff9e434 100644 --- a/ddtrace/tracer/stats_test.go +++ b/ddtrace/tracer/stats_test.go @@ -60,26 +60,26 @@ func TestConcentrator(t *testing.T) { assert.Nil(c.stop) assert.NotNil(c.buckets) assert.Equal(c.cfg, cfg) - assert.EqualValues(c.stopped, 1) + assert.EqualValues(c.stopped.Load(), 1) }) t.Run("start-stop", func(t *testing.T) { assert := assert.New(t) c := newConcentrator(&config{}, defaultStatsBucketSize) - assert.EqualValues(c.stopped, 1) + assert.EqualValues(c.stopped.Load(), 1) c.Start() - assert.EqualValues(c.stopped, 0) + assert.EqualValues(c.stopped.Load(), 0) c.Stop() c.Stop() - assert.EqualValues(c.stopped, 1) + assert.EqualValues(c.stopped.Load(), 1) c.Start() - assert.EqualValues(c.stopped, 0) + assert.EqualValues(c.stopped.Load(), 0) c.Start() c.Start() - assert.EqualValues(c.stopped, 0) + assert.EqualValues(c.stopped.Load(), 0) c.Stop() c.Stop() - assert.EqualValues(c.stopped, 1) + assert.EqualValues(c.stopped.Load(), 1) }) t.Run("valid", func(t *testing.T) { diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index 6b4437d7b0..6888bee059 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -12,7 +12,6 @@ import ( rt "runtime/trace" "strconv" "sync" - "sync/atomic" "time" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" @@ -23,6 +22,7 @@ import ( "gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof" "github.com/DataDog/datadog-agent/pkg/obfuscate" + uatomic "go.uber.org/atomic" ) var _ ddtrace.Tracer = (*tracer)(nil) @@ -70,13 +70,13 @@ type tracer struct { // These integers track metrics about spans and traces as they are started, // finished, and dropped - spansStarted, spansFinished, tracesDropped int64 + spansStarted, spansFinished, tracesDropped uatomic.Int64 // Records the number of dropped P0 traces and spans. - droppedP0Traces, droppedP0Spans uint64 + droppedP0Traces, droppedP0Spans uatomic.Uint64 // partialTrace the number of partially dropped traces. - partialTraces uint64 + partialTraces uatomic.Uint64 // rulesSampling holds an instance of the rules sampler used to apply either trace sampling, // or single span sampling rules on spans. These are user-defined @@ -331,7 +331,7 @@ type finishedTrace struct { // sampleFinishedTrace applies single-span sampling to the provided trace, which is considered to be finished. func (t *tracer) sampleFinishedTrace(info *finishedTrace) { - if info.decision == decisionKeep { + if info.decision.Load() == decisionKeep { return } if !t.rulesSampling.HasSpanRules() { @@ -346,13 +346,16 @@ func (t *tracer) sampleFinishedTrace(info *finishedTrace) { kept = append(kept, span) } } - atomic.AddUint64(&t.droppedP0Spans, uint64(len(info.spans)-len(kept))) + //atomic.AddUint64(&t.droppedP0Spans, uint64(len(info.spans)-len(kept))) + t.droppedP0Spans.Add(uint64(len(info.spans) - len(kept))) info.spans = kept if len(kept) == 0 { - atomic.AddUint64(&t.droppedP0Traces, 1) + //atomic.AddUint64(&t.droppedP0Traces, 1) + t.droppedP0Traces.Inc() return // no spans matched the rules and were sampled } - atomic.AddUint64(&t.partialTraces, 1) + //atomic.AddUint64(&t.partialTraces, 1) + t.partialTraces.Inc() } func (t *tracer) pushTrace(trace *finishedTrace) { diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index 85e3b18e76..ba1ba74d8a 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/tinylib/msgp/msgp" + uatomic "go.uber.org/atomic" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" @@ -295,7 +296,7 @@ func TestSamplingDecision(t *testing.T) { span.Finish() assert.Equal(t, float64(ext.PriorityAutoReject), span.Metrics[keySamplingPriority]) assert.Equal(t, "", span.context.trace.propagatingTags[keyDecisionMaker]) - assert.Equal(t, decisionKeep, span.context.trace.samplingDecision) + assert.Equal(t, samplingDecision{*uatomic.NewInt64(decisionKeep)}, span.context.trace.samplingDecision) }) t.Run("dropped_sent", func(t *testing.T) { @@ -312,7 +313,7 @@ func TestSamplingDecision(t *testing.T) { span.Finish() assert.Equal(t, float64(ext.PriorityAutoReject), span.Metrics[keySamplingPriority]) assert.Equal(t, "", span.context.trace.propagatingTags[keyDecisionMaker]) - assert.Equal(t, decisionKeep, span.context.trace.samplingDecision) + assert.Equal(t, decisionKeep, span.context.trace.samplingDecision.Load()) }) t.Run("dropped_stats", func(t *testing.T) { @@ -330,7 +331,7 @@ func TestSamplingDecision(t *testing.T) { span.Finish() assert.Equal(t, float64(ext.PriorityAutoReject), span.Metrics[keySamplingPriority]) assert.Equal(t, "", span.context.trace.propagatingTags[keyDecisionMaker]) - assert.Equal(t, decisionNone, span.context.trace.samplingDecision) + assert.Equal(t, decisionNone, span.context.trace.samplingDecision.Load()) }) t.Run("events_sampled", func(t *testing.T) { @@ -346,7 +347,7 @@ func TestSamplingDecision(t *testing.T) { span.Finish() assert.Equal(t, float64(ext.PriorityAutoReject), span.Metrics[keySamplingPriority]) assert.Equal(t, "", span.context.trace.tags[keyDecisionMaker]) - assert.Equal(t, decisionKeep, span.context.trace.samplingDecision) + assert.Equal(t, decisionKeep, span.context.trace.samplingDecision.Load()) }) t.Run("client_dropped", func(t *testing.T) { @@ -365,7 +366,7 @@ func TestSamplingDecision(t *testing.T) { // this trace won't be sent to the agent, // therefore not necessary to populate keyDecisionMaker assert.Equal(t, "", span.context.trace.propagatingTags[keyDecisionMaker]) - assert.Equal(t, decisionDrop, span.context.trace.samplingDecision) + assert.Equal(t, decisionDrop, span.context.trace.samplingDecision.Load()) }) t.Run("client_dropped_with_single_spans", func(t *testing.T) { @@ -386,7 +387,7 @@ func TestSamplingDecision(t *testing.T) { tracer.pushTrace(&finishedTrace{spans: []*span{parent, child}}) tracer.Stop() assert.Equal(t, float64(ext.PriorityAutoReject), parent.Metrics[keySamplingPriority]) - assert.Equal(t, decisionDrop, parent.context.trace.samplingDecision) + assert.Equal(t, decisionDrop, parent.context.trace.samplingDecision.Load()) assert.Equal(t, 8.0, parent.Metrics[keySpanSamplingMechanism]) assert.Equal(t, 1.0, parent.Metrics[keySingleSpanSamplingRuleRate]) assert.Equal(t, 15.0, parent.Metrics[keySingleSpanSamplingMPS]) @@ -1220,11 +1221,11 @@ func TestPushPayload(t *testing.T) { s.Meta["key"] = strings.Repeat("X", payloadSizeLimit/2+10) // half payload size reached - tracer.pushTrace(&finishedTrace{[]*span{s}, decisionKeep}) + tracer.pushTrace(&finishedTrace{[]*span{s}, samplingDecision{*uatomic.NewInt64(decisionKeep)}}) tracer.awaitPayload(t, 1) // payload size exceeded - tracer.pushTrace(&finishedTrace{[]*span{s}, decisionKeep}) + tracer.pushTrace(&finishedTrace{[]*span{s}, samplingDecision{*uatomic.NewInt64(decisionKeep)}}) flush(2) } diff --git a/ddtrace/tracer/transport.go b/ddtrace/tracer/transport.go index 85da05dd6f..685aa9e44c 100644 --- a/ddtrace/tracer/transport.go +++ b/ddtrace/tracer/transport.go @@ -15,7 +15,6 @@ import ( "runtime" "strconv" "strings" - "sync/atomic" "time" traceinternal "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/internal" @@ -151,16 +150,19 @@ func (t *httpTransport) send(p *payload) (body io.ReadCloser, err error) { if t.config.canComputeStats() { req.Header.Set("Datadog-Client-Computed-Stats", "yes") } - droppedTraces := int(atomic.SwapUint64(&t.droppedP0Traces, 0)) - partialTraces := int(atomic.SwapUint64(&t.partialTraces, 0)) - droppedSpans := int(atomic.SwapUint64(&t.droppedP0Spans, 0)) + // droppedTraces := int(atomic.SwapUint64(&t.droppedP0Traces, 0)) + // partialTraces := int(atomic.SwapUint64(&t.partialTraces, 0)) + // droppedSpans := int(atomic.SwapUint64(&t.droppedP0Spans, 0)) + droppedTraces := t.droppedP0Traces.Swap(0) + partialTraces := t.partialTraces.Swap(0) + droppedSpans := t.droppedP0Spans.Swap(0) if stats := t.config.statsd; stats != nil { stats.Count("datadog.tracer.dropped_p0_traces", int64(droppedTraces), []string{fmt.Sprintf("partial:%s", strconv.FormatBool(partialTraces > 0))}, 1) stats.Count("datadog.tracer.dropped_p0_spans", int64(droppedSpans), nil, 1) } - req.Header.Set("Datadog-Client-Dropped-P0-Traces", strconv.Itoa(droppedTraces)) - req.Header.Set("Datadog-Client-Dropped-P0-Spans", strconv.Itoa(droppedSpans)) + req.Header.Set("Datadog-Client-Dropped-P0-Traces", strconv.FormatUint(droppedTraces, 10)) + req.Header.Set("Datadog-Client-Dropped-P0-Spans", strconv.FormatUint(droppedSpans, 10)) } response, err := t.client.Do(req) if err != nil { diff --git a/docker-compose.yaml b/docker-compose.yaml index 34a0b1acb4..76528c6f31 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,4 +1,4 @@ -version: "3.9" # optional since v1.27.0 +version: "3.3" # optional since v1.27.0 services: cassandra: image: cassandra:3.7 diff --git a/go.mod b/go.mod index 55913f0646..9031d185f1 100644 --- a/go.mod +++ b/go.mod @@ -66,6 +66,7 @@ require ( github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/zenazn/goji v1.0.1 go.mongodb.org/mongo-driver v1.7.5 + go.uber.org/atomic v1.10.0 golang.org/x/net v0.0.0-20220722155237-a158d28d115b golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f diff --git a/go.sum b/go.sum index 972c353313..d565645b97 100644 --- a/go.sum +++ b/go.sum @@ -810,6 +810,8 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=