@@ -10,24 +10,20 @@ import (
10
10
"bytes"
11
11
"encoding/json"
12
12
"fmt"
13
- "io"
14
13
"net"
15
- "net/http"
16
14
"net/url"
17
15
"os"
18
16
"path"
19
17
"strconv"
20
18
"time"
21
19
22
20
"github.com/fatih/color"
23
- "github.com/hashicorp/go-multierror"
24
21
"github.com/spf13/cobra"
25
22
"go.uber.org/fx"
26
23
27
24
"github.com/DataDog/datadog-agent/cmd/agent/command"
28
25
"github.com/DataDog/datadog-agent/cmd/agent/common"
29
26
"github.com/DataDog/datadog-agent/cmd/agent/subcommands/streamlogs"
30
- sysprobeclient "github.com/DataDog/datadog-agent/cmd/system-probe/api/client"
31
27
"github.com/DataDog/datadog-agent/comp/aggregator/diagnosesendermanager/diagnosesendermanagerimpl"
32
28
authtokenimpl "github.com/DataDog/datadog-agent/comp/api/authtoken/fetchonlyimpl"
33
29
"github.com/DataDog/datadog-agent/comp/collector/collector"
@@ -36,8 +32,13 @@ import (
36
32
"github.com/DataDog/datadog-agent/comp/core/config"
37
33
"github.com/DataDog/datadog-agent/comp/core/flare"
38
34
"github.com/DataDog/datadog-agent/comp/core/flare/helpers"
35
+ flaretypes "github.com/DataDog/datadog-agent/comp/core/flare/types"
39
36
log "github.com/DataDog/datadog-agent/comp/core/log/def"
37
+ flareprofilerdef "github.com/DataDog/datadog-agent/comp/core/profiler/def"
38
+ flareprofilerfx "github.com/DataDog/datadog-agent/comp/core/profiler/fx"
40
39
"github.com/DataDog/datadog-agent/comp/core/secrets"
40
+ coresettings "github.com/DataDog/datadog-agent/comp/core/settings"
41
+ "github.com/DataDog/datadog-agent/comp/core/settings/settingsimpl"
41
42
"github.com/DataDog/datadog-agent/comp/core/sysprobeconfig"
42
43
"github.com/DataDog/datadog-agent/comp/core/sysprobeconfig/sysprobeconfigimpl"
43
44
tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def"
@@ -124,12 +125,23 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command {
124
125
defaultpaths .DogstatsDLogFile ,
125
126
defaultpaths .StreamlogsLogFile ,
126
127
)),
128
+ flareprofilerfx .Module (),
127
129
// workloadmeta setup
128
130
wmcatalog .GetCatalog (),
129
131
workloadmetafx .Module (workloadmeta.Params {
130
132
AgentType : workloadmeta .NodeAgent ,
131
133
InitHelper : common .GetWorkloadmetaInit (),
132
134
}),
135
+ fx .Provide (func (config config.Component ) coresettings.Params {
136
+ return coresettings.Params {
137
+ // A settings object is required to populate some dependencies, but
138
+ // no values are valid since the flare runs by default in a separate
139
+ // process from the main agent.
140
+ Settings : map [string ]coresettings.RuntimeSetting {},
141
+ Config : config ,
142
+ }
143
+ }),
144
+ settingsimpl .Module (),
133
145
localTaggerfx .Module (tagger.Params {}),
134
146
autodiscoveryimpl .Module (),
135
147
fx .Supply (option .None [collector.Component ]()),
@@ -171,147 +183,16 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command {
171
183
return []* cobra.Command {flareCmd }
172
184
}
173
185
174
- func readProfileData (seconds int ) (flare.ProfileData , error ) {
175
- type agentProfileCollector func (service string ) error
176
-
177
- pdata := flare.ProfileData {}
178
- c := util .GetClient (false )
179
-
180
- type pprofGetter func (path string ) ([]byte , error )
181
-
182
- tcpGet := func (portConfig string , onHTTPS bool ) pprofGetter {
183
- endpoint := url.URL {
184
- Scheme : "http" ,
185
- Host : net .JoinHostPort ("127.0.0.1" , strconv .Itoa (pkgconfigsetup .Datadog ().GetInt (portConfig ))),
186
- Path : "/debug/pprof" ,
187
- }
188
- if onHTTPS {
189
- endpoint .Scheme = "https"
190
- }
191
-
192
- return func (path string ) ([]byte , error ) {
193
- return util .DoGet (c , endpoint .String ()+ path , util .LeaveConnectionOpen )
194
- }
195
- }
196
-
197
- serviceProfileCollector := func (get func (url string ) ([]byte , error ), seconds int ) agentProfileCollector {
198
- return func (service string ) error {
199
- fmt .Fprintln (color .Output , color .BlueString ("Getting a %ds profile snapshot from %s." , seconds , service ))
200
- for _ , prof := range []struct { name , path string }{
201
- {
202
- // 1st heap profile
203
- name : service + "-1st-heap.pprof" ,
204
- path : "/heap" ,
205
- },
206
- {
207
- // CPU profile
208
- name : service + "-cpu.pprof" ,
209
- path : fmt .Sprintf ("/profile?seconds=%d" , seconds ),
210
- },
211
- {
212
- // 2nd heap profile
213
- name : service + "-2nd-heap.pprof" ,
214
- path : "/heap" ,
215
- },
216
- {
217
- // mutex profile
218
- name : service + "-mutex.pprof" ,
219
- path : "/mutex" ,
220
- },
221
- {
222
- // goroutine blocking profile
223
- name : service + "-block.pprof" ,
224
- path : "/block" ,
225
- },
226
- {
227
- // Trace
228
- name : service + ".trace" ,
229
- path : fmt .Sprintf ("/trace?seconds=%d" , seconds ),
230
- },
231
- } {
232
- b , err := get (prof .path )
233
- if err != nil {
234
- return err
235
- }
236
- pdata [prof .name ] = b
237
- }
238
- return nil
239
- }
240
- }
241
-
242
- agentCollectors := map [string ]agentProfileCollector {
243
- "core" : serviceProfileCollector (tcpGet ("expvar_port" , false ), seconds ),
244
- "security-agent" : serviceProfileCollector (tcpGet ("security_agent.expvar_port" , false ), seconds ),
245
- }
246
-
247
- if pkgconfigsetup .Datadog ().GetBool ("process_config.enabled" ) ||
248
- pkgconfigsetup .Datadog ().GetBool ("process_config.container_collection.enabled" ) ||
249
- pkgconfigsetup .Datadog ().GetBool ("process_config.process_collection.enabled" ) {
250
-
251
- agentCollectors ["process" ] = serviceProfileCollector (tcpGet ("process_config.expvar_port" , false ), seconds )
252
- }
253
-
254
- if pkgconfigsetup .Datadog ().GetBool ("apm_config.enabled" ) {
255
- traceCpusec := pkgconfigsetup .Datadog ().GetInt ("apm_config.receiver_timeout" )
256
- if traceCpusec > seconds {
257
- // do not exceed requested duration
258
- traceCpusec = seconds
259
- } else if traceCpusec <= 0 {
260
- // default to 4s as maximum connection timeout of trace-agent HTTP server is 5s by default
261
- traceCpusec = 4
262
- }
263
-
264
- agentCollectors ["trace" ] = serviceProfileCollector (tcpGet ("apm_config.debug.port" , true ), traceCpusec )
265
- }
266
-
267
- if pkgconfigsetup .SystemProbe ().GetBool ("system_probe_config.enabled" ) {
268
- client := & http.Client {
269
- Transport : & http.Transport {
270
- DialContext : sysprobeclient .DialContextFunc (pkgconfigsetup .SystemProbe ().GetString ("system_probe_config.sysprobe_socket" )),
271
- },
272
- }
273
-
274
- sysProbeGet := func () pprofGetter {
275
- return func (path string ) ([]byte , error ) {
276
- var buf bytes.Buffer
277
- pprofURL := sysprobeclient .DebugURL ("/pprof" + path )
278
- req , err := http .NewRequest (http .MethodGet , pprofURL , & buf )
279
- if err != nil {
280
- return nil , err
281
- }
282
-
283
- res , err := client .Do (req )
284
- if err != nil {
285
- return nil , err
286
- }
287
- defer res .Body .Close ()
288
-
289
- return io .ReadAll (res .Body )
290
- }
291
- }
292
-
293
- agentCollectors ["system-probe" ] = serviceProfileCollector (sysProbeGet (), seconds )
294
- }
295
-
296
- var errs error
297
- for name , callback := range agentCollectors {
298
- if err := callback (name ); err != nil {
299
- errs = multierror .Append (errs , fmt .Errorf ("error collecting %s agent profile: %v" , name , err ))
300
- }
301
- }
302
-
303
- return pdata , errs
304
- }
305
-
306
186
func makeFlare (flareComp flare.Component ,
307
187
lc log.Component ,
308
188
config config.Component ,
309
189
_ sysprobeconfig.Component ,
310
190
cliParams * cliParams ,
311
191
_ option.Option [workloadmeta.Component ],
312
- _ tagger.Component ) error {
192
+ _ tagger.Component ,
193
+ flareprofiler flareprofilerdef.Component ) error {
313
194
var (
314
- profile flare .ProfileData
195
+ profile flaretypes .ProfileData
315
196
err error
316
197
)
317
198
@@ -359,8 +240,13 @@ func makeFlare(flareComp flare.Component,
359
240
ProfileBlockingRate : cliParams .profileBlockingRate ,
360
241
}
361
242
243
+ logFunc := func (s string , params ... interface {}) error {
244
+ fmt .Fprintln (color .Output , color .BlueString (s , params ... ))
245
+ return nil
246
+ }
247
+
362
248
err = settings .ExecWithRuntimeProfilingSettings (func () {
363
- if profile , err = readProfileData (cliParams .profiling ); err != nil {
249
+ if profile , err = flareprofiler . ReadProfileData (cliParams .profiling , logFunc ); err != nil {
364
250
fmt .Fprintln (color .Output , color .YellowString (fmt .Sprintf ("Could not collect performance profile data: %s" , err )))
365
251
}
366
252
}, profilingOpts , c )
@@ -414,7 +300,7 @@ func makeFlare(flareComp flare.Component,
414
300
return nil
415
301
}
416
302
417
- func requestArchive (flareComp flare.Component , pdata flare .ProfileData , providerTimeout time.Duration ) (string , error ) {
303
+ func requestArchive (flareComp flare.Component , pdata flaretypes .ProfileData , providerTimeout time.Duration ) (string , error ) {
418
304
fmt .Fprintln (color .Output , color .BlueString ("Asking the agent to build the flare archive." ))
419
305
c := util .GetClient (false ) // FIX: get certificates right then make this true
420
306
ipcAddress , err := pkgconfigsetup .GetIPCAddress (pkgconfigsetup .Datadog ())
@@ -464,7 +350,7 @@ func requestArchive(flareComp flare.Component, pdata flare.ProfileData, provider
464
350
return string (r ), nil
465
351
}
466
352
467
- func createArchive (flareComp flare.Component , pdata flare .ProfileData , providerTimeout time.Duration , ipcError error ) (string , error ) {
353
+ func createArchive (flareComp flare.Component , pdata flaretypes .ProfileData , providerTimeout time.Duration , ipcError error ) (string , error ) {
468
354
fmt .Fprintln (color .Output , color .YellowString ("Initiating flare locally." ))
469
355
filePath , err := flareComp .Create (pdata , providerTimeout , ipcError )
470
356
if err != nil {
0 commit comments