Skip to content

shift process management from Probe to Manager #2029

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

damemi
Copy link
Contributor

@damemi damemi commented Mar 20, 2025

Part of setting up for exposing the Probe API -- the main goal of this PR is to shift usage of the internal process package from the base Probe implementation to the Manager.

#1943 moved process analysis to the manager, so this follows a similar pattern of consolidating process handling into the manager.

Functionally, that means moving a lot of the Probe initialization to the manager. So now, instead of thinking "the Probe sets itself up" the flow is more "the Manager sets up the Probe"

This is a WIP right now showing the basic idea, the tougher part will be decoupling Process info from Consts

@damemi damemi force-pushed the decouple-process-from-probe branch 2 times, most recently from 8d8aa32 to 6b65138 Compare March 20, 2025 18:48
Copy link
Contributor

@MrAlias MrAlias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of decoupling the probe from process management, but it seems like this is just shuffling existing patterns out of a probe without refactoring the details deep in the functionality. I think we need to drill deeper into what the process interactions are for a probe and likely redesign around that.

Comment on lines +45 to +46
// GetLogger returns the *slog.Logger associated with the Probe.
GetLogger() *slog.Logger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we ever need to get the logger from a probe? Doesn't the Manager have its own logger it can use for its own operations?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sill needs to be addressed. The Manager needs to use it's own logger. This should be removed.

Suggested change
// GetLogger returns the *slog.Logger associated with the Probe.
GetLogger() *slog.Logger

Comment on lines +57 to +55
// GetUprobes returns a list of *Uprobes for the Probe.
GetUprobes() []*Uprobe

// GetConsts returns a list of Consts for the Probe.
GetConsts() []Const
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are duplicates of the Manifest method which contains these values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, and it wasn't clear to me because we change the name of them in the Manifest: Uprobes->FunctionSymbol and Consts->StructFieldIDs

The latter I think is because the Manifest doesn't actually store all the Consts in the Probe, just the consts for fields. If we're loading the uprobes in the manager now and injecting the consts there, we'll need all of the consts.

Do you think we should refactor the Manifest struct a bit to align better with the Probe definition?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely unify these types respectively.

Given they are static to a probe, keeping their definitions in the Manifest seems appropriate.

@damemi damemi force-pushed the decouple-process-from-probe branch from 4cd3c36 to 39d7f0b Compare April 3, 2025 18:44
@damemi
Copy link
Contributor Author

damemi commented Apr 3, 2025

@MrAlias I did some more refactoring based on the last sig call. Basically, the Manager will now track a reference to the "initialized" probe, ie the probe+its collection+its closers. Then all collection/closer interaction can be done in the manager.

It's just a step, but let me know what you think

@damemi
Copy link
Contributor Author

damemi commented Apr 3, 2025

@MrAlias and now that I think about it, the collection/closer stuff could be set in the Manifest, but is the manifest intended to be mutable like that (ie, updated once the Probe is initialized) or just a static representation of the Probe's defintion?

@MrAlias
Copy link
Contributor

MrAlias commented Apr 8, 2025

just a static representation of the Probe's defintion?

My intent was for it to be static.

@damemi damemi changed the title (wip) shift process management from Probe to Manager shift process management from Probe to Manager Apr 8, 2025
@damemi damemi marked this pull request as ready for review April 8, 2025 19:51
@damemi damemi requested a review from a team as a code owner April 8, 2025 19:51
@damemi damemi force-pushed the decouple-process-from-probe branch 2 times, most recently from 613d429 to 4987d3a Compare April 8, 2025 19:59
@damemi damemi force-pushed the decouple-process-from-probe branch 3 times, most recently from a923943 to e0d26fa Compare April 10, 2025 19:39
@damemi damemi force-pushed the decouple-process-from-probe branch from e0d26fa to 71a7496 Compare April 10, 2025 20:56
Copy link
Contributor

@MrAlias MrAlias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't looks to be a working example. I'm not sure how far I can review because of this.

Comment on lines +45 to +46
// GetLogger returns the *slog.Logger associated with the Probe.
GetLogger() *slog.Logger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sill needs to be addressed. The Manager needs to use it's own logger. This should be removed.

Suggested change
// GetLogger returns the *slog.Logger associated with the Probe.
GetLogger() *slog.Logger

Comment on lines +57 to +55
// GetUprobes returns a list of *Uprobes for the Probe.
GetUprobes() []*Uprobe

// GetConsts returns a list of Consts for the Probe.
GetConsts() []Const
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely unify these types respectively.

Given they are static to a probe, keeping their definitions in the Manifest seems appropriate.

return nil
}

func (m *Manager) loadUprobe(u *probe.Uprobe, c *ebpf.Collection) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this is no longer used and a can be removed.

return inject.Constants(spec, opts...)
}

func (m *Manager) loadUprobesFromProbe(i ProbeReference) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar here, this can be removed.

return errors.Join(err, m.cleanup())
}

c, err := utils.InitializeEBPFCollection(spec, m.collectionOpts)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this function be moved to this package/file. This is the only place it is used.

Comment on lines +64 to +66
// ProbeReference is used by the Manager to track an initialized reference
// to a Probe and its related resources such as its ebpf.Collection and io.Closers.
type ProbeReference struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be unexported. It is only used internal to this package.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also not clear why this is needed. The collection field is never used (it is ineffectively set, but never read), and the closers field could just be captured in a thin wrapper around a Probe implementation (given it is already an interface).

@@ -54,6 +58,15 @@ type Manager struct {
probeMu sync.Mutex
state managerState
stateMu sync.RWMutex
collectionOpts *ebpf.CollectionOptions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to have a need as a field. It is only ever used in a single call site and always set to the same value. It should just be a local var to https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/2029/files#diff-8008933194d32417cc135227b15916c4d1f575de0abda31bc0545b51d9783bebR435

m.probes[id] = p
m.probes[id] = ProbeReference{
probe: p,
closers: make([]io.Closer, 0),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed. It is only allocating memory prior to need. append handles appends to empty values without issue.

Suggested change
closers: make([]io.Closer, 0),

if err != nil {
return errors.Join(err, m.cleanup())
}
i.collection = c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unused write to i.collection

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we are using it in the Close function,
the collection allows us to maybe make the closing mechanism simpler?
see
https://github.com/cilium/ebpf/blob/49a06b1fe26190a4c2a702932f611c6eff908d3a/collection.go#L904

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I gotcha, just this is writing to a value, not a reference. When this function returns the passed argument remains unchanged. This assignment is to a copied value that is not used.

@@ -398,11 +419,189 @@ func (m *Manager) loadProbes() error {
return nil
}

func (m *Manager) LoadProbe(i ProbeReference, name probe.ID, cfg Config) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoadProbe is only ever called internal to the package. This should be unexported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants