Skip to content

Commit e6e78e6

Browse files
committed
Fix deduplication to use PPID instead of PPNAME
- Changed unique key from name+uid+pid+ppname to name+uid+pid+ppid - PPID is more reliable (numeric) than PPNAME (can be None) - Properly tracks processes with same PID but different parent contexts - PPNAME is still included in output data for human readability
1 parent cdf0121 commit e6e78e6

1 file changed

Lines changed: 14 additions & 14 deletions

File tree

src/sysdiagnose/analysers/ps_everywhere.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def __extract_ps_base_file(self) -> Generator[dict, None, None]:
272272
module=self.module_name,
273273
data={'source': entity_type, 'uid': uid, 'pid': pid, 'ppid': ppid, 'ppname': ppname}
274274
)
275-
if self.add_if_full_command_is_not_in_set(ps_event.message, ps_event.datetime, uid, pid, ppname):
275+
if self.add_if_full_command_is_not_in_set(ps_event.message, ps_event.datetime, uid, pid, ppid):
276276
yield ps_event.to_dict()
277277
except Exception as e:
278278
logger.exception(f"ERROR while extracting {entity_type} file. {e}")
@@ -297,7 +297,7 @@ def __extract_ps_thread_file(self) -> Generator[dict, None, None]:
297297
module=self.module_name,
298298
data={'source': entity_type, 'uid': uid, 'pid': pid, 'ppid': ppid, 'ppname': ppname}
299299
)
300-
if self.add_if_full_command_is_not_in_set(ps_event.message, ps_event.datetime, uid, pid, ppname):
300+
if self.add_if_full_command_is_not_in_set(ps_event.message, ps_event.datetime, uid, pid, ppid):
301301
yield ps_event.to_dict()
302302
except Exception as e:
303303
logger.exception(f"ERROR while extracting {entity_type} file. {e}")
@@ -322,7 +322,7 @@ def __extract_ps_spindump_nosymbols_file(self) -> Generator[dict, None, None]:
322322
# Spindump has a direct 'parent' field with the parent process name
323323
ppname = p.get('parent')
324324

325-
if self.add_if_full_command_is_not_in_set(self._strip_flags(process_name), event_datetime, uid, pid, ppname):
325+
if self.add_if_full_command_is_not_in_set(self._strip_flags(process_name), event_datetime, uid, pid, ppid):
326326
yield Event(
327327
datetime=event_datetime,
328328
message=self._strip_flags(process_name),
@@ -334,7 +334,7 @@ def __extract_ps_spindump_nosymbols_file(self) -> Generator[dict, None, None]:
334334
for t in p['threads']:
335335
try:
336336
thread_name = f"{self._strip_flags(process_name)}::{t['thread_name']}"
337-
if self.add_if_full_command_is_not_in_set(thread_name, event_datetime, uid, pid, ppname):
337+
if self.add_if_full_command_is_not_in_set(thread_name, event_datetime, uid, pid, ppid):
338338
yield Event(
339339
datetime=event_datetime,
340340
message=self._strip_flags(thread_name),
@@ -547,21 +547,21 @@ def __extract_ps_logdata_statistics_txt(self) -> Generator[dict, None, None]:
547547
except Exception as e:
548548
logger.exception(f"ERROR while extracting {entity_type}. {e}")
549549

550-
def add_if_full_path_is_not_in_set(self, name: str, timestamp: Optional[datetime] = None, uid: Optional[int] = None, pid: Optional[int] = None, ppname: Optional[str] = None) -> bool:
550+
def add_if_full_path_is_not_in_set(self, name: str, timestamp: Optional[datetime] = None, uid: Optional[int] = None, pid: Optional[int] = None, ppid: Optional[int] = None) -> bool:
551551
"""
552552
Ensures that a process path is unique before adding it to the shared set,
553553
with time-based deduplication: only keep duplicates if they occur more than 1 hour apart.
554-
UID, PID, and PPNAME are considered part of the uniqueness - same process with different values is treated as separate.
554+
UID, PID, and PPID are considered part of the uniqueness - same process with different values is treated as separate.
555555
556556
:param name: Process path name
557557
:param timestamp: Timestamp of the process occurrence (optional, for time-based deduplication)
558558
:param uid: User ID of the process (optional, considered in uniqueness check)
559559
:param pid: Process ID (optional, considered in uniqueness check)
560-
:param ppname: Parent process name (optional, considered in uniqueness check)
560+
:param ppid: Parent Process ID (optional, considered in uniqueness check)
561561
:return: True if the process was not in the set or last seen > 1 hour ago, False otherwise.
562562
"""
563-
# Create a unique key that includes name, UID, PID, and PPNAME
564-
unique_key = f"{name}|uid:{uid}|pid:{pid}|ppname:{ppname}"
563+
# Create a unique key that includes name, UID, PID, and PPID
564+
unique_key = f"{name}|uid:{uid}|pid:{pid}|ppid:{ppid}"
565565

566566
# If no timestamp provided, use old behavior (always check for duplicates)
567567
if timestamp is None:
@@ -587,21 +587,21 @@ def add_if_full_path_is_not_in_set(self, name: str, timestamp: Optional[datetime
587587
self.process_last_seen[unique_key] = timestamp
588588
return True
589589

590-
def add_if_full_command_is_not_in_set(self, name: str, timestamp: Optional[datetime] = None, uid: Optional[int] = None, pid: Optional[int] = None, ppname: Optional[str] = None) -> bool:
590+
def add_if_full_command_is_not_in_set(self, name: str, timestamp: Optional[datetime] = None, uid: Optional[int] = None, pid: Optional[int] = None, ppid: Optional[int] = None) -> bool:
591591
"""
592592
Ensures that a process command is unique before adding it to the shared set,
593593
with time-based deduplication: only keep duplicates if they occur more than 1 hour apart.
594-
UID, PID, and PPNAME are considered part of the uniqueness - same process with different values is treated as separate.
594+
UID, PID, and PPID are considered part of the uniqueness - same process with different values is treated as separate.
595595
596596
:param name: Process command name
597597
:param timestamp: Timestamp of the process occurrence (optional, for time-based deduplication)
598598
:param uid: User ID of the process (optional, considered in uniqueness check)
599599
:param pid: Process ID (optional, considered in uniqueness check)
600-
:param ppname: Parent process name (optional, considered in uniqueness check)
600+
:param ppid: Parent Process ID (optional, considered in uniqueness check)
601601
:return: True if the process was not in the set or last seen > 1 hour ago, False otherwise.
602602
"""
603-
# Create a unique key that includes name, UID, PID, and PPNAME
604-
unique_key = f"{name}|uid:{uid}|pid:{pid}|ppname:{ppname}"
603+
# Create a unique key that includes name, UID, PID, and PPID
604+
unique_key = f"{name}|uid:{uid}|pid:{pid}|ppid:{ppid}"
605605

606606
# If no timestamp provided, use old behavior (always check for duplicates)
607607
if timestamp is None:

0 commit comments

Comments
 (0)