Skip to content

Commit

Permalink
chg: more timeline based output
Browse files Browse the repository at this point in the history
  • Loading branch information
cvandeplas committed Dec 18, 2024
1 parent d898f17 commit 2235073
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 25 deletions.
1 change: 1 addition & 0 deletions src/sysdiagnose/parsers/appinstallation.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

class AppInstallationParser(BaseParserInterface):
description = "Parsing app installation logs"
format = 'jsonl'

def __init__(self, config: dict, case_id: str):
super().__init__(__file__, config, case_id)
Expand Down
2 changes: 1 addition & 1 deletion src/sysdiagnose/parsers/lockdownd.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import glob
import os
from sysdiagnose.utils.base import BaseParserInterface
from datetime import datetime, timezone
from datetime import datetime
import re


Expand Down
25 changes: 21 additions & 4 deletions src/sysdiagnose/parsers/olddsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
import glob
import os
from sysdiagnose.utils.misc import load_plist_file_as_json
from sysdiagnose.utils.base import BaseParserInterface
from sysdiagnose.utils.base import BaseParserInterface, logger


class OldDscParser(BaseParserInterface):
description = "Parsing olddsc files"
format = 'jsonl'

json_pretty = False

def __init__(self, config: dict, case_id: str):
Expand All @@ -28,10 +30,25 @@ def get_log_files(self) -> dict:

return log_files

def execute(self) -> list | dict:
def execute(self) -> list:
timestamp_dict = {}
timestamp = self.sysdiagnose_creation_datetime
timestamp_dict['timestamp'] = timestamp.timestamp()
timestamp_dict['datetime'] = timestamp.isoformat(timespec='microseconds')
timestamp_dict['timestamp_desc'] = 'sysdiagnose creation'

entries = []
# we're not doing anything with
# - Unslid_Base_Address
# - Cache_UUID_String
# only acting on Binaries list
for log_file in self.get_log_files():
return OldDscParser.parse_file(log_file)
return {'error': ['No olddsc files present']}
for entry in OldDscParser.parse_file(log_file).get('Binaries', []):
entry.update(timestamp_dict)
entries.append(entry)
if not entries:
logger.warning('No olddsc files present')
return entries

def parse_file(path: str) -> list | dict:
try:
Expand Down
22 changes: 16 additions & 6 deletions src/sysdiagnose/parsers/psthread.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
import glob
import os
import re
from sysdiagnose.utils.base import BaseParserInterface
from sysdiagnose.utils.base import BaseParserInterface, logger
from sysdiagnose.utils.misc import snake_case


class PsThreadParser(BaseParserInterface):
description = "Parsing ps_thread.txt file"
format = 'jsonl'

def __init__(self, config: dict, case_id: str):
super().__init__(__file__, config, case_id)
Expand All @@ -31,8 +33,15 @@ def get_log_files(self) -> list:

return log_files

def execute(self) -> list | dict:
# TODO not really easy to conver to timebased jsonl, as the timestamp is complex to compute.
def execute(self) -> list:
# not really easy to conver to true timebased jsonl, as the timestamp is complex to compute.
# so we just fall back to the sysdiagnose creation timestamp
timestamp_dict = {}
timestamp = self.sysdiagnose_creation_datetime
timestamp_dict['timestamp'] = timestamp.timestamp()
timestamp_dict['datetime'] = timestamp.isoformat(timespec='microseconds')
timestamp_dict['timestamp_desc'] = 'sysdiagnose creation'
timestamp_dict['THREADS'] = 1

result = []
try:
Expand All @@ -47,11 +56,11 @@ def execute(self) -> list | dict:
result.append(row)

patterns = line.strip().split(None, header_length - 1)
row = {'THREADS': 1}
row = timestamp_dict.copy()
# merge last entries together, as last entry may contain spaces
for col in range(header_length):
# try to cast as int, float and fallback to string
col_name = header[col]
col_name = snake_case(header[col])
try:
row[col_name] = int(patterns[col])
continue
Expand All @@ -67,4 +76,5 @@ def execute(self) -> list | dict:
result.append(row)
return result
except IndexError:
return {'error': 'No ps_thread.txt file present'}
logger.warning('No ps_thread.txt file present')
return []
13 changes: 10 additions & 3 deletions src/sysdiagnose/parsers/sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
import os
import glob
import sysdiagnose.utils.misc as misc
from sysdiagnose.utils.base import BaseParserInterface
from sysdiagnose.utils.base import BaseParserInterface, logger


class SystemVersionParser(BaseParserInterface):
description = "Parsing SystemVersion plist file"
format = 'jsonl'

def __init__(self, config: dict, case_id: str):
super().__init__(__file__, config, case_id)
Expand All @@ -30,9 +31,15 @@ def get_log_files(self) -> list:

def execute(self) -> list | dict:
try:
return SystemVersionParser.parse_file(self.get_log_files()[0])
entry = SystemVersionParser.parse_file(self.get_log_files()[0])
timestamp = self.sysdiagnose_creation_datetime
entry['timestamp_desc'] = 'sysdiagnose creation'
entry['timestamp'] = timestamp.timestamp()
entry['datetime'] = timestamp.isoformat(timespec='microseconds')
return [entry]
except IndexError:
return {'error': 'No SystemVersion.plist file present'}
logger.warning('No SystemVersion.plist file present')
return []

def parse_file(path: str) -> list | dict:
return misc.load_plist_file_as_json(path)
Expand Down
10 changes: 6 additions & 4 deletions tests/test_parsers_olddsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ def test_parse_olddsc_file(self):
self.assertTrue(os.path.isfile(p.output_file))

result = p.get_result()
self.assertTrue('Unslid_Base_Address' in result)
self.assertTrue('Cache_UUID_String' in result)
self.assertTrue('Binaries' in result)
self.assertTrue(len(result['Binaries']) > 0)
for entry in result:
self.assertTrue('Load_Address' in entry)
# self.assertTrue('Unslid_Base_Address' in result)
# self.assertTrue('Cache_UUID_String' in result)
# self.assertTrue('Binaries' in result)
# self.assertTrue(len(result['Binaries']) > 0)


if __name__ == '__main__':
Expand Down
6 changes: 3 additions & 3 deletions tests/test_parsers_psthread.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ def test_parse_psthread(self):
result = p.get_result()
if result: # not all logs contain data
for item in result:
self.assertTrue('COMMAND' in item)
self.assertTrue('PID' in item)
self.assertTrue('USER' in item)
self.assertTrue('command' in item)
self.assertTrue('pid' in item)
self.assertTrue('user' in item)


if __name__ == '__main__':
Expand Down
8 changes: 4 additions & 4 deletions tests/test_parsers_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def test_getProductInfo(self):

result = p.get_result()
self.assertGreater(len(result), 0)

self.assertTrue(result.keys() | self.productinfo_keys == result.keys()) # check if the result contains at least the following keys
self.assertTrue('iPhone OS' in result['ProductName'])
self.assertTrue(result['BuildID'])
for item in result:
self.assertTrue(item.keys() | self.productinfo_keys == item.keys()) # check if the result contains at least the following keys
self.assertTrue('iPhone OS' in item['ProductName'])
self.assertTrue(item['BuildID'])


if __name__ == '__main__':
Expand Down

0 comments on commit 2235073

Please sign in to comment.