|
@@ -122,12 +122,13 @@ def read_trace_records(event_mapping, event_id_to_name, fobj):
|
|
|
|
|
|
yield rec
|
|
yield rec
|
|
|
|
|
|
-class Analyzer(object):
|
|
|
|
|
|
+class Analyzer:
|
|
"""A trace file analyzer which processes trace records.
|
|
"""A trace file analyzer which processes trace records.
|
|
|
|
|
|
An analyzer can be passed to run() or process(). The begin() method is
|
|
An analyzer can be passed to run() or process(). The begin() method is
|
|
invoked, then each trace record is processed, and finally the end() method
|
|
invoked, then each trace record is processed, and finally the end() method
|
|
- is invoked.
|
|
|
|
|
|
+ is invoked. When Analyzer is used as a context-manager (using the `with`
|
|
|
|
+ statement), begin() and end() are called automatically.
|
|
|
|
|
|
If a method matching a trace event name exists, it is invoked to process
|
|
If a method matching a trace event name exists, it is invoked to process
|
|
that trace record. Otherwise the catchall() method is invoked.
|
|
that trace record. Otherwise the catchall() method is invoked.
|
|
@@ -165,6 +166,15 @@ def end(self):
|
|
"""Called at the end of the trace."""
|
|
"""Called at the end of the trace."""
|
|
pass
|
|
pass
|
|
|
|
|
|
|
|
+ def __enter__(self):
|
|
|
|
+ self.begin()
|
|
|
|
+ return self
|
|
|
|
+
|
|
|
|
+ def __exit__(self, exc_type, exc_val, exc_tb):
|
|
|
|
+ if exc_type is None:
|
|
|
|
+ self.end()
|
|
|
|
+ return False
|
|
|
|
+
|
|
def process(events, log, analyzer, read_header=True):
|
|
def process(events, log, analyzer, read_header=True):
|
|
"""Invoke an analyzer on each event in a log.
|
|
"""Invoke an analyzer on each event in a log.
|
|
Args:
|
|
Args:
|
|
@@ -226,15 +236,14 @@ def build_fn(analyzer, event):
|
|
# Just arguments, no timestamp or pid
|
|
# Just arguments, no timestamp or pid
|
|
return lambda _, rec: fn(*rec[3:3 + event_argcount])
|
|
return lambda _, rec: fn(*rec[3:3 + event_argcount])
|
|
|
|
|
|
- analyzer.begin()
|
|
|
|
- fn_cache = {}
|
|
|
|
- for rec in read_trace_records(event_mapping, event_id_to_name, log):
|
|
|
|
- event_num = rec[0]
|
|
|
|
- event = event_mapping[event_num]
|
|
|
|
- if event_num not in fn_cache:
|
|
|
|
- fn_cache[event_num] = build_fn(analyzer, event)
|
|
|
|
- fn_cache[event_num](event, rec)
|
|
|
|
- analyzer.end()
|
|
|
|
|
|
+ with analyzer:
|
|
|
|
+ fn_cache = {}
|
|
|
|
+ for rec in read_trace_records(event_mapping, event_id_to_name, log):
|
|
|
|
+ event_num = rec[0]
|
|
|
|
+ event = event_mapping[event_num]
|
|
|
|
+ if event_num not in fn_cache:
|
|
|
|
+ fn_cache[event_num] = build_fn(analyzer, event)
|
|
|
|
+ fn_cache[event_num](event, rec)
|
|
|
|
|
|
if close_log:
|
|
if close_log:
|
|
log.close()
|
|
log.close()
|