@@ -19,7 +19,6 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
19
19
use std:: { collections:: HashMap , os:: unix:: process:: CommandExt , process:: Command } ;
20
20
21
21
use envmnt:: { ExpandOptions , ExpansionType } ;
22
-
23
22
use log:: error;
24
23
use nom:: AsBytes ;
25
24
use procfs:: { process:: Process , ProcError , ProcResult } ;
@@ -42,6 +41,7 @@ use crate::config::{
42
41
pub struct ProcessData {
43
42
pub name : String , // the replaced name
44
43
pub pid : u64 ,
44
+ pub ppid : u64 ,
45
45
pub process_name : String , // raw process name
46
46
pub cmd : Vec < String > ,
47
47
pub user_id : u32 ,
@@ -113,6 +113,12 @@ impl TryFrom<&Process> for ProcessData {
113
113
Ok ( ProcessData {
114
114
name : proc_name. to_string_lossy ( ) . to_string ( ) ,
115
115
pid : proc. pid as u64 ,
116
+ ppid : if let Ok ( stat) = proc. stat ( ) . as_ref ( ) {
117
+ stat. ppid as u64
118
+ } else {
119
+ error ! ( "pid {} get stat fail" , proc. pid) ;
120
+ 0
121
+ } ,
116
122
process_name : proc_name. to_string_lossy ( ) . to_string ( ) ,
117
123
cmd,
118
124
user_id : uid,
@@ -356,6 +362,7 @@ pub(super) fn get_all_process(conf: &OsProcScanConfig) -> Vec<ProcessData> {
356
362
}
357
363
}
358
364
}
365
+ fill_child_proc_tag_by_parent ( ret. as_mut ( ) ) ;
359
366
proc_scan_hook ( & mut ret) ;
360
367
}
361
368
return ret;
@@ -408,3 +415,49 @@ fn get_os_app_tag_by_exec(
408
415
Err ( e) => Err ( format ! ( "unmarshal to yaml fail: {}\n stdout: {}" , e, stdout) . to_string ( ) ) ,
409
416
}
410
417
}
418
+
419
+ fn fill_child_proc_tag_by_parent ( procs : & mut Vec < ProcessData > ) {
420
+ let merge_tag = |child_tag : & mut Vec < OsAppTagKV > , parent_tag : & [ OsAppTagKV ] | {
421
+ ' l: for pt in parent_tag {
422
+ // ignore key is in exist in child
423
+ for ct in child_tag. iter ( ) {
424
+ if ct. key == pt. key {
425
+ continue ' l;
426
+ }
427
+ }
428
+ child_tag. push ( pt. clone ( ) ) ;
429
+ }
430
+ } ;
431
+
432
+ // Hashmap<pid, proc_idx> use for fill child proc tag from parent tag
433
+ let mut pid_map = HashMap :: new ( ) ;
434
+ for ( i, p) in procs. iter ( ) . enumerate ( ) {
435
+ pid_map. insert ( p. pid , i) ;
436
+ }
437
+
438
+ for child_idx in 0 ..procs. len ( ) {
439
+ let child_ppid = procs. get ( child_idx) . unwrap ( ) . ppid ;
440
+ let Some ( parent_idx) = pid_map. get ( & child_ppid) else {
441
+ continue ;
442
+ } ;
443
+
444
+ if child_idx == * parent_idx {
445
+ error ! ( "pid: {} child pid equal to parent pid" , child_ppid) ;
446
+ continue ;
447
+ }
448
+
449
+ let ( child, parent) = if child_idx > * parent_idx {
450
+ let ( left, right) = procs. split_at_mut ( child_idx) ;
451
+ let child = right. get_mut ( 0 ) . unwrap ( ) ;
452
+ let parent: & ProcessData = left. get ( * parent_idx) . unwrap ( ) ;
453
+ ( child, parent)
454
+ } else {
455
+ let ( left, right) = procs. split_at_mut ( * parent_idx) ;
456
+ let child = left. get_mut ( child_idx) . unwrap ( ) ;
457
+ let parent: & ProcessData = right. get ( 0 ) . unwrap ( ) ;
458
+ ( child, parent)
459
+ } ;
460
+
461
+ merge_tag ( & mut child. os_app_tags , & parent. os_app_tags ) ;
462
+ }
463
+ }
0 commit comments