From a7e5c8d3666fa305f947a750de5f65514a3f17a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Fri, 5 Jul 2024 10:39:36 +0200 Subject: [PATCH 1/7] ddtrace/tracer: runtime metrics v2 --- ddtrace/tracer/option.go | 4 ++ ddtrace/tracer/slog.go | 64 +++++++++++++++++++++++++++++++ ddtrace/tracer/slog_test.go | 33 ++++++++++++++++ ddtrace/tracer/telemetry.go | 1 + ddtrace/tracer/tracer.go | 10 +++++ go.mod | 11 +++--- go.sum | 22 ++++++----- internal/apps/apps.go | 5 +++ internal/statsd.go | 2 + internal/statsdtest/statsdtest.go | 8 ++++ 10 files changed, 145 insertions(+), 15 deletions(-) create mode 100644 ddtrace/tracer/slog.go create mode 100644 ddtrace/tracer/slog_test.go diff --git a/ddtrace/tracer/option.go b/ddtrace/tracer/option.go index d8ce6843a2..e07d775d74 100644 --- a/ddtrace/tracer/option.go +++ b/ddtrace/tracer/option.go @@ -188,6 +188,9 @@ type config struct { // runtimeMetrics specifies whether collection of runtime metrics is enabled. runtimeMetrics bool + // runtimeMetricsV2 specifies whether collection of runtime metrics v2 is enabled. + runtimeMetricsV2 bool + // dogstatsdAddr specifies the address to connect for sending metrics to the // Datadog Agent. If not set, it defaults to "localhost:8125" or to the // combination of the environment variables DD_AGENT_HOST and DD_DOGSTATSD_PORT. @@ -377,6 +380,7 @@ func newConfig(opts ...StartOption) *config { } c.logStartup = internal.BoolEnv("DD_TRACE_STARTUP_LOGS", true) c.runtimeMetrics = internal.BoolVal(getDDorOtelConfig("metrics"), false) + c.runtimeMetricsV2 = internal.BoolVal("DD_RUNTIME_METRICS_V2_ENABLED", false) c.debug = internal.BoolVal(getDDorOtelConfig("debugMode"), false) c.enabled = newDynamicConfig("tracing_enabled", internal.BoolVal(getDDorOtelConfig("enabled"), true), func(b bool) bool { return true }, equal[bool]) if _, ok := os.LookupEnv("DD_TRACE_ENABLED"); ok { diff --git a/ddtrace/tracer/slog.go b/ddtrace/tracer/slog.go new file mode 100644 index 0000000000..09015eb14f --- /dev/null +++ b/ddtrace/tracer/slog.go @@ -0,0 +1,64 @@ +package tracer + +import ( + "context" + "log/slog" + "strings" + + "gopkg.in/DataDog/dd-trace-go.v1/internal/log" +) + +// slogHandler implements the slog.Handler interface to dispatch messages to our +// internal logger. +type slogHandler struct { + attrs []string + groups []string +} + +func (h slogHandler) Enabled(ctx context.Context, lvl slog.Level) bool { + if lvl <= slog.LevelDebug { + return log.DebugEnabled() + } + // TODO(fg): Implement generic log level checking in the internal logger. + // But we're we're not concerned with slog perf, so this is okay for now. + return true +} + +func (h slogHandler) Handle(ctx context.Context, r slog.Record) error { + parts := make([]string, 0, 1+len(h.attrs)+r.NumAttrs()) + parts = append(parts, r.Message) + parts = append(parts, h.attrs...) + r.Attrs(func(a slog.Attr) bool { + parts = append(parts, formatAttr(a, h.groups)) + return true + }) + + msg := strings.Join(parts, " ") + switch r.Level { + case slog.LevelDebug: + log.Debug(msg) + case slog.LevelInfo: + log.Info(msg) + case slog.LevelWarn: + log.Warn(msg) + case slog.LevelError: + log.Error(msg) + } + return nil +} + +func (h slogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + for _, a := range attrs { + h.attrs = append(h.attrs, formatAttr(a, h.groups)) + } + return h +} + +func (h slogHandler) WithGroup(name string) slog.Handler { + h.groups = append(h.groups, name) + return h +} + +func formatAttr(a slog.Attr, groups []string) string { + return strings.Join(append(groups, a.String()), ".") +} diff --git a/ddtrace/tracer/slog_test.go b/ddtrace/tracer/slog_test.go new file mode 100644 index 0000000000..c04c028760 --- /dev/null +++ b/ddtrace/tracer/slog_test.go @@ -0,0 +1,33 @@ +package tracer + +import ( + "log/slog" + "testing" + + "github.com/stretchr/testify/require" + "gopkg.in/DataDog/dd-trace-go.v1/internal/log" +) + +func Test_slogHandler(t *testing.T) { + // Create a record logger to capture the logs and restore the original + // logger at the end. + rl := &log.RecordLogger{} + defer log.UseLogger(rl)() + + // Log a few messages at different levels. The debug message gets discarded + // because the internal logger does not have debug enabled by default. + l := slog.New(slogHandler{}) + l = l.With("foo", "bar") + l = l.WithGroup("a").WithGroup("b") + l.Debug("debug test", "n", 0) + l.Info("info test", "n", 1) + l.Warn("warn test", "n", 2) + l.Error("error test", "n", 3) + log.Flush() // needed to get the error log flushed + + // Check that the logs were written correctly. + require.Len(t, rl.Logs(), 3) + require.Contains(t, rl.Logs()[0], "info test foo=bar a.b.n=1") + require.Contains(t, rl.Logs()[1], "warn test foo=bar a.b.n=2") + require.Contains(t, rl.Logs()[2], "error test foo=bar a.b.n=3") +} diff --git a/ddtrace/tracer/telemetry.go b/ddtrace/tracer/telemetry.go index 7fec111383..31ddeddfb2 100644 --- a/ddtrace/tracer/telemetry.go +++ b/ddtrace/tracer/telemetry.go @@ -47,6 +47,7 @@ func startTelemetry(c *config) { {Name: "agent_url", Value: c.agentURL.String()}, {Name: "agent_hostname", Value: c.hostname}, {Name: "runtime_metrics_enabled", Value: c.runtimeMetrics}, + {Name: "runtime_metrics_v2_enabled", Value: c.runtimeMetricsV2}, {Name: "dogstatsd_addr", Value: c.dogstatsdAddr}, {Name: "trace_debug_enabled", Value: !c.noDebugStack}, {Name: "profiling_hotspots_enabled", Value: c.profilerHotspots}, diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index 35e3f2ce43..3d8711ef9a 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -8,6 +8,7 @@ package tracer import ( gocontext "context" "encoding/binary" + "log/slog" "math" "os" "runtime/pprof" @@ -32,6 +33,7 @@ import ( "gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof" "github.com/DataDog/datadog-agent/pkg/obfuscate" + "github.com/DataDog/go-runtime-metrics-internal/pkg/runtimemetrics" ) var _ ddtrace.Tracer = (*tracer)(nil) @@ -307,6 +309,14 @@ func newTracer(opts ...StartOption) *tracer { t.reportRuntimeMetrics(defaultMetricsReportInterval) }() } + if c.runtimeMetricsV2 { + l := slog.New(slogHandler{}) + if err := runtimemetrics.Start(t.statsd, l); err == nil { + l.Debug("Runtime metrics v2 enabled.") + } else { + l.Error("Failed to enable runtime metrics v2", "err", err.Error()) + } + } if c.debugAbandonedSpans { log.Info("Abandoned spans logs enabled.") t.abandonedSpansDebugger = newAbandonedSpansDebugger() diff --git a/go.mod b/go.mod index c879e8440f..82660e73aa 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,9 @@ require ( github.com/DataDog/appsec-internal-go v1.6.0 github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.1 - github.com/DataDog/datadog-go/v5 v5.3.0 + github.com/DataDog/datadog-go/v5 v5.5.0 github.com/DataDog/go-libddwaf/v3 v3.2.1 + github.com/DataDog/go-runtime-metrics-internal v0.0.0-20240703170703-20739ceb6063 github.com/DataDog/gostackparse v0.7.0 github.com/DataDog/sketches-go v1.4.5 github.com/IBM/sarama v1.40.0 @@ -255,12 +256,12 @@ require ( go.opentelemetry.io/otel/metric v1.20.0 // indirect golang.org/x/arch v0.4.0 // indirect golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/sync v0.5.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/mod v0.16.0 // indirect + golang.org/x/sync v0.6.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/tools v0.19.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect diff --git a/go.sum b/go.sum index dde9e28268..0b1d602c48 100644 --- a/go.sum +++ b/go.sum @@ -632,10 +632,12 @@ github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0/go.mod h1:HzySONXnAgSmIQf github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.1 h1:5nE6N3JSs2IG3xzMthNFhXfOaXlrsdgqmJ73lndFf8c= github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.1/go.mod h1:Vc+snp0Bey4MrrJyiV2tVxxJb6BmLomPvN1RgAvjGaQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/datadog-go/v5 v5.3.0 h1:2q2qjFOb3RwAZNU+ez27ZVDwErJv5/VpbBPprz7Z+s8= -github.com/DataDog/datadog-go/v5 v5.3.0/go.mod h1:XRDJk1pTc00gm+ZDiBKsjh7oOOtJfYfglVCmFb8C2+Q= +github.com/DataDog/datadog-go/v5 v5.5.0 h1:G5KHeB8pWBNXT4Jtw0zAkhdxEAWSpWH00geHI6LDrKU= +github.com/DataDog/datadog-go/v5 v5.5.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= github.com/DataDog/go-libddwaf/v3 v3.2.1 h1:lZPc6UxCOwioHc++nsldKR50FpIrRh1uGnGLuryqnE8= github.com/DataDog/go-libddwaf/v3 v3.2.1/go.mod h1:AP+7Atb8ftSsrha35wht7+K3R+xuzfVSQhabSO4w6CY= +github.com/DataDog/go-runtime-metrics-internal v0.0.0-20240703170703-20739ceb6063 h1:vGv1wZc9ztE0pV0SNVit5w7PSgnzs8wndArZpra7yfQ= +github.com/DataDog/go-runtime-metrics-internal v0.0.0-20240703170703-20739ceb6063/go.mod h1:zDQhUvRGwpo8egskalchVK7yoU+09H16wtMIG/aG3Hw= github.com/DataDog/go-tuf v1.0.2-0.5.2 h1:EeZr937eKAWPxJ26IykAdWA4A0jQXJgkhUjqEI/w7+I= github.com/DataDog/go-tuf v1.0.2-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= @@ -2236,8 +2238,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -2279,8 +2281,8 @@ golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2415,8 +2417,8 @@ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2688,8 +2690,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/apps/apps.go b/internal/apps/apps.go index 27518f478e..4ac7a6e205 100644 --- a/internal/apps/apps.go +++ b/internal/apps/apps.go @@ -40,6 +40,11 @@ func (c Config) RunHTTP(handler func() http.Handler) { os.Setenv("DD_PROFILING_EXECUTION_TRACE_PERIOD", "1s") } + // Enabled runtime metrics v2 by default + if v := os.Getenv("DD_RUNTIME_METRICS_V2_ENABLED"); v == "" { + os.Setenv("DD_RUNTIME_METRICS_V2_ENABLED", "true") + } + // Setup context that gets canceled on receiving SIGINT ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() diff --git a/internal/statsd.go b/internal/statsd.go index a901759f27..df1d18a307 100644 --- a/internal/statsd.go +++ b/internal/statsd.go @@ -16,7 +16,9 @@ const DefaultDogstatsdAddr = "localhost:8125" type StatsdClient interface { Incr(name string, tags []string, rate float64) error Count(name string, value int64, tags []string, rate float64) error + CountWithTimestamp(name string, value int64, tags []string, rate float64, timestamp time.Time) error Gauge(name string, value float64, tags []string, rate float64) error + GaugeWithTimestamp(name string, value float64, tags []string, rate float64, timestamp time.Time) error Timing(name string, value time.Duration, tags []string, rate float64) error Flush() error Close() error diff --git a/internal/statsdtest/statsdtest.go b/internal/statsdtest/statsdtest.go index b48e3b753a..2e6e676731 100644 --- a/internal/statsdtest/statsdtest.go +++ b/internal/statsdtest/statsdtest.go @@ -62,6 +62,10 @@ func (tg *TestStatsdClient) Gauge(name string, value float64, tags []string, rat }) } +func (tg *TestStatsdClient) GaugeWithTimestamp(name string, value float64, tags []string, rate float64, timestamp time.Time) error { + panic("not implemented yet") +} + func (tg *TestStatsdClient) Incr(name string, tags []string, rate float64) error { tg.addCount(name, 1) return tg.addMetric(callTypeIncr, tags, TestStatsdCall{ @@ -81,6 +85,10 @@ func (tg *TestStatsdClient) Count(name string, value int64, tags []string, rate }) } +func (tg *TestStatsdClient) CountWithTimestamp(name string, value int64, tags []string, rate float64, timestamp time.Time) error { + panic("not implemented yet") +} + func (tg *TestStatsdClient) Timing(name string, value time.Duration, tags []string, rate float64) error { return tg.addMetric(callTypeTiming, tags, TestStatsdCall{ name: name, From fdd5e082d6fa3e0d9bddcd027bb7ea0100c8b55a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Wed, 28 Aug 2024 19:27:51 +0200 Subject: [PATCH 2/7] fix: test failure b/c of global log level leak --- ddtrace/tracer/tracer_test.go | 2 ++ internal/log/log.go | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index 19835db105..decf4407ea 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -2126,6 +2126,7 @@ func BenchmarkGenSpanID(b *testing.B) { // startTestTracer returns a Tracer with a DummyTransport func startTestTracer(t testing.TB, opts ...StartOption) (trc *tracer, transport *dummyTransport, flush func(n int), stop func()) { + oldLevel := log.GetLevel() transport = newDummyTransport() tick := make(chan time.Time) o := append([]StartOption{ @@ -2160,6 +2161,7 @@ func startTestTracer(t testing.TB, opts ...StartOption) (trc *tracer, transport tracer.Stop() // clear any service name that was set: we want the state to be the same as startup globalconfig.SetServiceName("") + log.SetLevel(oldLevel) // avoids test failures because of global state } } diff --git a/internal/log/log.go b/internal/log/log.go index 16be1ac7d0..383975147f 100644 --- a/internal/log/log.go +++ b/internal/log/log.go @@ -65,6 +65,13 @@ func SetLevel(lvl Level) { level = lvl } +// GetLevel returns the currrent log level. +func GetLevel() Level { + mu.Lock() + defer mu.Unlock() + return level +} + // DebugEnabled returns true if debug log messages are enabled. This can be used in extremely // hot code paths to avoid allocating the ...interface{} argument. func DebugEnabled() bool { From 12769848ddeff1686bff0becd2a917a508b39bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Wed, 28 Aug 2024 22:22:10 +0200 Subject: [PATCH 3/7] fix internal apps --- internal/apps/go.mod | 7 ++++--- internal/apps/go.sum | 14 ++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/internal/apps/go.mod b/internal/apps/go.mod index 2aebc0aee2..dbc49a99ca 100644 --- a/internal/apps/go.mod +++ b/internal/apps/go.mod @@ -3,13 +3,14 @@ module github.com/DataDog/dd-trace-go/internal/apps go 1.21 require ( - golang.org/x/sync v0.5.0 + golang.org/x/sync v0.6.0 gopkg.in/DataDog/dd-trace-go.v1 v1.64.0 ) require ( github.com/DataDog/appsec-internal-go v1.7.0 // indirect github.com/DataDog/go-libddwaf/v3 v3.3.0 // indirect + github.com/DataDog/go-runtime-metrics-internal v0.0.0-20240819080326-9964da68e4b5 // 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 @@ -23,8 +24,8 @@ require ( github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/mod v0.16.0 // indirect + golang.org/x/tools v0.19.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/apps/go.sum b/internal/apps/go.sum index 0e6e942134..5a8ec755b1 100644 --- a/internal/apps/go.sum +++ b/internal/apps/go.sum @@ -8,6 +8,8 @@ github.com/DataDog/datadog-go/v5 v5.3.0 h1:2q2qjFOb3RwAZNU+ez27ZVDwErJv5/VpbBPpr github.com/DataDog/datadog-go/v5 v5.3.0/go.mod h1:XRDJk1pTc00gm+ZDiBKsjh7oOOtJfYfglVCmFb8C2+Q= github.com/DataDog/go-libddwaf/v3 v3.3.0 h1:jS72fuQpFgJZEdEJDmHJCPAgNTEMZoz1EUvimPUOiJ4= github.com/DataDog/go-libddwaf/v3 v3.3.0/go.mod h1:Bz/0JkpGf689mzbUjKJeheJINqsyyhM8p9PDuHdK2Ec= +github.com/DataDog/go-runtime-metrics-internal v0.0.0-20240819080326-9964da68e4b5 h1:2S3vDq1CtlmVMdq0+7TIwYKUSDJmBEsaB9gdnGI52yE= +github.com/DataDog/go-runtime-metrics-internal v0.0.0-20240819080326-9964da68e4b5/go.mod h1:quaQJ+wPN41xEC458FCpTwyROZm3MzmTZ8q8XOXQiPs= github.com/DataDog/go-tuf v1.0.2-0.5.2 h1:EeZr937eKAWPxJ26IykAdWA4A0jQXJgkhUjqEI/w7+I= github.com/DataDog/go-tuf v1.0.2-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= @@ -135,8 +137,8 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -147,8 +149,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -178,8 +180,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From b070f109829670f992b086515d3e52dcaa829c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Wed, 28 Aug 2024 22:31:09 +0200 Subject: [PATCH 4/7] copyright headers --- ddtrace/tracer/slog.go | 5 +++++ ddtrace/tracer/slog_test.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ddtrace/tracer/slog.go b/ddtrace/tracer/slog.go index 09015eb14f..06a477d02d 100644 --- a/ddtrace/tracer/slog.go +++ b/ddtrace/tracer/slog.go @@ -1,3 +1,8 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2024 Datadog, Inc. + package tracer import ( diff --git a/ddtrace/tracer/slog_test.go b/ddtrace/tracer/slog_test.go index c04c028760..9030a8bda5 100644 --- a/ddtrace/tracer/slog_test.go +++ b/ddtrace/tracer/slog_test.go @@ -1,3 +1,8 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2024 Datadog, Inc. + package tracer import ( From 2b9ebd051e24d2b93bff9ffbd09cef0441f89db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Wed, 28 Aug 2024 22:39:58 +0200 Subject: [PATCH 5/7] fix one more log level leak --- ddtrace/tracer/log_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ddtrace/tracer/log_test.go b/ddtrace/tracer/log_test.go index f91047c8bd..e49e6c56f5 100644 --- a/ddtrace/tracer/log_test.go +++ b/ddtrace/tracer/log_test.go @@ -179,8 +179,9 @@ func TestLogAgentReachable(t *testing.T) { func TestLogFormat(t *testing.T) { assert := assert.New(t) tp := new(log.RecordLogger) - tracer := newTracer(WithLogger(tp), WithRuntimeMetrics(), WithDebugMode(true)) - defer tracer.Stop() + + tracer, _, _, stop := startTestTracer(t, WithLogger(tp), WithRuntimeMetrics(), WithDebugMode(true)) + defer stop() tp.Reset() tp.Ignore("appsec: ", telemetry.LogPrefix) tracer.StartSpan("test", ServiceName("test-service"), ResourceName("/"), WithSpanID(12345)) From 160885f926c52fd9cfe50765c6e4661475babe5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Wed, 28 Aug 2024 22:43:46 +0200 Subject: [PATCH 6/7] one more go.mod --- internal/exectracetest/go.mod | 1 + internal/exectracetest/go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/internal/exectracetest/go.mod b/internal/exectracetest/go.mod index e5573375e9..2cf127f51a 100644 --- a/internal/exectracetest/go.mod +++ b/internal/exectracetest/go.mod @@ -17,6 +17,7 @@ require ( github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.1 // indirect github.com/DataDog/datadog-go/v5 v5.3.0 // indirect github.com/DataDog/go-libddwaf/v3 v3.3.0 // indirect + github.com/DataDog/go-runtime-metrics-internal v0.0.0-20240819080326-9964da68e4b5 // indirect github.com/DataDog/go-tuf v1.0.2-0.5.2 // indirect github.com/DataDog/sketches-go v1.4.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect diff --git a/internal/exectracetest/go.sum b/internal/exectracetest/go.sum index 1f817550c2..0473e4d34a 100644 --- a/internal/exectracetest/go.sum +++ b/internal/exectracetest/go.sum @@ -8,6 +8,8 @@ github.com/DataDog/datadog-go/v5 v5.3.0 h1:2q2qjFOb3RwAZNU+ez27ZVDwErJv5/VpbBPpr github.com/DataDog/datadog-go/v5 v5.3.0/go.mod h1:XRDJk1pTc00gm+ZDiBKsjh7oOOtJfYfglVCmFb8C2+Q= github.com/DataDog/go-libddwaf/v3 v3.3.0 h1:jS72fuQpFgJZEdEJDmHJCPAgNTEMZoz1EUvimPUOiJ4= github.com/DataDog/go-libddwaf/v3 v3.3.0/go.mod h1:Bz/0JkpGf689mzbUjKJeheJINqsyyhM8p9PDuHdK2Ec= +github.com/DataDog/go-runtime-metrics-internal v0.0.0-20240819080326-9964da68e4b5 h1:2S3vDq1CtlmVMdq0+7TIwYKUSDJmBEsaB9gdnGI52yE= +github.com/DataDog/go-runtime-metrics-internal v0.0.0-20240819080326-9964da68e4b5/go.mod h1:quaQJ+wPN41xEC458FCpTwyROZm3MzmTZ8q8XOXQiPs= github.com/DataDog/go-tuf v1.0.2-0.5.2 h1:EeZr937eKAWPxJ26IykAdWA4A0jQXJgkhUjqEI/w7+I= github.com/DataDog/go-tuf v1.0.2-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= From 535a60aac489ce467b4059e8158540b344d1ab5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Wed, 23 Oct 2024 15:52:16 +0200 Subject: [PATCH 7/7] fix global state pollution in a better way --- ddtrace/tracer/slog_test.go | 7 +++++++ ddtrace/tracer/tracer_test.go | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ddtrace/tracer/slog_test.go b/ddtrace/tracer/slog_test.go index 9030a8bda5..352cac0183 100644 --- a/ddtrace/tracer/slog_test.go +++ b/ddtrace/tracer/slog_test.go @@ -19,6 +19,13 @@ func Test_slogHandler(t *testing.T) { rl := &log.RecordLogger{} defer log.UseLogger(rl)() + // Ensure the logger is set to the default level. This may not be the case + // when previous tests pollute the global state. We leave the logger in the + // state we found it to not contribute to this pollution ourselves. + oldLevel := log.GetLevel() + log.SetLevel(log.LevelWarn) + defer log.SetLevel(oldLevel) + // Log a few messages at different levels. The debug message gets discarded // because the internal logger does not have debug enabled by default. l := slog.New(slogHandler{}) diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index dc88eb1323..2c57d08b4d 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -2147,7 +2147,6 @@ func BenchmarkGenSpanID(b *testing.B) { // startTestTracer returns a Tracer with a DummyTransport func startTestTracer(t testing.TB, opts ...StartOption) (trc *tracer, transport *dummyTransport, flush func(n int), stop func()) { - oldLevel := log.GetLevel() transport = newDummyTransport() tick := make(chan time.Time) o := append([]StartOption{ @@ -2182,7 +2181,6 @@ func startTestTracer(t testing.TB, opts ...StartOption) (trc *tracer, transport tracer.Stop() // clear any service name that was set: we want the state to be the same as startup globalconfig.SetServiceName("") - log.SetLevel(oldLevel) // avoids test failures because of global state } }