2525###############################################################################
2626from typing import Optional
2727
28+ from pydantic import ValidationError
29+
2830from nodescraper .base import InBandDataCollector
2931from nodescraper .enums import EventCategory , EventPriority , ExecutionStatus , OSFamily
3032from nodescraper .models import TaskResult
33+ from nodescraper .utils import get_exception_details
3134
35+ from .collector_args import JournalCollectorArgs
3236from .journaldata import JournalData
3337
3438
35- class JournalCollector (InBandDataCollector [JournalData , None ]):
39+ class JournalCollector (InBandDataCollector [JournalData , JournalCollectorArgs ]):
3640 """Read journal log via journalctl."""
3741
3842 SUPPORTED_OS_FAMILY = {OSFamily .LINUX }
3943 DATA_MODEL = JournalData
4044 CMD = "journalctl --no-pager --system --output=short-iso"
4145
42- def _read_with_journalctl (self ):
46+ def _read_with_journalctl (self , args : Optional [ JournalCollectorArgs ] = None ):
4347 """Read journal logs using journalctl
4448
4549 Returns:
4650 str|None: system journal read
4751 """
48- res = self ._run_sut_cmd (self .CMD , sudo = True , log_artifact = False , strip = False )
52+
53+ cmd = "journalctl --no-pager --system --output=short-iso"
54+ try :
55+ # safe check for args.boot
56+ if args is not None and getattr (args , "boot" , None ):
57+ cmd = f"journalctl --no-pager -b { args .boot } --system --output=short-iso"
58+
59+ res = self ._run_sut_cmd (cmd , sudo = True , log_artifact = False , strip = False )
60+
61+ except ValidationError as val_err :
62+ self ._log_event (
63+ category = EventCategory .OS ,
64+ description = "Exception while running journalctl" ,
65+ data = get_exception_details (val_err ),
66+ priority = EventPriority .ERROR ,
67+ console_log = True ,
68+ )
69+ self .result .message = "Could not read journalctl data"
70+ self .result .status = ExecutionStatus .ERROR
71+ return None
4972
5073 if res .exit_code != 0 :
5174 self ._log_event (
@@ -61,16 +84,22 @@ def _read_with_journalctl(self):
6184
6285 return res .stdout
6386
64- def collect_data (self , args = None ) -> tuple [TaskResult , Optional [JournalData ]]:
87+ def collect_data (
88+ self ,
89+ args : Optional [JournalCollectorArgs ] = None ,
90+ ) -> tuple [TaskResult , Optional [JournalData ]]:
6591 """Collect journal logs
6692
6793 Args:
6894 args (_type_, optional): Collection args. Defaults to None.
6995
7096 Returns:
71- tuple[TaskResult, Optional[JournalData, None ]]: Tuple of results and data model or none.
97+ tuple[TaskResult, Optional[JournalData]]: Tuple of results and data model or none.
7298 """
73- journal_log = self ._read_with_journalctl ()
99+ if args is None :
100+ args = JournalCollectorArgs ()
101+
102+ journal_log = self ._read_with_journalctl (args )
74103 if journal_log :
75104 data = JournalData (journal_log = journal_log )
76105 self .result .message = self .result .message or "Journal data collected"
0 commit comments