-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmem_rep_parser.py
More file actions
175 lines (137 loc) · 5.8 KB
/
Copy pathmem_rep_parser.py
File metadata and controls
175 lines (137 loc) · 5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import logging
import regexes
import re
from dataclasses import dataclass
import utils
class MemRepParser:
@dataclass
class Report:
arena_total: str = None
arena_stats: dict = None
cfs_total: str = None
cfs_stats: dict = None
misc_stats: dict = None
@staticmethod
def is_start_line(line):
return re.fullmatch(regexes.MEM_REP_TITLE, line) is not None
def __init__(self):
self.reports = dict()
def try_adding_entries(self, log_entries, start_entry_idx):
entry_idx = start_entry_idx
entry = log_entries[entry_idx]
mem_rep_lines = utils.remove_empty_lines_at_start(
entry.get_msg_lines())
if not mem_rep_lines:
return False, entry_idx
if not MemRepParser.is_start_line(mem_rep_lines[0]):
return False, entry_idx
try:
logging.debug(f"Parsing Memory Report Entry ("
f"{utils.format_line_num_from_entry(entry)}")
time = entry.get_time()
self.add_lines(time, mem_rep_lines)
except utils.ParsingError:
logging.error(f"Error while parsing Memory Report entry, "
f"Skipping.\nentry:{entry}")
entry_idx += 1
return True, entry_idx
def add_lines(self, time, mem_rep_lines):
assert len(mem_rep_lines) > 0
assert MemRepParser.is_start_line(mem_rep_lines[0])
report = MemRepParser.Report()
line_idx = 1
arena_total, arena_section_stats, line_idx = \
MemRepParser.parse_arena_stats_lines(mem_rep_lines, line_idx)
report.arena_total = arena_total
report.arena_stats = arena_section_stats
cfs_total, cfs_section_stats, line_idx = \
MemRepParser.parse_cfs_stats_lines(mem_rep_lines, line_idx)
report.cfs_total = cfs_total
report.cfs_stats = cfs_section_stats
misc_section_stats, line_idx = \
MemRepParser.parse_misc_stats_lines(mem_rep_lines, line_idx)
report.misc_stats = misc_section_stats
self.reports[time] = report
def get_reports(self):
return self.reports
@staticmethod
def parse_arena_stats_lines(mem_rep_lines, start_line_idx):
line_idx = start_line_idx
if not MemRepParser.is_arena_stats_title_line(mem_rep_lines[line_idx]):
raise utils.ParsingError(
f"Missing expected Arena Stats title. line:\n"
f"{mem_rep_lines[line_idx]}")
line_idx += 1
total_match = MemRepParser.parse_total_line(mem_rep_lines[line_idx])
if not total_match:
raise utils.ParsingError(
f"Missing expected Arena Total line. line:\n"
f"{mem_rep_lines[line_idx]}")
arena_total = total_match["usage"]
line_idx += 1
arena_section_stats, line_idx = \
MemRepParser.parse_section_stats(mem_rep_lines, line_idx,
regexes.MEM_REP_ENTITY_USAGE_LINE,
"entity",
regexes.MEM_REP_CFS_STATS_TITLE)
return arena_total, arena_section_stats, line_idx
@staticmethod
def parse_cfs_stats_lines(mem_rep_lines, start_line_idx):
line_idx = start_line_idx
if not MemRepParser.is_cfs_stats_title_line(mem_rep_lines[line_idx]):
raise utils.ParsingError(
f"Missing expected CF-s Stats title. line:\n"
f"{mem_rep_lines[line_idx]}")
line_idx += 1
total_match = MemRepParser.parse_total_line(mem_rep_lines[line_idx])
if not total_match:
raise utils.ParsingError(
f"Missing expected CF-s Total line. line:\n"
f"{mem_rep_lines[line_idx]}")
cfs_total = total_match["usage"]
line_idx += 1
arena_section_stats, line_idx = \
MemRepParser.parse_section_stats(mem_rep_lines, line_idx,
regexes.MEM_REP_CF_USAGE_LINE,
"cf")
return cfs_total, arena_section_stats, line_idx
@staticmethod
def parse_misc_stats_lines(mem_rep_lines, start_line_idx):
line_idx = start_line_idx
return \
MemRepParser.parse_section_stats(mem_rep_lines, line_idx,
regexes.MEM_REP_ENTITY_USAGE_LINE,
"entity")
@staticmethod
def parse_section_stats(mem_rep_lines, line_idx,
usage_line_regex,
key_name,
end_line_regex=None):
section_stats = dict()
while line_idx < len(mem_rep_lines):
line = mem_rep_lines[line_idx].strip()
# Finish when finding the specified end regex
if end_line_regex:
if re.fullmatch(end_line_regex, line) is not None:
break
# But also finish when not finding another usage line
match = re.fullmatch(usage_line_regex, line)
if match is None:
break
section_stats[match[key_name]] = match["usage"]
line_idx += 1
return section_stats, line_idx
@staticmethod
def parse_total_line(line):
return re.fullmatch(regexes.MEM_REP_TOTAL_LINE, line)
@staticmethod
def is_total_line(line):
return MemRepParser.parse_total_line(line) is not None
@staticmethod
def is_arena_stats_title_line(line):
return re.fullmatch(regexes.MEM_REP_ARENA_STATS_TITLE, line) is not \
None
@staticmethod
def is_cfs_stats_title_line(line):
return re.fullmatch(regexes.MEM_REP_CFS_STATS_TITLE, line) is not \
None