diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 4e122bd74..20cb184c7 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -4,11 +4,14 @@ core,dario.cat/mergo,BSD-3-Clause core,github.com/Azure/go-ansiterm,MIT core,github.com/BurntSushi/toml,MIT core,github.com/DataDog/appsec-internal-go,Apache-2.0 +core,github.com/DataDog/datadog-agent/comp/core/tagger/origindetection,Apache-2.0 core,github.com/DataDog/datadog-agent/pkg/config/model,Apache-2.0 core,github.com/DataDog/datadog-agent/pkg/config/remote,Apache-2.0 core,github.com/DataDog/datadog-agent/pkg/obfuscate,Apache-2.0 +core,github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes,Apache-2.0 core,github.com/DataDog/datadog-agent/pkg/proto,Apache-2.0 core,github.com/DataDog/datadog-agent/pkg/remoteconfig/state,Apache-2.0 +core,github.com/DataDog/datadog-agent/pkg/trace,Apache-2.0 core,github.com/DataDog/datadog-agent/pkg/util/backoff,Apache-2.0 core,github.com/DataDog/datadog-agent/pkg/util/cache,Apache-2.0 core,github.com/DataDog/datadog-agent/pkg/util/grpc,Apache-2.0 @@ -24,8 +27,11 @@ core,github.com/DataDog/datadog-operator/api/datadoghq/common,Unknown core,github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1,Unknown core,github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1,Unknown core,github.com/DataDog/datadog-operator/api/utils,Unknown +core,github.com/DataDog/dd-trace-go/v2,Apache-2.0 core,github.com/DataDog/extendeddaemonset/api/v1alpha1,Apache-2.0 core,github.com/DataDog/go-libddwaf/v3,Apache-2.0 +core,github.com/DataDog/go-libddwaf/v4,Apache-2.0 +core,github.com/DataDog/go-runtime-metrics-internal/pkg/runtimemetrics,Apache-2.0 core,github.com/DataDog/go-sqllexer,MIT core,github.com/DataDog/go-tuf,BSD-3-Clause core,github.com/DataDog/gostackparse,Apache-2.0 @@ -68,6 +74,7 @@ core,github.com/beorn7/perks/quantile,MIT core,github.com/blang/semver/v4,MIT core,github.com/cenkalti/backoff,MIT core,github.com/cenkalti/backoff/v4,MIT +core,github.com/cenkalti/backoff/v5,MIT core,github.com/cespare/xxhash/v2,MIT core,github.com/chai2010/gettext-go,BSD-3-Clause core,github.com/cihub/seelog,BSD-3-Clause @@ -79,6 +86,7 @@ core,github.com/cyphar/filepath-securejoin,BSD-3-Clause core,github.com/davecgh/go-spew/spew,ISC core,github.com/dsnet/compress,BSD-3-Clause core,github.com/dustin/go-humanize,MIT +core,github.com/ebitengine/purego,Apache-2.0 core,github.com/emicklei/go-restful/v3,MIT core,github.com/evanphx/json-patch,BSD-3-Clause core,github.com/evanphx/json-patch/v5,BSD-3-Clause @@ -122,13 +130,13 @@ core,github.com/gosuri/uitable,MIT core,github.com/gosuri/uitable/util/wordwrap,MIT core,github.com/gregjones/httpcache,MIT core,github.com/grpc-ecosystem/go-grpc-middleware,Apache-2.0 -core,github.com/grpc-ecosystem/grpc-gateway,BSD-3-Clause core,github.com/grpc-ecosystem/grpc-gateway/v2,BSD-3-Clause core,github.com/hako/durafmt,MIT core,github.com/hashicorp/errwrap,MPL-2.0 core,github.com/hashicorp/go-cleanhttp,MPL-2.0 core,github.com/hashicorp/go-multierror,MPL-2.0 core,github.com/hashicorp/go-retryablehttp,MPL-2.0 +core,github.com/hashicorp/go-version,MPL-2.0 core,github.com/hashicorp/hcl,MPL-2.0 core,github.com/huandu/xstrings,MIT core,github.com/inconshreveable/mousetrap,Apache-2.0 @@ -136,6 +144,7 @@ core,github.com/jmoiron/sqlx,MIT core,github.com/json-iterator/go,MIT core,github.com/klauspost/compress,Apache-2.0 core,github.com/klauspost/compress/internal/snapref,BSD-3-Clause +core,github.com/klauspost/compress/s2,BSD-3-Clause core,github.com/klauspost/compress/zstd/internal/xxhash,MIT core,github.com/klauspost/pgzip,MIT core,github.com/lann/builder,MIT @@ -147,6 +156,7 @@ core,github.com/mattn/go-colorable,MIT core,github.com/mattn/go-isatty,MIT core,github.com/mattn/go-runewidth,MIT core,github.com/mholt/archiver/v3,MIT +core,github.com/minio/simdjson-go,Apache-2.0 core,github.com/mitchellh/copystructure,MIT core,github.com/mitchellh/go-wordwrap,MIT core,github.com/mitchellh/hashstructure/v2,MIT @@ -173,12 +183,14 @@ core,github.com/philhofer/fwd,MIT core,github.com/pierrec/lz4/v4,BSD-3-Clause core,github.com/pkg/browser,BSD-2-Clause core,github.com/pkg/errors,BSD-2-Clause +core,github.com/planetscale/vtprotobuf/protohelpers,BSD-3-Clause core,github.com/pmezard/go-difflib/difflib,BSD-3-Clause core,github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil,BSD-3-Clause core,github.com/prometheus/client_golang/prometheus,Apache-2.0 core,github.com/prometheus/client_model/go,Apache-2.0 core,github.com/prometheus/common,Apache-2.0 core,github.com/prometheus/procfs,Apache-2.0 +core,github.com/puzpuzpuz/xsync/v3,Apache-2.0 core,github.com/richardartoul/molecule,MIT core,github.com/richardartoul/molecule/src/codec,Apache-2.0 core,github.com/richardartoul/molecule/src/protowire,BSD-3-Clause @@ -191,6 +203,7 @@ core,github.com/samber/lo,MIT core,github.com/santhosh-tekuri/jsonschema/v6,Apache-2.0 core,github.com/secure-systems-lab/go-securesystemslib/cjson,MIT core,github.com/shirou/gopsutil/v3,BSD-3-Clause +core,github.com/shirou/gopsutil/v4,BSD-3-Clause core,github.com/shoenig/go-m1cpu,MPL-2.0 core,github.com/shopspring/decimal,MIT core,github.com/sirupsen/logrus,MIT @@ -205,16 +218,25 @@ core,github.com/stretchr/objx,MIT core,github.com/stretchr/testify,MIT core,github.com/tinylib/msgp/msgp,MIT core,github.com/tklauser/go-sysconf,BSD-3-Clause +core,github.com/tklauser/numcpus,Apache-2.0 +core,github.com/trailofbits/go-mutexasserts,MIT core,github.com/ulikunitz/xz,BSD-3-Clause core,github.com/x448/float16,MIT core,github.com/xi2/xz,Unknown core,github.com/xlab/treeprint,MIT core,go.etcd.io/bbolt,MIT core,go.opentelemetry.io/auto/sdk,Apache-2.0 +core,go.opentelemetry.io/collector/component,Apache-2.0 +core,go.opentelemetry.io/collector/featuregate,Apache-2.0 +core,go.opentelemetry.io/collector/internal/telemetry,Apache-2.0 +core,go.opentelemetry.io/collector/pdata,Apache-2.0 +core,go.opentelemetry.io/collector/pdata/pprofile,Apache-2.0 +core,go.opentelemetry.io/contrib/bridges/otelzap,Apache-2.0 core,go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp,Apache-2.0 core,go.opentelemetry.io/otel,Apache-2.0 core,go.opentelemetry.io/otel/exporters/otlp/otlptrace,Apache-2.0 core,go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc,Apache-2.0 +core,go.opentelemetry.io/otel/log,Apache-2.0 core,go.opentelemetry.io/otel/metric,Apache-2.0 core,go.opentelemetry.io/otel/sdk,Apache-2.0 core,go.opentelemetry.io/otel/trace,Apache-2.0 @@ -225,7 +247,7 @@ core,go.uber.org/zap,MIT core,go.yaml.in/yaml/v2,Apache-2.0 core,go.yaml.in/yaml/v3,MIT core,golang.org/x/crypto,BSD-3-Clause -core,golang.org/x/exp/slices,BSD-3-Clause +core,golang.org/x/exp,BSD-3-Clause core,golang.org/x/mod/semver,BSD-3-Clause core,golang.org/x/net,BSD-3-Clause core,golang.org/x/oauth2,BSD-3-Clause @@ -239,12 +261,12 @@ core,golang.org/x/xerrors,BSD-3-Clause core,gomodules.xyz/jsonpatch/v2,Apache-2.0 core,google.golang.org/genproto/googleapis/api,Apache-2.0 core,google.golang.org/genproto/googleapis/rpc,Apache-2.0 -core,google.golang.org/genproto/protobuf/field_mask,Apache-2.0 core,google.golang.org/grpc,Apache-2.0 core,google.golang.org/protobuf,BSD-3-Clause core,gopkg.in/DataDog/dd-trace-go.v1,Apache-2.0 core,gopkg.in/evanphx/json-patch.v4,BSD-3-Clause core,gopkg.in/inf.v0,BSD-3-Clause +core,gopkg.in/ini.v1,Apache-2.0 core,gopkg.in/yaml.v2,Apache-2.0 core,gopkg.in/yaml.v3,MIT core,helm.sh/helm/v3,Apache-2.0 diff --git a/cmd/main.go b/cmd/main.go index fa42adce0..1bbe45fa3 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -15,11 +15,11 @@ import ( "sync/atomic" "time" + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" edsdatadoghqv1alpha1 "github.com/DataDog/extendeddaemonset/api/v1alpha1" "github.com/go-logr/logr" "go.uber.org/zap" "go.uber.org/zap/zapcore" - "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" "gopkg.in/DataDog/dd-trace-go.v1/profiler" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -154,8 +154,8 @@ func (opts *options) Parse() { // Observability flags flag.StringVar(&opts.metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") flag.BoolVar(&opts.secureMetrics, "metrics-secure", false, "If true, the metrics endpoint is served securely via HTTPS. Use false to use HTTP instead.") - flag.BoolVar(&opts.profilingEnabled, "profiling-enabled", false, "Enable Datadog profile in the Datadog Operator process.") - flag.BoolVar(&opts.tracingEnabled, "tracing-enabled", false, "Enable Datadog APM tracing in the Datadog Operator process.") + flag.BoolVar(&opts.profilingEnabled, "profiling-enabled", os.Getenv("DD_OPERATOR_PROFILING_ENABLED") == "true", "Enable Datadog profiling in the Datadog Operator process.") + flag.BoolVar(&opts.tracingEnabled, "tracing-enabled", os.Getenv("DD_OPERATOR_TRACING_ENABLED") == "true", "Enable Datadog APM tracing in the Datadog Operator process.") opts.logLevel = zap.LevelFlag("loglevel", zapcore.InfoLevel, "Set log level") flag.StringVar(&opts.logEncoder, "logEncoder", "json", "log encoding ('json' or 'console')") flag.BoolVar(&opts.printVersion, "version", false, "Print version and exit") @@ -256,11 +256,16 @@ func run(opts *options) error { if opts.tracingEnabled { setupLog.Info("Starting datadog APM tracer") - tracer.Start( + if err := tracer.Start( tracer.WithService("datadog-operator"), tracer.WithServiceVersion(version.Version), - ) - defer tracer.Stop() + tracer.WithGlobalTag("git.repository_url", "https://github.com/DataDog/datadog-operator"), + ); err != nil { + setupLog.Error(err, "Failed to start datadog APM tracer, continuing without tracing") + opts.tracingEnabled = false + } else { + defer tracer.Stop() + } } // Dispatch CLI flags to each package diff --git a/go.work.sum b/go.work.sum index 94ef8ec7e..aea32ae47 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,6 +1,7 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898 h1:SC+c6A1qTFstO9qmB86mPV2IpYme/2ZoEQ0hrP+wo+Q= cel.dev/expr v0.16.2/go.mod h1:gXngZQMkWJoSbE8mOzehJlXQyubn/Vg0vR9/F3W7iw8= cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc= cloud.google.com/go/accessapproval v1.8.0 h1:DLU5ua2WQXvdUL6yd/D4XFPXyd6acv1hNJJBMdt6Fh0= cloud.google.com/go/accessapproval v1.8.0/go.mod h1:ycc7qSIXOrH6gGOGQsuBwpRZw3QhZLi0OWeej3rA5Mg= @@ -56,6 +57,7 @@ cloud.google.com/go/clouddms v1.8.0 h1:BBPvI//wT1n3ruqVGDgCxBdpu9/era/b3B/HsiY8S cloud.google.com/go/clouddms v1.8.0/go.mod h1:JUgTgqd1M9iPa7p3jodjLTuecdkGTcikrg7nz++XB5E= cloud.google.com/go/cloudtasks v1.13.0 h1:rKVSsQwh0CI68n3RalLoGuW7sOtq2eil2gVZK4Pyi40= cloud.google.com/go/cloudtasks v1.13.0/go.mod h1:O1jFRGb1Vm3sN2u/tBdPiVGVTWIsrsbEs3K3N3nNlEU= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute v1.28.0/go.mod h1:DEqZBtYrDnD5PvjsKwb3onnhX+qjdCVM7eshj1XdjV4= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/contactcenterinsights v1.14.0 h1:hZSiEb53tyULmOSBlDPhEWPEe+vQ0F2gPQjOka1E5oE= @@ -120,6 +122,7 @@ cloud.google.com/go/grafeas v0.3.10 h1:D9uP/DjVHq9ZzCekVd+aNvQEHb3Hkwp8ki9FDnhRR cloud.google.com/go/grafeas v0.3.10/go.mod h1:Mz/AoXmxNhj74VW0fz5Idc3kMN2VZMi4UT5+UPx5Pq0= cloud.google.com/go/gsuiteaddons v1.7.0 h1:k+DNTzjW+hG+lfGsNbNCopicaUIyT0Q4B0xLYCwEnpo= cloud.google.com/go/gsuiteaddons v1.7.0/go.mod h1:/B1L8ANPbiSvxCgdSwqH9CqHIJBzTt6v50fPr3vJCtg= +cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= cloud.google.com/go/iam v1.2.0 h1:kZKMKVNk/IsSSc/udOb83K0hL/Yh/Gcqpz+oAkoIFN8= cloud.google.com/go/iam v1.2.0/go.mod h1:zITGuWgsLZxd8OwAlX+eMFgZDXzBm7icj1PVTYG766Q= cloud.google.com/go/iap v1.10.0 h1:Er5DF68/1MMBQo62Vfs3XvOPmyqj9JgQniSCNKLHYK8= @@ -174,6 +177,7 @@ cloud.google.com/go/policytroubleshooter v1.11.0 h1:TUxMBu2SAWmo8RtWhKcgv7LjbmUE cloud.google.com/go/policytroubleshooter v1.11.0/go.mod h1:yTqY8n60lPLdU5bRbImn9IazrmF1o5b0VBshVxPzblQ= cloud.google.com/go/privatecatalog v0.10.0 h1:9ZescTLuQE6idHyXAGh7nDxer8UJXfACW7DLIuhtvOs= cloud.google.com/go/privatecatalog v0.10.0/go.mod h1:/Lci3oPTxJpixjiTBoiVv3PmUZg/IdhPvKHcLEgObuc= +cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= cloud.google.com/go/pubsub v1.42.0 h1:PVTbzorLryFL5ue8esTS2BfehUs0ahyNOY9qcd+HMOs= cloud.google.com/go/pubsub v1.42.0/go.mod h1:KADJ6s4MbTwhXmse/50SebEhE4SmUwHi48z3/dHar1Y= cloud.google.com/go/pubsublite v1.8.2 h1:jLQozsEVr+c6tOU13vDugtnaBSUy/PD5zK6mhm+uF1Y= @@ -297,8 +301,15 @@ github.com/DataDog/datadog-agent/comp/core/tagger/utils v0.63.0-rc.1 h1:0H4x+Yx2 github.com/DataDog/datadog-agent/comp/core/tagger/utils v0.63.0-rc.1/go.mod h1:Dsx/DPworzF825CKFUa63voyxkbukZT19xmnwWabvvQ= github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def v0.63.0-rc.1 h1:F0tmip+yd38HtgHeoIbCx+lekwWPsiW2Das9QgzNdow= github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def v0.63.0-rc.1/go.mod h1:jCFmzEJDYFnjE6FNEXgr90mNoD0dIW4HiiLx2CaINig= +github.com/DataDog/datadog-agent/comp/trace/compression/def v0.71.0/go.mod h1:YZChPRJGbiW+jjZ6k3ZiY0WilBzBOQwvYbH+16Pa9H0= +github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip v0.71.0/go.mod h1:wqpWgCXg73YUhT6uMoTpTAH6j8LaEgvy9Iky3wiDmvU= +github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd v0.71.0/go.mod h1:Obi3j7t0xzOJBMezJ5f+jPbnaDqLj+Dc1U06FqTnLeY= +github.com/DataDog/datadog-agent/pkg/api v0.71.0/go.mod h1:k8/tuu1rgOpdLD+A9v1j9wM4eLwP6CrlaAu0n2n5SJc= +github.com/DataDog/datadog-agent/pkg/template v0.71.0/go.mod h1:mpV3MbF/us0LdM3tvVHDztjApy3VWGeu5RuS/MpGVHQ= github.com/DataDog/datadog-agent/pkg/trace v0.63.0-rc.1 h1:8xSnvGrJoEr1vtsUG/FzDwvlL7RQR1ZjEtQAOyt1rz8= github.com/DataDog/datadog-agent/pkg/trace v0.63.0-rc.1/go.mod h1:107rqQNihdwkVbmF/DEIeJbGmQOrXns+xiOUnz4qAaU= +github.com/DataDog/datadog-agent/pkg/util/cgroups v0.71.0/go.mod h1:0aOukuEPgxYjfNapCdk/F1loXGGJ0bUvuHRa/KEXrPY= +github.com/DataDog/datadog-agent/pkg/util/pointer v0.71.0/go.mod h1:9nP4HNOKZszsv8YoCe16xQ5XPKgitPaWBjgCJQC0+jk= github.com/DataDog/datadog-agent/pkg/util/testutil v0.63.0-rc.1 h1:3Ct/38ONls2/g/diTNkYHzwqc7xZsw7PFyNkuH/gdfE= github.com/DataDog/datadog-agent/pkg/util/testutil v0.63.0-rc.1/go.mod h1:y1l7iTMENfjfgV4L3a5RtsMiQAVeu6B/0SEo6A8XDFQ= github.com/DataDog/datadog-api-client-go v1.16.0 h1:5jOZv1m98criCvYTa3qpW8Hzv301nbZX3K9yJtwGyWY= @@ -309,6 +320,7 @@ github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0/go.mod h1:dppbR7CwXD4p github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2 h1:cZpsGsWTIFKymTA0je7IIvi1O7Es7apb9CF3EQlOcfE= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2/go.mod h1:itPGVDKf9cC/ov4MdvJ2QZ0khw4bfoo9jzwTJlaxy2k= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0/go.mod h1:2bIszWvQRlJVmJLiuLhukLImRjKPcYdzzsx6darK02A= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= github.com/IBM/sarama v1.40.0 h1:QTVmX+gMKye52mT5x+Ve/Bod2D0Gy7ylE2Wslv+RHtc= github.com/IBM/sarama v1.40.0/go.mod h1:6pBloAs1WanL/vsq5qFTyTGulJUntZHhMLOUYEIs9mg= github.com/Masterminds/sprig/v3 v3.2.1 h1:n6EPaDyLSvCEa3frruQvAiHuNp2dhBlMSmkEr+HuzGc= @@ -459,6 +471,7 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLje github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= @@ -627,6 +640,7 @@ github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQr github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= +github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo= github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= @@ -693,6 +707,7 @@ github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws= github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= @@ -873,6 +888,7 @@ github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUU github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/leeavital/protoc-gen-gostreamer v0.1.0/go.mod h1:sC19nxpNkHy3enGT3ck6LTr5mittUoUXE/elp/mnTS4= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= @@ -964,6 +980,7 @@ github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16A github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= +github.com/open-feature/go-sdk v1.17.0/go.mod h1:lPxPSu1UnZ4E3dCxZi5gV3et2ACi8O8P+zsTGVsDZUw= github.com/opencontainers/runc v1.0.0-rc93 h1:x2UMpOOVf3kQ8arv/EsDGwim8PTNqzL1/EYDr/+scOM= github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d h1:pNa8metDkwZjb9g4T8s+krQ+HRgZAkqnXml+wNir/+s= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= @@ -1016,6 +1033,7 @@ github.com/pulumi/pulumi-libvirt/sdk v0.5.4 h1:7nS8ATK0Iml+yid80BrkW8WDynzwWYevx github.com/pulumi/pulumi-libvirt/sdk v0.5.4/go.mod h1:HPx6S9mhaHpSHTKDVERTMaziKEpSqY8Trm+m2z1iJ3k= github.com/pulumi/pulumi/pkg/v3 v3.137.0 h1:/KPFQQaB5W0/GhVxSTGnEzv3ZW5uieGN5Q2q+Lsr+Zw= github.com/pulumi/pulumi/pkg/v3 v3.137.0/go.mod h1:ZQXJUTysDwq/mtilutRBKguH6DI+3b2WgNcOrs0whJ0= +github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY= @@ -1199,8 +1217,10 @@ go.opentelemetry.io/collector/pdata v1.24.0/go.mod h1:cf3/W9E/uIvPS4MR26SnMFJhra go.opentelemetry.io/contrib/detectors/gcp v1.31.0 h1:G1JQOreVrfhRkner+l4mrGxmfqYCAuy76asTDAo0xsA= go.opentelemetry.io/contrib/detectors/gcp v1.31.0/go.mod h1:tzQL6E1l+iV44YFTkcAeNQqzXUiekSYP9jjJjXwEd00= go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= +go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/contrib/otelconf v0.17.0/go.mod h1:8dHKS6uMiZlvmrA7MGUtb4HwnX+ukdF5iS3p2UPKvLE= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= @@ -1218,6 +1238,7 @@ go.starlark.net v0.0.0-20231101134539-556fd59b42f6 h1:+eC0F/k4aBLC4szgOcjd7bDTEn go.starlark.net v0.0.0-20231101134539-556fd59b42f6/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= gocloud.dev v0.37.0 h1:XF1rN6R0qZI/9DYjN16Uy0durAmSlf58DHOcb28GPro= gocloud.dev v0.37.0/go.mod h1:7/O4kqdInCNsc6LqgmuFnS0GRew4XNNYWpA44yQnwco= @@ -1314,6 +1335,7 @@ google.golang.org/api v0.194.0 h1:dztZKG9HgtIpbI35FhfuSNR/zmaMVdxNlntHj1sIS4s= google.golang.org/api v0.194.0/go.mod h1:AgvUFdojGANh3vI+P7EVnxj3AISHllxGCJSFmggmnd0= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 h1:Cpp2P6TPjujNoC5M2KHY6g7wfyLYfIWRZaSdIKfDasA= google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg= +google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= diff --git a/internal/controller/datadogagent/controller_reconcile_v2.go b/internal/controller/datadogagent/controller_reconcile_v2.go index 06f7c339b..102f3c128 100644 --- a/internal/controller/datadogagent/controller_reconcile_v2.go +++ b/internal/controller/datadogagent/controller_reconcile_v2.go @@ -9,6 +9,7 @@ import ( "context" "time" + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -27,21 +28,41 @@ import ( "github.com/DataDog/datadog-operator/pkg/controller/utils" pkgutils "github.com/DataDog/datadog-operator/pkg/controller/utils/datadog" "github.com/DataDog/datadog-operator/pkg/kubernetes" + "github.com/DataDog/datadog-operator/pkg/trace" ) func (r *Reconciler) internalReconcileV2(ctx context.Context, instance *datadoghqv2alpha1.DatadogAgent) (reconcile.Result, error) { + span, ctx := startDDASpan(ctx) + var reconcileErr error + defer func() { span.Finish(tracer.WithError(reconcileErr)) }() + reqLogger := r.log.WithValues("datadogagent", pkgutils.GetNamespacedName(instance)) reqLogger.Info("Reconciling DatadogAgent") var result reconcile.Result // 1. Validate the resource. - if err := datadoghqv2alpha1.ValidateDatadogAgent(instance); err != nil { - return result, err + { + vSpan, vCtx := trace.StartControllerSpan(ctx, "validateDatadogAgent") + _ = vCtx // validation is CPU-only, no sub-calls need the child context + err := datadoghqv2alpha1.ValidateDatadogAgent(instance) + vSpan.Finish(tracer.WithError(err)) + if err != nil { + reconcileErr = err + return result, err + } } // 2. Handle finalizer logic. - if result, err := r.handleFinalizer(reqLogger, instance, r.finalizeDadV2); utils.ShouldReturn(result, err) { - return result, err + { + fSpan, fCtx := trace.StartControllerSpan(ctx, "handleFinalizer") + _ = fCtx // handleFinalizer takes a logger, not ctx + var err error + result, err = r.handleFinalizer(reqLogger, instance, r.finalizeDadV2) + fSpan.Finish(tracer.WithError(err)) + if utils.ShouldReturn(result, err) { + reconcileErr = err + return result, err + } } // 3. Set default values for GlobalConfig and Features @@ -50,16 +71,23 @@ func (r *Reconciler) internalReconcileV2(ctx context.Context, instance *datadogh // 4. Delegate to the main reconcile function. if r.options.DatadogAgentInternalEnabled { - return r.reconcileInstanceV3(ctx, reqLogger, instanceCopy) + result, reconcileErr = r.reconcileInstanceV3(ctx, reqLogger, instanceCopy) + return result, reconcileErr } - return r.reconcileInstanceV2(ctx, reqLogger, instanceCopy) + result, reconcileErr = r.reconcileInstanceV2(ctx, reqLogger, instanceCopy) + return result, reconcileErr } func (r *Reconciler) reconcileInstanceV3(ctx context.Context, logger logr.Logger, instance *datadoghqv2alpha1.DatadogAgent) (reconcile.Result, error) { + span, ctx := startDDASpan(ctx) + var reconcileErr error + defer func() { span.Finish(tracer.WithError(reconcileErr)) }() + // Set up field manager for crd apply if r.fieldManager == nil { f, err := newFieldManager(r.client, r.scheme, getDDAIGVK()) if err != nil { + reconcileErr = err return reconcile.Result{}, err } r.fieldManager = f @@ -72,14 +100,28 @@ func (r *Reconciler) reconcileInstanceV3(ctx context.Context, logger logr.Logger newDDAStatus := generateNewStatusFromDDA(ddaStatusCopy) // Manage dependencies - if err := r.manageDDADependenciesWithDDAI(ctx, logger, instance, newDDAStatus); err != nil { - return r.updateStatusIfNeededV2(logger, instance, ddaStatusCopy, result, err, now) + { + dSpan, dCtx := trace.StartControllerSpan(ctx, "manageDDADependenciesWithDDAI") + depErr := r.manageDDADependenciesWithDDAI(dCtx, logger, instance, newDDAStatus) + dSpan.Finish(tracer.WithError(depErr)) + if depErr != nil { + reconcileErr = depErr + return r.updateStatusIfNeededV2(ctx, logger, instance, ddaStatusCopy, result, depErr, now) + } } // Generate default DDAI object from DDA - ddai, err := r.generateDDAIFromDDA(instance) - if err != nil { - return r.updateStatusIfNeededV2(logger, instance, ddaStatusCopy, result, err, now) + var ddai *datadoghqv1alpha1.DatadogAgentInternal + { + gSpan, gCtx := trace.StartControllerSpan(ctx, "generateDDAIFromDDA") + _ = gCtx // generateDDAIFromDDA does not take a context + var genErr error + ddai, genErr = r.generateDDAIFromDDA(instance) + gSpan.Finish(tracer.WithError(genErr)) + if genErr != nil { + reconcileErr = genErr + return r.updateStatusIfNeededV2(ctx, logger, instance, ddaStatusCopy, result, genErr, now) + } } ddais = append(ddais, ddai) @@ -87,48 +129,79 @@ func (r *Reconciler) reconcileInstanceV3(ctx context.Context, logger logr.Logger // TODO: introspection sendProfileEnabledMetric(r.options.DatadogAgentProfileEnabled) if r.options.DatadogAgentProfileEnabled { + pSpan, pCtx := trace.StartControllerSpan(ctx, "reconcileProfiles") dsName := component.GetDaemonSetNameFromDatadogAgent(instance, &instance.Spec) dsNSName := types.NamespacedName{ Namespace: instance.Namespace, Name: dsName, } maxUnavailable := agentprofile.GetMaxUnavailableFromSpecAndEDS(&instance.Spec, &r.options.ExtendedDaemonsetOptions, nil) - appliedProfiles, e := r.reconcileProfiles(ctx, dsNSName, maxUnavailable) + appliedProfiles, e := r.reconcileProfiles(pCtx, dsNSName, maxUnavailable) if e != nil { - return r.updateStatusIfNeededV2(logger, instance, ddaStatusCopy, result, e, now) + pSpan.Finish(tracer.WithError(e)) + reconcileErr = e + return r.updateStatusIfNeededV2(ctx, logger, instance, ddaStatusCopy, result, e, now) } profileDDAIs, e := r.applyProfilesToDDAISpec(ddai, appliedProfiles) if e != nil { - return r.updateStatusIfNeededV2(logger, instance, ddaStatusCopy, result, e, now) + pSpan.Finish(tracer.WithError(e)) + reconcileErr = e + return r.updateStatusIfNeededV2(ctx, logger, instance, ddaStatusCopy, result, e, now) } ddais = profileDDAIs + pSpan.Finish() } // Create or update the DDAI object in k8s - for _, ddai := range ddais { - if e := r.createOrUpdateDDAI(ddai); e != nil { - return r.updateStatusIfNeededV2(logger, instance, ddaStatusCopy, result, e, now) - } + { + cSpan, cCtx := trace.StartControllerSpan(ctx, "createOrUpdateDDAI") + var ddaiErr error + for _, ddai := range ddais { + if e := r.createOrUpdateDDAI(cCtx, ddai); e != nil { + ddaiErr = e + cSpan.Finish(tracer.WithError(ddaiErr)) + reconcileErr = ddaiErr + return r.updateStatusIfNeededV2(ctx, logger, instance, ddaStatusCopy, result, e, now) + } - // Add DDAI status to DDA status - if e := r.addDDAIStatusToDDAStatus(newDDAStatus, ddai.ObjectMeta); e != nil { - return r.updateStatusIfNeededV2(logger, instance, ddaStatusCopy, result, e, now) - } + // Add DDAI status to DDA status + if e := r.addDDAIStatusToDDAStatus(cCtx, newDDAStatus, ddai.ObjectMeta); e != nil { + ddaiErr = e + cSpan.Finish(tracer.WithError(ddaiErr)) + reconcileErr = ddaiErr + return r.updateStatusIfNeededV2(ctx, logger, instance, ddaStatusCopy, result, e, now) + } - // Add DDA remote config status to DDAI status - if res, e := r.addRemoteConfigStatusToDDAIStatus(ctx, newDDAStatus, ddai.ObjectMeta); utils.ShouldReturn(res, e) { - return r.updateStatusIfNeededV2(logger, instance, ddaStatusCopy, result, e, now) + // Add DDA remote config status to DDAI status + if res, e := r.addRemoteConfigStatusToDDAIStatus(cCtx, newDDAStatus, ddai.ObjectMeta); utils.ShouldReturn(res, e) { + ddaiErr = e + cSpan.Finish(tracer.WithError(ddaiErr)) + reconcileErr = ddaiErr + return r.updateStatusIfNeededV2(ctx, logger, instance, ddaStatusCopy, result, e, now) + } } + cSpan.Finish(tracer.WithError(ddaiErr)) } // Clean up unused DDAI objects - if e := r.cleanUpUnusedDDAIs(ctx, ddais); e != nil { - return r.updateStatusIfNeededV2(logger, instance, ddaStatusCopy, result, e, now) + { + clSpan, clCtx := trace.StartControllerSpan(ctx, "cleanUpUnusedDDAIs") + if e := r.cleanUpUnusedDDAIs(clCtx, ddais); e != nil { + clSpan.Finish(tracer.WithError(e)) + reconcileErr = e + return r.updateStatusIfNeededV2(ctx, logger, instance, ddaStatusCopy, result, e, now) + } + clSpan.Finish() } - // Prevent the reconcile loop from stopping by requeueing the DDAI object after a period of time - result.RequeueAfter = defaultRequeuePeriod - return r.updateStatusIfNeededV2(logger, instance, newDDAStatus, result, err, now) + // Update status + { + sSpan, sCtx := trace.StartControllerSpan(ctx, "updateStatusIfNeededV2") + result.RequeueAfter = defaultRequeuePeriod + result, reconcileErr = r.updateStatusIfNeededV2(sCtx, logger, instance, newDDAStatus, result, nil, now) + sSpan.Finish(tracer.WithError(reconcileErr)) + return result, reconcileErr + } } func (r *Reconciler) reconcileInstanceV2(ctx context.Context, logger logr.Logger, instance *datadoghqv2alpha1.DatadogAgent) (reconcile.Result, error) { @@ -175,44 +248,54 @@ func (r *Reconciler) reconcileInstanceV2(ctx context.Context, logger logr.Logger } } + // 1. Manage dependencies var err error - if err = r.manageGlobalDependencies(logger, instance, resourceManagers, requiredComponents); err != nil { - return r.updateStatusIfNeededV2(logger, instance, newStatus, reconcile.Result{}, err, now) - } - if err = r.manageFeatureDependencies(logger, enabledFeatures, resourceManagers, k8sProvider); err != nil { - return r.updateStatusIfNeededV2(logger, instance, newStatus, reconcile.Result{}, err, now) - } - if err = r.overrideDependencies(logger, resourceManagers, instance); err != nil { - return r.updateStatusIfNeededV2(logger, instance, newStatus, reconcile.Result{}, err, now) - } - - // 1. Apply and cleanup dependencies before reconciling components to ensure deps exist at reconciliation time. - if err = r.applyAndCleanupDependencies(ctx, logger, depsStore); err != nil { - return r.updateStatusIfNeededV2(logger, instance, newStatus, reconcile.Result{}, err, now) + { + span, spanCtx := trace.StartControllerSpan(ctx, "manageDependencies") + if err = r.manageGlobalDependencies(logger, instance, resourceManagers, requiredComponents); err != nil { + span.Finish(tracer.WithError(err)) + return r.updateStatusIfNeededV2(ctx, logger, instance, newStatus, reconcile.Result{}, err, now) + } + if err = r.manageFeatureDependencies(logger, enabledFeatures, resourceManagers, k8sProvider); err != nil { + span.Finish(tracer.WithError(err)) + return r.updateStatusIfNeededV2(ctx, logger, instance, newStatus, reconcile.Result{}, err, now) + } + if err = r.overrideDependencies(logger, resourceManagers, instance); err != nil { + span.Finish(tracer.WithError(err)) + return r.updateStatusIfNeededV2(ctx, logger, instance, newStatus, reconcile.Result{}, err, now) + } + if err = r.applyAndCleanupDependencies(spanCtx, logger, depsStore); err != nil { + span.Finish(tracer.WithError(err)) + return r.updateStatusIfNeededV2(ctx, logger, instance, newStatus, reconcile.Result{}, err, now) + } + span.Finish() } // 2. Reconcile each component using the component registry - params := &ReconcileComponentParams{ - Logger: logger, - DDA: instance, - RequiredComponents: requiredComponents, - Features: append(configuredFeatures, enabledFeatures...), - ResourceManagers: resourceManagers, - Status: newStatus, - Provider: k8sProvider, - ProviderList: providerList, - } - - result, err = r.componentRegistry.ReconcileComponents(ctx, params) - if utils.ShouldReturn(result, err) { - return r.updateStatusIfNeededV2(logger, instance, newStatus, result, err, now) + { + span, spanCtx := trace.StartControllerSpan(ctx, "reconcileComponents") + params := &ReconcileComponentParams{ + Logger: logger, + DDA: instance, + RequiredComponents: requiredComponents, + Features: append(configuredFeatures, enabledFeatures...), + ResourceManagers: resourceManagers, + Status: newStatus, + Provider: k8sProvider, + ProviderList: providerList, + } + result, err = r.componentRegistry.ReconcileComponents(spanCtx, params) + span.Finish(tracer.WithError(err)) + if utils.ShouldReturn(result, err) { + return r.updateStatusIfNeededV2(ctx, logger, instance, newStatus, result, err, now) + } } // 2.b. Node Agent and profiles // TODO: ignore profiles and introspection for DDAI if result, err = r.reconcileAgentProfiles(ctx, logger, instance, requiredComponents, append(configuredFeatures, enabledFeatures...), resourceManagers, newStatus, now); utils.ShouldReturn(result, err) { - return r.updateStatusIfNeededV2(logger, instance, newStatus, result, err, now) + return r.updateStatusIfNeededV2(ctx, logger, instance, newStatus, result, err, now) } // TODO: this feels like it should be moved somewhere else @@ -222,19 +305,24 @@ func (r *Reconciler) reconcileInstanceV2(ctx context.Context, logger logr.Logger } // 3. Cleanup extraneous resources. - if err = r.cleanupExtraneousResources(ctx, logger, instance, newStatus, resourceManagers); err != nil { - logger.Error(err, "Error cleaning up extraneous resources") - return r.updateStatusIfNeededV2(logger, instance, newStatus, result, err, now) + { + span, spanCtx := trace.StartControllerSpan(ctx, "cleanupResources") + if err = r.cleanupExtraneousResources(spanCtx, logger, instance, newStatus, resourceManagers); err != nil { + logger.Error(err, "Error cleaning up extraneous resources") + span.Finish(tracer.WithError(err)) + return r.updateStatusIfNeededV2(ctx, logger, instance, newStatus, result, err, now) + } + span.Finish() } // Always requeue if !result.Requeue && result.RequeueAfter == 0 { result.RequeueAfter = defaultRequeuePeriod } - return r.updateStatusIfNeededV2(logger, instance, newStatus, result, err, now) + return r.updateStatusIfNeededV2(ctx, logger, instance, newStatus, result, err, now) } -func (r *Reconciler) updateStatusIfNeededV2(logger logr.Logger, agentdeployment *datadoghqv2alpha1.DatadogAgent, newStatus *datadoghqv2alpha1.DatadogAgentStatus, result reconcile.Result, currentError error, now metav1.Time) (reconcile.Result, error) { +func (r *Reconciler) updateStatusIfNeededV2(ctx context.Context, logger logr.Logger, agentdeployment *datadoghqv2alpha1.DatadogAgent, newStatus *datadoghqv2alpha1.DatadogAgentStatus, result reconcile.Result, currentError error, now metav1.Time) (reconcile.Result, error) { if currentError == nil { condition.UpdateDatadogAgentStatusConditions(newStatus, now, common.DatadogAgentReconcileErrorConditionType, metav1.ConditionFalse, "DatadogAgent_reconcile_ok", "DatadogAgent reconcile ok", false) } else { @@ -246,7 +334,7 @@ func (r *Reconciler) updateStatusIfNeededV2(logger logr.Logger, agentdeployment if !IsEqualStatus(&agentdeployment.Status, newStatus) { updateAgentDeployment := agentdeployment.DeepCopy() updateAgentDeployment.Status = *newStatus - if err := r.client.Status().Update(context.TODO(), updateAgentDeployment); err != nil { + if err := r.client.Status().Update(ctx, updateAgentDeployment); err != nil { if apierrors.IsConflict(err) { logger.V(1).Info("unable to update DatadogAgent status due to update conflict") return reconcile.Result{RequeueAfter: time.Second}, nil diff --git a/internal/controller/datadogagent/controller_reconcile_v2_common.go b/internal/controller/datadogagent/controller_reconcile_v2_common.go index ef70322ea..d227abaf5 100644 --- a/internal/controller/datadogagent/controller_reconcile_v2_common.go +++ b/internal/controller/datadogagent/controller_reconcile_v2_common.go @@ -586,16 +586,16 @@ func shouldProfileWaitForCanary(logger logr.Logger, annotations map[string]strin return false } -func (r *Reconciler) createOrUpdateDDAI(ddai *v1alpha1.DatadogAgentInternal) error { +func (r *Reconciler) createOrUpdateDDAI(ctx context.Context, ddai *v1alpha1.DatadogAgentInternal) error { currentDDAI := &v1alpha1.DatadogAgentInternal{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: ddai.Name, Namespace: ddai.Namespace}, currentDDAI); err != nil { + if err := r.client.Get(ctx, types.NamespacedName{Name: ddai.Name, Namespace: ddai.Namespace}, currentDDAI); err != nil { if !apierrors.IsNotFound(err) { r.log.Error(err, "unexpected error during DDAI get") return err } // Create the DDAI object if it doesn't exist r.log.Info("creating DatadogAgentInternal", "ns", ddai.Namespace, "name", ddai.Name) - if err := r.client.Create(context.TODO(), ddai); err != nil { + if err := r.client.Create(ctx, ddai); err != nil { return err } return nil @@ -605,7 +605,7 @@ func (r *Reconciler) createOrUpdateDDAI(ddai *v1alpha1.DatadogAgentInternal) err // if only the annotations changed. if !maps.Equal(currentDDAI.Annotations, ddai.Annotations) { r.log.Info("updating DatadogAgentInternal", "ns", ddai.Namespace, "name", ddai.Name) - if err := kubernetes.UpdateFromObject(context.TODO(), r.client, ddai, currentDDAI.ObjectMeta); err != nil { + if err := kubernetes.UpdateFromObject(ctx, r.client, ddai, currentDDAI.ObjectMeta); err != nil { return err } } @@ -613,9 +613,9 @@ func (r *Reconciler) createOrUpdateDDAI(ddai *v1alpha1.DatadogAgentInternal) err return nil } -func (r *Reconciler) addDDAIStatusToDDAStatus(status *v2alpha1.DatadogAgentStatus, ddai metav1.ObjectMeta) error { +func (r *Reconciler) addDDAIStatusToDDAStatus(ctx context.Context, status *v2alpha1.DatadogAgentStatus, ddai metav1.ObjectMeta) error { currentDDAI := &v1alpha1.DatadogAgentInternal{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: ddai.Name, Namespace: ddai.Namespace}, currentDDAI); err != nil { + if err := r.client.Get(ctx, types.NamespacedName{Name: ddai.Name, Namespace: ddai.Namespace}, currentDDAI); err != nil { if !apierrors.IsNotFound(err) { r.log.Error(err, "unexpected error during DDAI get") return err diff --git a/internal/controller/datadogagent/controller_reconcile_v2_common_test.go b/internal/controller/datadogagent/controller_reconcile_v2_common_test.go index 9b27b5289..9ea8a1623 100644 --- a/internal/controller/datadogagent/controller_reconcile_v2_common_test.go +++ b/internal/controller/datadogagent/controller_reconcile_v2_common_test.go @@ -1,6 +1,7 @@ package datadogagent import ( + "context" "errors" "testing" "time" @@ -871,7 +872,7 @@ func Test_addDDAIStatusToDDAStatus(t *testing.T) { log: logf.Log.WithName(tt.name), } - err := r.addDDAIStatusToDDAStatus(&tt.status, tt.existingDDAI.ObjectMeta) + err := r.addDDAIStatusToDDAStatus(context.TODO(), &tt.status, tt.existingDDAI.ObjectMeta) assert.NoError(t, err) assert.Equal(t, tt.expectedStatus, tt.status) }) diff --git a/internal/controller/datadogagent/ddai.go b/internal/controller/datadogagent/ddai.go index 7b2ba5875..7759ffc58 100644 --- a/internal/controller/datadogagent/ddai.go +++ b/internal/controller/datadogagent/ddai.go @@ -106,7 +106,7 @@ func (r *Reconciler) cleanUpUnusedDDAIs(ctx context.Context, validDDAIs []*v1alp func (r *Reconciler) addRemoteConfigStatusToDDAIStatus(ctx context.Context, ddaStatus *v2alpha1.DatadogAgentStatus, ddaiMeta metav1.ObjectMeta) (reconcile.Result, error) { ddai := &v1alpha1.DatadogAgentInternal{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: ddaiMeta.Name, Namespace: ddaiMeta.Namespace}, ddai); err != nil { + if err := r.client.Get(ctx, types.NamespacedName{Name: ddaiMeta.Name, Namespace: ddaiMeta.Namespace}, ddai); err != nil { return reconcile.Result{}, err } // check equality diff --git a/internal/controller/datadogagent/tracing.go b/internal/controller/datadogagent/tracing.go new file mode 100644 index 000000000..eabbbfa04 --- /dev/null +++ b/internal/controller/datadogagent/tracing.go @@ -0,0 +1,18 @@ +// 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 2016-present Datadog, Inc. + +package datadogagent + +import ( + "context" + + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" + + "github.com/DataDog/datadog-operator/pkg/trace" +) + +func startDDASpan(ctx context.Context, extraTags ...tracer.StartSpanOption) (*tracer.Span, context.Context) { + return trace.StartControllerSpan(ctx, trace.CallerFuncName(1), extraTags...) +} diff --git a/internal/controller/datadogagent_controller.go b/internal/controller/datadogagent_controller.go index d986ccff6..8b084d252 100644 --- a/internal/controller/datadogagent_controller.go +++ b/internal/controller/datadogagent_controller.go @@ -9,6 +9,7 @@ import ( "context" "reflect" + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" edsdatadoghqv1alpha1 "github.com/DataDog/extendeddaemonset/api/v1alpha1" "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" @@ -23,8 +24,10 @@ import ( ctrl "sigs.k8s.io/controller-runtime" ctrlbuilder "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" + ctrlcontroller "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -35,6 +38,7 @@ import ( "github.com/DataDog/datadog-operator/internal/controller/metrics" "github.com/DataDog/datadog-operator/pkg/controller/utils/datadog" "github.com/DataDog/datadog-operator/pkg/kubernetes" + "github.com/DataDog/datadog-operator/pkg/trace" ) // DatadogAgentReconciler reconciles a DatadogAgent object. @@ -214,7 +218,20 @@ type DatadogAgentReconciler struct { // Reconcile loop for DatadogAgent. func (r *DatadogAgentReconciler) Reconcile(ctx context.Context, dda *v2alpha1.DatadogAgent) (ctrl.Result, error) { - return r.internal.Reconcile(ctx, dda) + var result ctrl.Result + var err error + + ctx = trace.WithControllerContext(ctx, dda.Name, dda.Namespace, string(ctrlcontroller.ReconcileIDFromContext(ctx)), "DatadogAgent", "datadogagent") + span, ctx := trace.StartControllerSpan(ctx, "Reconcile") + defer func() { span.Finish(tracer.WithError(err)) }() + + ctx = log.IntoContext(ctx, ctrl.LoggerFrom(ctx).WithValues( + "dd.trace_id", span.Context().TraceID(), + "dd.span_id", span.Context().SpanID(), + )) + + result, err = r.internal.Reconcile(ctx, dda) + return result, err } // SetupWithManager creates a new DatadogAgent controller. diff --git a/pkg/trace/controller.go b/pkg/trace/controller.go index a0db4aff4..105db59fd 100644 --- a/pkg/trace/controller.go +++ b/pkg/trace/controller.go @@ -62,6 +62,7 @@ func StartControllerSpan(ctx context.Context, resourceName string, extraTags ... opts := []tracer.StartSpanOption{ tracer.ResourceName(resourceName), + tracer.Measured(), } if kind, ok := ctx.Value(contextKeyKind).(string); ok { opts = append(opts, tracer.Tag("kind", kind)) diff --git a/pkg/trace/transport.go b/pkg/trace/transport.go index 12569e408..817d47f9a 100644 --- a/pkg/trace/transport.go +++ b/pkg/trace/transport.go @@ -9,6 +9,7 @@ import ( "net/http" "strconv" + "github.com/DataDog/dd-trace-go/v2/ddtrace/ext" "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" ) @@ -34,16 +35,16 @@ func (t *tracingTransport) RoundTrip(req *http.Request) (*http.Response, error) resource := req.Method + " " + req.URL.Path span, ctx := tracer.StartSpanFromContext(req.Context(), "http.request", tracer.ResourceName(resource), - tracer.Tag("http.method", req.Method), - tracer.Tag("http.url", req.URL.String()), - tracer.Tag("span.type", "http"), - tracer.Tag("span.kind", "client"), + tracer.Tag(ext.HTTPMethod, req.Method), + tracer.Tag(ext.HTTPURL, req.URL.String()), + tracer.Tag(ext.SpanType, ext.SpanTypeHTTP), + tracer.Tag(ext.SpanKind, ext.SpanKindClient), ) req = req.WithContext(ctx) resp, err := t.wrapped.RoundTrip(req) if resp != nil { - span.SetTag("http.status_code", strconv.Itoa(resp.StatusCode)) + span.SetTag(ext.HTTPCode, strconv.Itoa(resp.StatusCode)) } span.Finish(tracer.WithError(err)) return resp, err diff --git a/test/e2e/go.mod b/test/e2e/go.mod index b834aa711..932fee729 100644 --- a/test/e2e/go.mod +++ b/test/e2e/go.mod @@ -1,6 +1,6 @@ module github.com/DataDog/datadog-operator/test/e2e -go 1.25.6 +go 1.25.0 toolchain go1.25.7 diff --git a/test/e2e/go.sum b/test/e2e/go.sum index adfc4c811..26c57384c 100644 --- a/test/e2e/go.sum +++ b/test/e2e/go.sum @@ -344,7 +344,6 @@ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5T github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4 h1:kEISI/Gx67NzH3nJxAmY/dGac80kKZgZt134u7Y/k1s= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4/go.mod h1:6Nz966r3vQYCqIzWsuEl9d7cf7mRhtDmm++sOxlnfxI= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= @@ -648,8 +647,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0 h1:SZmDnHcgp3zwlP go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0/go.mod h1:fdWW0HtZJ7+jNpTKUR0GpMEDP69nR8YBJQxNiVCE3jk= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 h1:cC2yDI3IQd0Udsux7Qmq8ToKAx1XCilTQECZ0KDZyTw= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0/go.mod h1:2PD5Ex6z8CFzDbTdOlwyNIUywRr1DN0ospafJM1wJ+s= -go.opentelemetry.io/otel/log v0.8.0 h1:egZ8vV5atrUWUbnSsHn6vB8R21G2wrKqNiDt3iWertk= -go.opentelemetry.io/otel/log v0.8.0/go.mod h1:M9qvDdUTRCopJcGRKg57+JSQ9LgLBrwwfC32epk5NX8= +go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= +go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= @@ -798,7 +797,7 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 h1:BulPr26Jqjnd4eYDVe+YvyR7Yc2vJGkO5/0UxD0/jZU= +google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 h1:ImUcDPHjTrAqNhlOkSocDLfG9rrNHH7w7uoKWPaWZ8s= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=