@@ -45,7 +45,7 @@ const (
45
45
// Manager handles the management of [probe.Probe] instances.
46
46
type Manager struct {
47
47
logger * slog.Logger
48
- probes map [probe.ID ]probe. Probe
48
+ probes map [probe.ID ]ProbeReference
49
49
otelController * opentelemetry.Controller
50
50
cp ConfigProvider
51
51
exe * link.Executable
@@ -59,11 +59,19 @@ type Manager struct {
59
59
collectionOpts * ebpf.CollectionOptions
60
60
}
61
61
62
+ // ProbeReference is used by the Manager to track an initialized reference
63
+ // to a Probe and its related resources such as its ebpf.Collection and io.Closers.
64
+ type ProbeReference struct {
65
+ probe probe.Probe
66
+ collection * ebpf.Collection
67
+ closers []io.Closer
68
+ }
69
+
62
70
// NewManager returns a new [Manager].
63
71
func NewManager (logger * slog.Logger , otelController * opentelemetry.Controller , pid process.ID , cp ConfigProvider , probes ... probe.Probe ) (* Manager , error ) {
64
72
m := & Manager {
65
73
logger : logger ,
66
- probes : make (map [probe.ID ]probe. Probe ),
74
+ probes : make (map [probe.ID ]ProbeReference ),
67
75
otelController : otelController ,
68
76
cp : cp ,
69
77
}
@@ -132,7 +140,10 @@ func (m *Manager) registerProbe(p probe.Probe) error {
132
140
return err
133
141
}
134
142
135
- m .probes [id ] = p
143
+ m .probes [id ] = ProbeReference {
144
+ probe : p ,
145
+ closers : make ([]io.Closer , 0 ),
146
+ }
136
147
return nil
137
148
}
138
149
@@ -146,7 +157,7 @@ func (m *Manager) filterUnusedProbes() {
146
157
147
158
for name , inst := range m .probes {
148
159
funcsFound := false
149
- for _ , s := range inst .Manifest ().Symbols {
160
+ for _ , s := range inst .probe . Manifest ().Symbols {
150
161
if len (s .DependsOn ) == 0 {
151
162
if _ , exists := existingFuncMap [s .Symbol ]; exists {
152
163
funcsFound = true
@@ -213,15 +224,15 @@ func (m *Manager) applyConfig(c Config) error {
213
224
214
225
if currentlyEnabled && ! newEnabled {
215
226
m .logger .Info ("Disabling probe" , "id" , id )
216
- err = errors .Join (err , p . Close ( ))
227
+ err = errors .Join (err , m . CloseProbe ( p ))
217
228
continue
218
229
}
219
230
220
231
if ! currentlyEnabled && newEnabled {
221
232
m .logger .Info ("Enabling probe" , "id" , id )
222
233
err = errors .Join (err , m .LoadProbe (p , id , c ))
223
234
if err == nil {
224
- m .runProbe (p )
235
+ m .runProbe (p . probe )
225
236
}
226
237
continue
227
238
}
@@ -296,7 +307,7 @@ func (m *Manager) runProbes(ctx context.Context) (context.Context, error) {
296
307
297
308
for id , p := range m .probes {
298
309
if isProbeEnabled (id , m .currentConfig ) {
299
- m .runProbe (p )
310
+ m .runProbe (p . probe )
300
311
}
301
312
}
302
313
@@ -390,29 +401,31 @@ func (m *Manager) loadProbes() error {
390
401
return nil
391
402
}
392
403
393
- func (m * Manager ) LoadProbe (i probe. Probe , name probe.ID , cfg Config ) error {
404
+ func (m * Manager ) LoadProbe (i ProbeReference , name probe.ID , cfg Config ) error {
394
405
m .logger .Info ("loading probe" , "name" , name )
395
406
396
- err := i .Init ( cfg . SamplingConfig )
407
+ spec , err := i .probe . Spec ( )
397
408
if err != nil {
398
409
return errors .Join (err , m .cleanup ())
399
410
}
400
411
401
- spec , err := i . Spec ( )
412
+ err = m . InjectProbeConsts ( i . probe , spec )
402
413
if err != nil {
403
- return errors . Join ( err , m . cleanup ())
414
+ return err
404
415
}
405
416
406
- err = m . InjectProbeConsts ( i , spec )
417
+ c , err := utils . InitializeEBPFCollection ( spec , m . collectionOpts )
407
418
if err != nil {
408
419
return err
409
420
}
421
+ i .collection = c
410
422
411
- c , err := utils . InitializeEBPFCollection ( spec , m . collectionOpts )
423
+ reader , err := i . probe . InitStartupConfig ( c , cfg . SamplingConfig )
412
424
if err != nil {
413
- return err
425
+ return errors . Join ( err , m . cleanup ())
414
426
}
415
- i .SetCollection (c )
427
+ i .closers = append (i .closers , reader )
428
+
416
429
return nil
417
430
}
418
431
@@ -437,8 +450,8 @@ func (m *Manager) InjectProbeConsts(i probe.Probe, spec *ebpf.CollectionSpec) er
437
450
return inject .Constants (spec , opts ... )
438
451
}
439
452
440
- func (m * Manager ) loadUprobesFromProbe (i probe. Probe ) error {
441
- for _ , up := range i .GetUprobes () {
453
+ func (m * Manager ) loadUprobesFromProbe (i ProbeReference ) error {
454
+ for _ , up := range i .probe . GetUprobes () {
442
455
var skip bool
443
456
for _ , pc := range up .PackageConstraints {
444
457
if pc .Constraints .Check (m .proc .Modules [pc .Package ]) {
@@ -448,17 +461,17 @@ func (m *Manager) loadUprobesFromProbe(i probe.Probe) error {
448
461
var logFn func (string , ... any )
449
462
switch pc .FailureMode {
450
463
case probe .FailureModeIgnore :
451
- logFn = i .GetLogger ().Debug
464
+ logFn = i .probe . GetLogger ().Debug
452
465
case probe .FailureModeWarn :
453
- logFn = i .GetLogger ().Warn
466
+ logFn = i .probe . GetLogger ().Warn
454
467
default :
455
468
// Unknown and FailureModeError.
456
469
return fmt .Errorf ("uprobe %s package constraint (%s) not met, version %v" , up .Sym , pc .Constraints .String (), m .proc .Modules [pc .Package ])
457
470
}
458
471
459
472
logFn (
460
473
"package constraint not meet, skipping uprobe" ,
461
- "probe" , i .Manifest ().ID ,
474
+ "probe" , i .probe . Manifest ().ID ,
462
475
"symbol" , up .Sym ,
463
476
"package" , pc .Package ,
464
477
"constraint" , pc .Constraints .String (),
@@ -472,22 +485,23 @@ func (m *Manager) loadUprobesFromProbe(i probe.Probe) error {
472
485
continue
473
486
}
474
487
475
- err := m .loadUprobe (up , i .GetCollection () )
488
+ err := m .loadUprobe (up , i .collection )
476
489
if err != nil {
477
490
var logFn func (string , ... any )
478
491
switch up .FailureMode {
479
492
case probe .FailureModeIgnore :
480
- logFn = i .GetLogger ().Debug
493
+ logFn = i .probe . GetLogger ().Debug
481
494
case probe .FailureModeWarn :
482
- logFn = i .GetLogger ().Warn
495
+ logFn = i .probe . GetLogger ().Warn
483
496
default :
484
497
// Unknown and FailureModeError.
485
498
return err
486
499
}
487
- logFn ("failed to load uprobe" , "probe" , i .Manifest ().ID , "symbol" , up .Sym , "error" , err )
500
+ logFn ("failed to load uprobe" , "probe" , i .probe . Manifest ().ID , "symbol" , up .Sym , "error" , err )
488
501
continue
489
502
}
490
- _ = i .UpdateClosers (up )
503
+
504
+ i .closers = append (i .closers , up )
491
505
}
492
506
return nil
493
507
}
@@ -555,11 +569,26 @@ func (m *Manager) mount() error {
555
569
return bpffsMount (m .proc )
556
570
}
557
571
572
+ func (m * Manager ) CloseProbe (p ProbeReference ) error {
573
+ if p .collection != nil {
574
+ p .collection .Close ()
575
+ }
576
+
577
+ var err error
578
+ for _ , c := range p .closers {
579
+ err = errors .Join (err , c .Close ())
580
+ }
581
+ if err == nil {
582
+ p .probe .GetLogger ().Debug ("Closed" , "Probe" , p .probe .Manifest ().ID )
583
+ }
584
+ return err
585
+ }
586
+
558
587
func (m * Manager ) cleanup () error {
559
588
ctx := context .Background ()
560
589
err := m .cp .Shutdown (context .Background ())
561
590
for _ , i := range m .probes {
562
- err = errors .Join (err , i . Close ( ))
591
+ err = errors .Join (err , m . CloseProbe ( i ))
563
592
}
564
593
565
594
// Wait for all probes to close so we know there is no more telemetry being
0 commit comments