-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathcommand.go
More file actions
188 lines (164 loc) · 7.13 KB
/
Copy pathcommand.go
File metadata and controls
188 lines (164 loc) · 7.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// 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.
//go:build linux
// Package run is the run host-profiler subcommand
package run
import (
"context"
"errors"
"log/slog"
"os"
"github.com/spf13/cobra"
"go.uber.org/fx"
ddgostatsd "github.com/DataDog/datadog-go/v5/statsd"
"github.com/DataDog/datadog-agent/cmd/agent/command"
"github.com/DataDog/datadog-agent/cmd/host-profiler/globalparams"
"github.com/DataDog/datadog-agent/comp/core"
"github.com/DataDog/datadog-agent/comp/core/config"
configsync "github.com/DataDog/datadog-agent/comp/core/configsync/def"
configsyncfx "github.com/DataDog/datadog-agent/comp/core/configsync/fx"
"github.com/DataDog/datadog-agent/comp/core/hostname/remotehostnameimpl"
ipcfx "github.com/DataDog/datadog-agent/comp/core/ipc/fx"
log "github.com/DataDog/datadog-agent/comp/core/log/def"
tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def"
remoteTaggerFx "github.com/DataDog/datadog-agent/comp/core/tagger/fx-remote"
statsd "github.com/DataDog/datadog-agent/comp/dogstatsd/statsd/def"
statsdotel "github.com/DataDog/datadog-agent/comp/dogstatsd/statsd/otel"
hostprofiler "github.com/DataDog/datadog-agent/comp/host-profiler"
collector "github.com/DataDog/datadog-agent/comp/host-profiler/collector/def"
collectorimpl "github.com/DataDog/datadog-agent/comp/host-profiler/collector/impl"
"github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/metricsclient"
traceagentfx "github.com/DataDog/datadog-agent/comp/trace/agent/fx"
traceagentcomp "github.com/DataDog/datadog-agent/comp/trace/agent/impl"
gzipfx "github.com/DataDog/datadog-agent/comp/trace/compression/fx-gzip"
traceconfigdef "github.com/DataDog/datadog-agent/comp/trace/config/def"
traceconfigfx "github.com/DataDog/datadog-agent/comp/trace/config/fx"
payloadmodifierfx "github.com/DataDog/datadog-agent/comp/trace/payload-modifier/fx"
pkgconfigenv "github.com/DataDog/datadog-agent/pkg/config/env"
pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model"
"github.com/DataDog/datadog-agent/pkg/config/setup"
"github.com/DataDog/datadog-agent/pkg/trace/telemetry"
"github.com/DataDog/datadog-agent/pkg/util/defaultpaths"
"github.com/DataDog/datadog-agent/pkg/util/fxutil"
"github.com/DataDog/datadog-agent/pkg/util/fxutil/logging"
)
type cliParams struct {
*globalparams.GlobalParams
GoRuntimeMetrics bool
}
// MakeCommand creates the `run` command
func MakeCommand(globalConfGetter func() *globalparams.GlobalParams) []*cobra.Command {
params := &cliParams{}
cmd := &cobra.Command{
Use: "run",
Short: "Start Host Profiler",
Long: `Runs the Host Profiler to collect host profiling data and send it to Datadog.`,
RunE: func(_ *cobra.Command, _ []string) error {
params.GlobalParams = globalConfGetter()
return runHostProfilerCommand(context.Background(), params)
},
}
cmd.Flags().BoolVar(¶ms.GoRuntimeMetrics, "go-runtime-metrics", false, "Enable Go runtime metrics collection.")
return []*cobra.Command{cmd}
}
func validateFlags(params *globalparams.GlobalParams) error {
// Require at least one configuration source
if params.ConfFilePath == "" && params.CoreConfPath == "" {
return errors.New("must provide either --config or --core-config configuration")
}
return nil
}
func runHostProfilerCommand(ctx context.Context, cliParams *cliParams) error {
// Validate flag usage
if err := validateFlags(cliParams.GlobalParams); err != nil {
return err
}
var opts = []fx.Option{
hostprofiler.Bundle(collectorimpl.NewParams(cliParams.GlobalParams.ConfigURI(), cliParams.GoRuntimeMetrics)),
logging.DefaultFxLoggingOption(),
}
if cliParams.GlobalParams.CoreConfPath != "" {
warnBothConfigs := cliParams.GlobalParams.ConfFilePath != ""
opts = append(opts,
core.Bundle(),
remotehostnameimpl.Module(),
fx.Supply(core.BundleParams{
ConfigParams: config.NewAgentParams(cliParams.GlobalParams.CoreConfPath),
LogParams: log.ForDaemon(command.LoggerName, "hostprofiler.log_file", defaultpaths.GetDefaultHostProfilerLogFile()),
}),
fx.Provide(collectorimpl.NewExtraFactoriesWithAgentCore),
fx.Invoke(func(l log.Component) {
if warnBothConfigs {
l.Warn("Both OTel and Core Agent configuration paths were provided. The OTel configuration will be ignored and the Core Agent configuration will be used.")
}
}),
)
opts = append(opts, getRemoteTaggerOptions()...)
opts = append(opts, getTraceAgentOptions(ctx)...)
opts = append(opts, getConfigOptions(cliParams.GlobalParams)...)
} else {
opts = append(opts,
fx.Invoke(initStandaloneConfig),
fx.Provide(collectorimpl.NewExtraFactoriesWithoutAgentCore),
)
}
return fxutil.OneShot(run, opts...)
}
func run(collector collector.Component) error {
return collector.Run()
}
// initStandaloneConfig performs one-time config setup for standalone mode (no core agent).
// K8S_NODE_IP is set by upstream Helm charts for the node IP; we use it as
// kubernetes_kubelet_host so the kubelet client can resolve the node hostname.
func initStandaloneConfig() {
const kubeletHostAgentConfig = "kubernetes_kubelet_host"
pkgconfigenv.DetectFeatures(setup.Datadog())
k8sNodeIP := os.Getenv("K8S_NODE_IP")
// If not set, let's keep DD_KUBERNETES_KUBELET_HOST as fallback
if k8sNodeIP != "" {
setup.Datadog().Set(kubeletHostAgentConfig, k8sNodeIP, pkgconfigmodel.SourceAgentRuntime)
} else if _, exists := os.LookupEnv("DD_KUBERNETES_KUBELET_HOST"); exists {
slog.Warn("DD_KUBERNETES_KUBELET_HOST used as fallback to K8S_NODE_IP but is not officially supported")
}
}
func getRemoteTaggerOptions() []fx.Option {
return []fx.Option{
ipcfx.ModuleReadWrite(),
remoteTaggerFx.Module(tagger.NewRemoteParams()),
}
}
func getConfigOptions(params *globalparams.GlobalParams) []fx.Option {
return []fx.Option{
configsyncfx.Module(configsync.NewParams(params.SyncTimeout, true, params.SyncOnInitTimeout)),
}
}
func getTraceAgentOptions(ctx context.Context) []fx.Option {
return []fx.Option{
traceagentfx.Module(),
traceconfigfx.Module(),
fx.Supply(&traceagentcomp.Params{
CPUProfile: "",
MemProfile: "",
PIDFilePath: "",
DisableInternalProfiling: true,
}),
fx.Provide(func(cfg traceconfigdef.Component) telemetry.TelemetryCollector {
return telemetry.NewCollector(cfg.Object())
}),
fx.Supply(metricsclient.NewStatsdClientWrapper(&ddgostatsd.NoOpClient{})),
fx.Provide(func(client *metricsclient.StatsdClientWrapper) statsd.Component {
return statsdotel.NewOTelStatsd(client)
}),
gzipfx.Module(),
payloadmodifierfx.NilModule(),
fx.Supply(fx.Annotate(ctx, fx.As(new(context.Context)))),
fx.Decorate(func(config config.Component) config.Component {
config.Set("apm_config.debug.port", 0, pkgconfigmodel.SourceDefault) // Disabled as in the otel-agent
config.Set(setup.OTLPTracePort, 0, pkgconfigmodel.SourceDefault) // Disabled as in the otel-agent
config.Set("apm_config.receiver_enabled", false, pkgconfigmodel.SourceDefault) // disable HTTP receiver
return config
}),
}
}