Commit | Line | Data |
---|---|---|
323b3fd6 | 1 | import linuxautomaton.automaton |
bd3cd7c5 JD |
2 | from lttnganalysescli import progressbar |
3 | from linuxautomaton import common | |
4 | from babeltrace import TraceCollection | |
323b3fd6 PP |
5 | import argparse |
6 | import sys | |
7 | ||
8 | ||
9 | class Command: | |
bd3cd7c5 | 10 | def __init__(self, add_arguments_cb, enable_proc_filter_args): |
323b3fd6 | 11 | self._add_arguments_cb = add_arguments_cb |
bd3cd7c5 JD |
12 | if enable_proc_filter_args: |
13 | self._enable_proc_filter_args = True | |
323b3fd6 PP |
14 | self._create_automaton() |
15 | ||
16 | def _error(self, msg, exit_code=1): | |
17 | print(msg, file=sys.stderr) | |
18 | sys.exit(exit_code) | |
19 | ||
20 | def _gen_error(self, msg, exit_code=1): | |
21 | self._error('Error: {}'.format(msg), exit_code) | |
22 | ||
23 | def _cmdline_error(self, msg, exit_code=1): | |
24 | self._error('Command line error: {}'.format(msg), exit_code) | |
25 | ||
bd3cd7c5 JD |
26 | def _open_trace(self): |
27 | traces = TraceCollection() | |
28 | handle = traces.add_traces_recursive(self._arg_path, "ctf") | |
29 | if handle == {}: | |
30 | self._gen_error("Failed to open " + self._arg_path, -1) | |
31 | self._handle = handle | |
32 | self._traces = traces | |
33 | common.process_date_args(self) | |
34 | ||
35 | def _close_trace(self): | |
36 | for h in self._handle.values(): | |
37 | self._traces.remove_trace(h) | |
38 | ||
39 | def _run_analysis(self, reset_cb, refresh_cb): | |
40 | self.trace_start_ts = 0 | |
41 | self.trace_end_ts = 0 | |
42 | self.current_sec = 0 | |
43 | self.start_ns = 0 | |
44 | self.end_ns = 0 | |
45 | started = 0 | |
46 | progressbar.progressbar_setup(self) | |
47 | if not self._arg_begin: | |
48 | started = 1 | |
49 | for event in self._traces.events: | |
50 | progressbar.progressbar_update(self) | |
51 | if self._arg_begin and started == 0 and \ | |
52 | event.timestamp >= self._arg_begin: | |
53 | started = 1 | |
54 | self.trace_start_ts = event.timestamp | |
55 | self.start_ns = event.timestamp | |
56 | reset_cb(event.timestamp) | |
57 | if self._arg_end and event.timestamp > self._arg_end: | |
58 | break | |
59 | if self.start_ns == 0: | |
60 | self.start_ns = event.timestamp | |
61 | if self.trace_start_ts == 0: | |
62 | self.trace_start_ts = event.timestamp | |
63 | self.end_ns = event.timestamp | |
64 | self._check_refresh(event, refresh_cb) | |
65 | self.trace_end_ts = event.timestamp | |
66 | # feed automaton | |
67 | self._automaton.process_event(event) | |
68 | # feed analysis | |
69 | self._analysis.process_event(event) | |
70 | progressbar.progressbar_finish(self) | |
71 | ||
72 | def _check_refresh(self, event, refresh_cb): | |
73 | """Check if we need to output something""" | |
74 | if self._arg_refresh == 0: | |
75 | return | |
76 | event_sec = event.timestamp / common.NSEC_PER_SEC | |
77 | if self.current_sec == 0: | |
78 | self.current_sec = event_sec | |
79 | elif self.current_sec != event_sec and \ | |
80 | (self.current_sec + self._arg_refresh) <= event_sec: | |
81 | refresh_cb(self.start_ns, event.timestamp) | |
82 | self.current_sec = event_sec | |
83 | self.start_ns = event.timestamp | |
84 | ||
85 | def _validate_transform_common_args(self, args): | |
86 | self._arg_path = args.path | |
87 | self._arg_proc_list = None | |
88 | if args.procname: | |
89 | self._arg_proc_list = args.procname.split(",") | |
90 | self._arg_pid_list = None | |
91 | if args.pid: | |
92 | self._arg_pid_list = args.pid.split(",") | |
93 | if args.limit: | |
94 | self._arg_limit = args.limit | |
95 | self._arg_begin = None | |
96 | if args.begin: | |
97 | self._arg_begin = args.begin | |
98 | self._arg_end = None | |
99 | if args.end: | |
100 | self._arg_end = args.end | |
101 | self._arg_timerange = None | |
102 | if args.timerange: | |
103 | self._arg_timerange = args.timerange | |
104 | self._arg_gmt = None | |
105 | if args.gmt: | |
106 | self._arg_gmt = args.gmt | |
107 | self._arg_refresh = args.refresh | |
108 | self._arg_no_progress = args.no_progress | |
109 | ||
323b3fd6 PP |
110 | def _parse_args(self): |
111 | ap = argparse.ArgumentParser(description=self._DESC) | |
112 | ||
113 | # common arguments | |
bd3cd7c5 JD |
114 | ap.add_argument('path', metavar="<path/to/trace>", help='trace path') |
115 | ap.add_argument('-r', '--refresh', type=int, | |
116 | help='Refresh period in seconds', default=0) | |
117 | ap.add_argument('--limit', type=int, default=10, | |
118 | help='Limit to top X (default = 10)') | |
119 | ap.add_argument('--no-progress', action="store_true", | |
120 | help='Don\'t display the progress bar') | |
121 | ap.add_argument('--gmt', action="store_true", | |
122 | help='Manipulate timestamps based on GMT instead ' | |
123 | 'of local time') | |
124 | ap.add_argument('--begin', type=str, help='start time: ' | |
125 | 'hh:mm:ss[.nnnnnnnnn]') | |
126 | ap.add_argument('--end', type=str, help='end time: ' | |
127 | 'hh:mm:ss[.nnnnnnnnn]') | |
128 | ap.add_argument('--timerange', type=str, help='time range: ' | |
129 | '[begin,end]') | |
130 | ||
131 | if self._enable_proc_filter_args: | |
132 | ap.add_argument('--procname', type=str, default=0, | |
133 | help='Filter the results only for this list of ' | |
134 | 'process names') | |
135 | ap.add_argument('--pid', type=str, default=0, | |
136 | help='Filter the results only for this list ' | |
137 | 'of PIDs') | |
323b3fd6 PP |
138 | |
139 | # specific arguments | |
140 | self._add_arguments_cb(ap) | |
141 | ||
142 | # version of the specific command | |
323b3fd6 PP |
143 | ap.add_argument('-V', '--version', action='version', |
144 | version=self._VERSION) | |
145 | ||
146 | # parse arguments | |
147 | args = ap.parse_args() | |
148 | ||
bd3cd7c5 | 149 | self._validate_transform_common_args(args) |
323b3fd6 | 150 | |
323b3fd6 PP |
151 | # save all arguments |
152 | self._args = args | |
153 | ||
154 | def _create_automaton(self): | |
155 | self._automaton = linuxautomaton.automaton.Automaton() |