-
Notifications
You must be signed in to change notification settings - Fork 14
feat: add procfs process tracking #1288
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
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,12 +77,15 @@ impl Sampler { | |
| clippy::too_many_lines, | ||
| clippy::cast_sign_loss, | ||
| clippy::cast_possible_truncation, | ||
| clippy::cast_possible_wrap | ||
| clippy::cast_possible_wrap, | ||
| clippy::cast_lossless | ||
| )] | ||
| pub(crate) async fn poll(&mut self, include_smaps: bool) -> Result<(), Error> { | ||
| // A tally of the total RSS and PSS consumed by the parent process and | ||
| // its children. | ||
| let mut aggr = memory::smaps_rollup::Aggregator::default(); | ||
| let mut processes_found: i32 = 0; | ||
| let mut pids_skipped: FxHashSet<i32> = FxHashSet::default(); | ||
|
|
||
| // Every sample run we collect all the child processes rooted at the | ||
| // parent. As noted by the procfs documentation is this done by | ||
|
|
@@ -119,9 +122,18 @@ impl Sampler { | |
| } | ||
| } | ||
|
|
||
| processes_found += 1; | ||
| let pid = process.pid(); | ||
| if let Err(e) = self.handle_process(process, &mut aggr, include_smaps).await { | ||
| warn!("Encountered uncaught error when handling `/proc/{pid}/`: {e}"); | ||
| match self.handle_process(process, &mut aggr, include_smaps).await { | ||
| Ok(true) => { | ||
| // handled successfully | ||
| } | ||
| Ok(false) => { | ||
| pids_skipped.insert(pid); | ||
| } | ||
| Err(e) => { | ||
| warn!("Encountered uncaught error when handling `/proc/{pid}/`: {e}"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -130,10 +142,22 @@ impl Sampler { | |
|
|
||
| gauge!("total_rss_bytes").set(aggr.rss as f64); | ||
| gauge!("total_pss_bytes").set(aggr.pss as f64); | ||
| gauge!("processes_found").set(processes_found as f64); | ||
|
|
||
| // If we skipped any processes, log a warning. | ||
| if !pids_skipped.is_empty() { | ||
| warn!( | ||
| "Skipped {} processes: {:?}", | ||
| pids_skipped.len(), | ||
| pids_skipped | ||
| ); | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| /// Handle a process. Returns true if the process was handled successfully, | ||
| /// false if it was skipped for any reason. | ||
| #[allow( | ||
| clippy::similar_names, | ||
| clippy::too_many_lines, | ||
|
|
@@ -146,7 +170,7 @@ impl Sampler { | |
| process: Process, | ||
| aggr: &mut memory::smaps_rollup::Aggregator, | ||
| include_smaps: bool, | ||
| ) -> Result<(), Error> { | ||
| ) -> Result<bool, Error> { | ||
| let pid = process.pid(); | ||
|
|
||
| // `/proc/{pid}/status` | ||
|
|
@@ -156,12 +180,12 @@ impl Sampler { | |
| warn!("Couldn't read status: {:?}", e); | ||
| // The pid may have exited since we scanned it or we may not | ||
| // have sufficient permission. | ||
| return Ok(()); | ||
| return Ok(false); | ||
| } | ||
| }; | ||
| if status.tgid != pid { | ||
| // This is a thread, not a process and we do not wish to scan it. | ||
| return Ok(()); | ||
| return Ok(false); | ||
| } | ||
|
|
||
| // If we haven't seen this process before, initialize its ProcessInfo. | ||
|
|
@@ -174,7 +198,7 @@ impl Sampler { | |
| warn!("Couldn't read exe for pid {}: {:?}", pid, e); | ||
| // The pid may have exited since we scanned it or we may not | ||
| // have sufficient permission. | ||
| return Ok(()); | ||
| return Ok(false); | ||
| } | ||
| }; | ||
| let comm = match proc_comm(pid).await { | ||
|
|
@@ -183,7 +207,7 @@ impl Sampler { | |
| warn!("Couldn't read comm for pid {}: {:?}", pid, e); | ||
| // The pid may have exited since we scanned it or we may not | ||
| // have sufficient permission. | ||
| return Ok(()); | ||
| return Ok(false); | ||
| } | ||
| }; | ||
| let cmdline = match proc_cmdline(pid).await { | ||
|
|
@@ -192,7 +216,7 @@ impl Sampler { | |
| warn!("Couldn't read cmdline for pid {}: {:?}", pid, e); | ||
| // The pid may have exited since we scanned it or we may not | ||
| // have sufficient permission. | ||
| return Ok(()); | ||
| return Ok(false); | ||
| } | ||
| }; | ||
| let pid_s = format!("{pid}"); | ||
|
|
@@ -238,7 +262,7 @@ impl Sampler { | |
| // which will happen if we don't have permissions or, more | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the GH UI is preventing me from commenting on the right line but the:
is preventing us from simplifying the return to simply be |
||
| // likely, the process has exited. | ||
| warn!("Couldn't process `/proc/{pid}/stat`: {e}"); | ||
| return Ok(()); | ||
| return Ok(false); | ||
| } | ||
|
|
||
| if include_smaps { | ||
|
|
@@ -317,10 +341,10 @@ impl Sampler { | |
| // which will happen if we don't have permissions or, more | ||
| // likely, the process has exited. | ||
| warn!("Couldn't process `/proc/{pid}/smaps_rollup`: {err}"); | ||
| return Ok(()); | ||
| return Ok(false); | ||
| } | ||
|
|
||
| Ok(()) | ||
| Ok(true) | ||
| } | ||
| } | ||
|
|
||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We decided to go with consistency rather than correctness here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This lint doesn't need a change in the types, just in conversion. I think you can replace this with
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See our previous conversation: #1288 (comment)
I'd prefer to do a pass after where we address all of these together.