@@ -83,6 +83,8 @@ impl Sampler {
8383 // A tally of the total RSS and PSS consumed by the parent process and
8484 // its children.
8585 let mut aggr = memory:: smaps_rollup:: Aggregator :: default ( ) ;
86+ let mut processes_found: i32 = 0 ;
87+ let mut pids_skipped: FxHashSet < i32 > = FxHashSet :: default ( ) ;
8688
8789 // Every sample run we collect all the child processes rooted at the
8890 // parent. As noted by the procfs documentation is this done by
@@ -119,9 +121,12 @@ impl Sampler {
119121 }
120122 }
121123
124+ processes_found += 1 ;
122125 let pid = process. pid ( ) ;
123- if let Err ( e) = self . handle_process ( process, & mut aggr, include_smaps) . await {
124- warn ! ( "Encountered uncaught error when handling `/proc/{pid}/`: {e}" ) ;
126+ match self . handle_process ( process, & mut aggr, include_smaps) . await {
127+ Ok ( false ) => {
128+ pids_skipped. insert ( pid) ;
129+ }
125130 }
126131 }
127132
@@ -130,10 +135,22 @@ impl Sampler {
130135
131136 gauge ! ( "total_rss_bytes" ) . set ( aggr. rss as f64 ) ;
132137 gauge ! ( "total_pss_bytes" ) . set ( aggr. pss as f64 ) ;
138+ gauge ! ( "processes_found" ) . set ( processes_found as f64 ) ;
139+
140+ // If we skipped any processes, log a warning.
141+ if !pids_skipped. is_empty ( ) {
142+ warn ! (
143+ "Skipped {} processes: {:?}" ,
144+ pids_skipped. len( ) ,
145+ pids_skipped
146+ ) ;
147+ }
133148
134149 Ok ( ( ) )
135150 }
136151
152+ /// Handle a process. Returns true if the process was handled successfully,
153+ /// false if it was skipped for any reason.
137154 #[ allow(
138155 clippy:: similar_names,
139156 clippy:: too_many_lines,
@@ -146,7 +163,7 @@ impl Sampler {
146163 process : Process ,
147164 aggr : & mut memory:: smaps_rollup:: Aggregator ,
148165 include_smaps : bool ,
149- ) -> Result < ( ) , Error > {
166+ ) -> bool {
150167 let pid = process. pid ( ) ;
151168
152169 // `/proc/{pid}/status`
@@ -156,12 +173,12 @@ impl Sampler {
156173 warn ! ( "Couldn't read status: {:?}" , e) ;
157174 // The pid may have exited since we scanned it or we may not
158175 // have sufficient permission.
159- return Ok ( ( ) ) ;
176+ return false ;
160177 }
161178 } ;
162179 if status. tgid != pid {
163180 // This is a thread, not a process and we do not wish to scan it.
164- return Ok ( ( ) ) ;
181+ return false ;
165182 }
166183
167184 // If we haven't seen this process before, initialize its ProcessInfo.
@@ -174,7 +191,7 @@ impl Sampler {
174191 warn ! ( "Couldn't read exe for pid {}: {:?}" , pid, e) ;
175192 // The pid may have exited since we scanned it or we may not
176193 // have sufficient permission.
177- return Ok ( ( ) ) ;
194+ return Ok ( false ) ;
178195 }
179196 } ;
180197 let comm = match proc_comm ( pid) . await {
@@ -183,7 +200,7 @@ impl Sampler {
183200 warn ! ( "Couldn't read comm for pid {}: {:?}" , pid, e) ;
184201 // The pid may have exited since we scanned it or we may not
185202 // have sufficient permission.
186- return Ok ( ( ) ) ;
203+ return Ok ( false ) ;
187204 }
188205 } ;
189206 let cmdline = match proc_cmdline ( pid) . await {
@@ -192,7 +209,7 @@ impl Sampler {
192209 warn ! ( "Couldn't read cmdline for pid {}: {:?}" , pid, e) ;
193210 // The pid may have exited since we scanned it or we may not
194211 // have sufficient permission.
195- return Ok ( ( ) ) ;
212+ return Ok ( false ) ;
196213 }
197214 } ;
198215 let pid_s = format ! ( "{pid}" ) ;
@@ -238,7 +255,7 @@ impl Sampler {
238255 // which will happen if we don't have permissions or, more
239256 // likely, the process has exited.
240257 warn ! ( "Couldn't process `/proc/{pid}/stat`: {e}" ) ;
241- return Ok ( ( ) ) ;
258+ return false ;
242259 }
243260
244261 if include_smaps {
@@ -317,10 +334,10 @@ impl Sampler {
317334 // which will happen if we don't have permissions or, more
318335 // likely, the process has exited.
319336 warn ! ( "Couldn't process `/proc/{pid}/smaps_rollup`: {err}" ) ;
320- return Ok ( ( ) ) ;
337+ return false ;
321338 }
322339
323- Ok ( ( ) )
340+ return true ;
324341 }
325342}
326343
0 commit comments