From 73d42638a5c9c342f2293959ca7b8c66a5e733dc Mon Sep 17 00:00:00 2001 From: Hannah Kim Date: Mon, 9 Dec 2024 15:01:40 -0500 Subject: [PATCH 1/7] ddtrace/tracer: report number of instrumentations used as health metric --- ddtrace/tracer/tracer.go | 8 ++++++++ ddtrace/tracer/tracer_test.go | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index ccc52bbc17..f9bae1ffc6 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -8,6 +8,7 @@ package tracer import ( gocontext "context" "encoding/binary" + "fmt" "log/slog" "math" "os" @@ -347,6 +348,13 @@ func newTracer(opts ...StartOption) *tracer { t.abandonedSpansDebugger = newAbandonedSpansDebugger() t.abandonedSpansDebugger.Start(t.config.spanTimeout) } + for name, conf := range c.integrations { + if !conf.Instrumented { + continue + } + t.statsd.Incr("datadog.tracer.instrumentations", []string{fmt.Sprintf("source:%s", name)}, 1) + } + t.wg.Add(1) go func() { defer t.wg.Done() diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index 555c71080d..a35b876e8f 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -255,6 +255,23 @@ func TestTracerStart(t *testing.T) { tr.Stop() tr.Stop() }) + + t.Run("integration_health_metric", func(t *testing.T) { + defer clearIntegrationsForTests() + var tg statsdtest.TestStatsdClient + + ok := MarkIntegrationImported("github.com/go-chi/chi") + assert.True(t, ok) + tr, _, _, stop := startTestTracer(t, withStatsdClient(&tg)) + defer stop() + + conf, ok := tr.config.integrations["chi"] + assert.True(t, ok) + assert.True(t, conf.Instrumented) + + counts := tg.Counts() + assert.Equal(t, int64(1), counts["datadog.tracer.instrumentations"]) + }) } func TestTracerLogFile(t *testing.T) { From e38c49e62bf78723855c0791196d3348297521f1 Mon Sep 17 00:00:00 2001 From: Hannah Kim Date: Thu, 12 Dec 2024 13:32:09 -0500 Subject: [PATCH 2/7] ddtrace/tracer: check for appropriate tag in instrumentation metric --- ddtrace/tracer/tracer.go | 2 +- ddtrace/tracer/tracer_test.go | 21 +++++++++++++++++---- internal/statsdtest/statsdtest.go | 8 ++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index f9bae1ffc6..c2c216ef42 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -352,7 +352,7 @@ func newTracer(opts ...StartOption) *tracer { if !conf.Instrumented { continue } - t.statsd.Incr("datadog.tracer.instrumentations", []string{fmt.Sprintf("source:%s", name)}, 1) + t.statsd.Incr("datadog.tracer.instrumentations", []string{fmt.Sprintf("instrumentation:%s", name)}, 1) } t.wg.Add(1) diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index a35b876e8f..1acf025854 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -257,20 +257,33 @@ func TestTracerStart(t *testing.T) { }) t.Run("integration_health_metric", func(t *testing.T) { + assert := assert.New(t) defer clearIntegrationsForTests() var tg statsdtest.TestStatsdClient ok := MarkIntegrationImported("github.com/go-chi/chi") - assert.True(t, ok) + assert.True(ok) tr, _, _, stop := startTestTracer(t, withStatsdClient(&tg)) defer stop() + tg.Wait(assert, 1, 100*time.Millisecond) + conf, ok := tr.config.integrations["chi"] - assert.True(t, ok) - assert.True(t, conf.Instrumented) + assert.True(ok) + assert.True(conf.Instrumented) counts := tg.Counts() - assert.Equal(t, int64(1), counts["datadog.tracer.instrumentations"]) + assert.Equal(int64(1), counts["datadog.tracer.instrumentations"]) + + calls := tg.IncrCalls() + for _, c := range calls { + if c.GetName() == "datadog.tracer.instrumentations" { + assert.Equal(c.GetTags(), []string{"instrumentation:chi"}) + return + } + } + assert.Fail("expected instrumentation tag to contain `chi`") + }) } diff --git a/internal/statsdtest/statsdtest.go b/internal/statsdtest/statsdtest.go index 8845e6465c..4981d413fc 100644 --- a/internal/statsdtest/statsdtest.go +++ b/internal/statsdtest/statsdtest.go @@ -55,6 +55,14 @@ func (tg *TestStatsdClient) addCount(name string, value int64) { tg.counts[name] += value } +func (tc *TestStatsdCall) GetTags() []string { + return tc.tags +} + +func (tc *TestStatsdCall) GetName() string { + return tc.name +} + func (tg *TestStatsdClient) Gauge(name string, value float64, tags []string, rate float64) error { return tg.addMetric(callTypeGauge, tags, TestStatsdCall{ name: name, From 6f3cfa1fb17e8030832ce1d741ad19666bc17e39 Mon Sep 17 00:00:00 2001 From: Hannah Kim Date: Thu, 12 Dec 2024 13:39:31 -0500 Subject: [PATCH 3/7] ddtrace/tracer: add version tag to instrumentation metric --- ddtrace/tracer/tracer.go | 6 +++++- ddtrace/tracer/tracer_test.go | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index c2c216ef42..bb3d76b024 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -352,7 +352,11 @@ func newTracer(opts ...StartOption) *tracer { if !conf.Instrumented { continue } - t.statsd.Incr("datadog.tracer.instrumentations", []string{fmt.Sprintf("instrumentation:%s", name)}, 1) + v := conf.Version + if v == "" { + v = "unknown" + } + t.statsd.Incr("datadog.tracer.instrumentations", []string{fmt.Sprintf("instrumentation:%s", name), fmt.Sprintf("version:%s", v)}, 1) } t.wg.Add(1) diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index 1acf025854..2fe0eea1ed 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -278,11 +278,11 @@ func TestTracerStart(t *testing.T) { calls := tg.IncrCalls() for _, c := range calls { if c.GetName() == "datadog.tracer.instrumentations" { - assert.Equal(c.GetTags(), []string{"instrumentation:chi"}) + assert.EqualValues(c.GetTags(), []string{"instrumentation:chi", "version:unknown"}) return } } - assert.Fail("expected instrumentation tag to contain `chi`") + assert.Fail("expected instrumentation to have appropriate tags") }) } From 530a452e359abd668317e59cea1fd4060f67ab25 Mon Sep 17 00:00:00 2001 From: Hannah Kim Date: Thu, 12 Dec 2024 14:22:40 -0500 Subject: [PATCH 4/7] ddtrace/tracer: rename version tag for more clarity --- ddtrace/tracer/tracer.go | 2 +- ddtrace/tracer/tracer_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index bb3d76b024..7a883342e3 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -356,7 +356,7 @@ func newTracer(opts ...StartOption) *tracer { if v == "" { v = "unknown" } - t.statsd.Incr("datadog.tracer.instrumentations", []string{fmt.Sprintf("instrumentation:%s", name), fmt.Sprintf("version:%s", v)}, 1) + t.statsd.Incr("datadog.tracer.instrumentations", []string{fmt.Sprintf("instrumentation:%s", name), fmt.Sprintf("instrumentation_version:%s", v)}, 1) } t.wg.Add(1) diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index 2fe0eea1ed..3d099c826c 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -278,7 +278,7 @@ func TestTracerStart(t *testing.T) { calls := tg.IncrCalls() for _, c := range calls { if c.GetName() == "datadog.tracer.instrumentations" { - assert.EqualValues(c.GetTags(), []string{"instrumentation:chi", "version:unknown"}) + assert.EqualValues(c.GetTags(), []string{"instrumentation:chi", "instrumentation_version:unknown"}) return } } From 565a5b825dcacad0a693f5702d0db75c8e2dce9c Mon Sep 17 00:00:00 2001 From: Hannah Kim Date: Tue, 17 Dec 2024 10:14:39 -0500 Subject: [PATCH 5/7] use FilterCallsByName to simplify tests --- ddtrace/tracer/tracer_test.go | 8 +++----- internal/statsdtest/statsdtest.go | 14 ++++++++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index 3d099c826c..c95eb21804 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -276,11 +276,9 @@ func TestTracerStart(t *testing.T) { assert.Equal(int64(1), counts["datadog.tracer.instrumentations"]) calls := tg.IncrCalls() - for _, c := range calls { - if c.GetName() == "datadog.tracer.instrumentations" { - assert.EqualValues(c.GetTags(), []string{"instrumentation:chi", "instrumentation_version:unknown"}) - return - } + for _, c := range statsdtest.FilterCallsByName(calls, "datadog.tracer.instrumentations") { + assert.EqualValues(c.GetTags(), []string{"instrumentation:chi", "instrumentation_version:unknown"}) + return } assert.Fail("expected instrumentation to have appropriate tags") diff --git a/internal/statsdtest/statsdtest.go b/internal/statsdtest/statsdtest.go index 4981d413fc..af41d118fe 100644 --- a/internal/statsdtest/statsdtest.go +++ b/internal/statsdtest/statsdtest.go @@ -59,10 +59,6 @@ func (tc *TestStatsdCall) GetTags() []string { return tc.tags } -func (tc *TestStatsdCall) GetName() string { - return tc.name -} - func (tg *TestStatsdClient) Gauge(name string, value float64, tags []string, rate float64) error { return tg.addMetric(callTypeGauge, tags, TestStatsdCall{ name: name, @@ -222,6 +218,16 @@ func (tg *TestStatsdClient) CallsByName() map[string]int { return counts } +func FilterCallsByName(calls []TestStatsdCall, name string) []TestStatsdCall { + var matches []TestStatsdCall + for _, c := range calls { + if c.name == name { + matches = append(matches, c) + } + } + return matches +} + func (tg *TestStatsdClient) Counts() map[string]int64 { tg.mu.RLock() defer tg.mu.RUnlock() From c3339e5a980166f11ecb6ee95e84631ce48b5809 Mon Sep 17 00:00:00 2001 From: Hannah Kim Date: Tue, 17 Dec 2024 16:02:32 -0500 Subject: [PATCH 6/7] ddtrace/tracer: rename to integrations --- ddtrace/tracer/tracer.go | 2 +- ddtrace/tracer/tracer_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index 7a883342e3..afb8d44d05 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -356,7 +356,7 @@ func newTracer(opts ...StartOption) *tracer { if v == "" { v = "unknown" } - t.statsd.Incr("datadog.tracer.instrumentations", []string{fmt.Sprintf("instrumentation:%s", name), fmt.Sprintf("instrumentation_version:%s", v)}, 1) + t.statsd.Incr("datadog.tracer.integrations", []string{fmt.Sprintf("integration:%s", name), fmt.Sprintf("integration_version:%s", v)}, 1) } t.wg.Add(1) diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index c95eb21804..133b724e02 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -273,14 +273,14 @@ func TestTracerStart(t *testing.T) { assert.True(conf.Instrumented) counts := tg.Counts() - assert.Equal(int64(1), counts["datadog.tracer.instrumentations"]) + assert.Equal(int64(1), counts["datadog.tracer.integrations"]) calls := tg.IncrCalls() - for _, c := range statsdtest.FilterCallsByName(calls, "datadog.tracer.instrumentations") { - assert.EqualValues(c.GetTags(), []string{"instrumentation:chi", "instrumentation_version:unknown"}) + for _, c := range statsdtest.FilterCallsByName(calls, "datadog.tracer.integrations") { + assert.EqualValues(c.GetTags(), []string{"integration:chi", "integration_version:unknown"}) return } - assert.Fail("expected instrumentation to have appropriate tags") + assert.Fail("expected integration to have appropriate tags") }) } From 0327e1079e98102a61796d138a24064c3eb541c5 Mon Sep 17 00:00:00 2001 From: Hannah Kim Date: Tue, 17 Dec 2024 16:06:34 -0500 Subject: [PATCH 7/7] ddtrace/tracer: replace sprintf with string concat --- ddtrace/tracer/tracer.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index afb8d44d05..abc44d0619 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -8,7 +8,6 @@ package tracer import ( gocontext "context" "encoding/binary" - "fmt" "log/slog" "math" "os" @@ -356,7 +355,7 @@ func newTracer(opts ...StartOption) *tracer { if v == "" { v = "unknown" } - t.statsd.Incr("datadog.tracer.integrations", []string{fmt.Sprintf("integration:%s", name), fmt.Sprintf("integration_version:%s", v)}, 1) + t.statsd.Incr("datadog.tracer.integrations", []string{"integration:" + name, "integration_version:" + v}, 1) } t.wg.Add(1)