3 # The MIT License (MIT)
5 # Copyright (C) 2015 - Julien Desfossez <jdesfosez@efficios.com>
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 import linuxautomaton
.automaton
26 from lttnganalysescli
import progressbar
27 from linuxautomaton
import common
28 from babeltrace
import TraceCollection
34 def __init__(self
, add_arguments_cb
,
35 enable_proc_filter_args
=False,
36 enable_max_min_args
=False,
37 enable_max_min_size_arg
=False,
38 enable_freq_arg
=False,
40 enable_stats_arg
=False):
41 self
._add
_arguments
_cb
= add_arguments_cb
42 self
._enable
_proc
_filter
_args
= enable_proc_filter_args
43 self
._enable
_max
_min
_arg
= enable_max_min_args
44 self
._enable
_max
_min
_size
_arg
= enable_max_min_size_arg
45 self
._enable
_freq
_arg
= enable_freq_arg
46 self
._enable
_log
_arg
= enable_log_arg
47 self
._enable
_stats
_arg
= enable_stats_arg
48 self
._create
_automaton
()
50 def _error(self
, msg
, exit_code
=1):
51 print(msg
, file=sys
.stderr
)
54 def _gen_error(self
, msg
, exit_code
=1):
55 self
._error
('Error: {}'.format(msg
), exit_code
)
57 def _cmdline_error(self
, msg
, exit_code
=1):
58 self
._error
('Command line error: {}'.format(msg
), exit_code
)
60 def _open_trace(self
):
61 traces
= TraceCollection()
62 handle
= traces
.add_traces_recursive(self
._arg
_path
, "ctf")
64 self
._gen
_error
("Failed to open " + self
._arg
_path
, -1)
67 common
.process_date_args(self
)
69 def _close_trace(self
):
70 for h
in self
._handle
.values():
71 self
._traces
.remove_trace(h
)
73 def _run_analysis(self
, reset_cb
, refresh_cb
, break_cb
=None):
74 self
.trace_start_ts
= 0
80 progressbar
.progressbar_setup(self
)
81 if not self
._arg
_begin
:
83 for event
in self
._traces
.events
:
84 progressbar
.progressbar_update(self
)
85 if self
._arg
_begin
and started
== 0 and \
86 event
.timestamp
>= self
._arg
_begin
:
88 self
.trace_start_ts
= event
.timestamp
89 self
.start_ns
= event
.timestamp
90 reset_cb(event
.timestamp
)
91 if self
._arg
_end
and event
.timestamp
> self
._arg
_end
:
92 if break_cb
is not None:
93 # check if we really can break here
98 if self
.start_ns
== 0:
99 self
.start_ns
= event
.timestamp
100 if self
.trace_start_ts
== 0:
101 self
.trace_start_ts
= event
.timestamp
102 self
.end_ns
= event
.timestamp
103 self
._check
_refresh
(event
, refresh_cb
)
104 self
.trace_end_ts
= event
.timestamp
106 self
._analysis
.process_event(event
)
108 self
._automaton
.process_event(event
)
109 progressbar
.progressbar_finish(self
)
111 def _check_refresh(self
, event
, refresh_cb
):
112 """Check if we need to output something"""
113 if self
._arg
_refresh
== 0:
115 event_sec
= event
.timestamp
/ common
.NSEC_PER_SEC
116 if self
.current_sec
== 0:
117 self
.current_sec
= event_sec
118 elif self
.current_sec
!= event_sec
and \
119 (self
.current_sec
+ self
._arg
_refresh
) <= event_sec
:
120 refresh_cb(self
.start_ns
, event
.timestamp
)
121 self
.current_sec
= event_sec
122 self
.start_ns
= event
.timestamp
124 def _validate_transform_common_args(self
, args
):
125 self
._arg
_path
= args
.path
127 self
._arg
_limit
= args
.limit
128 self
._arg
_begin
= None
130 self
._arg
_begin
= args
.begin
133 self
._arg
_end
= args
.end
134 self
._arg
_timerange
= None
136 self
._arg
_timerange
= args
.timerange
139 self
._arg
_gmt
= args
.gmt
140 self
._arg
_refresh
= args
.refresh
141 self
._arg
_no
_progress
= args
.no_progress
143 if self
._enable
_proc
_filter
_args
:
144 self
._arg
_proc
_list
= None
146 self
._arg
_proc
_list
= args
.procname
.split(",")
147 self
._arg
_pid
_list
= None
149 self
._arg
_pid
_list
= args
.pid
.split(",")
151 if self
._enable
_max
_min
_arg
:
155 self
._arg
_max
= args
.max
159 self
._arg
_min
= args
.min
161 if self
._enable
_max
_min
_size
_arg
:
162 if args
.maxsize
== -1:
163 self
._arg
_maxsize
= None
165 self
._arg
_maxsize
= args
.maxsize
166 if args
.minsize
== -1:
167 self
._arg
_minsize
= None
169 self
._arg
_minsize
= args
.minsize
171 if self
._enable
_freq
_arg
:
172 self
._arg
_freq
= args
.freq
173 self
._arg
_freq
_resolution
= args
.freq_resolution
175 if self
._enable
_log
_arg
:
176 self
._arg
_log
= args
.log
178 if self
._enable
_stats
_arg
:
179 self
._arg
_stats
= args
.stats
181 def _parse_args(self
):
182 ap
= argparse
.ArgumentParser(description
=self
._DESC
)
185 ap
.add_argument('path', metavar
="<path/to/trace>", help='trace path')
186 ap
.add_argument('-r', '--refresh', type=int,
187 help='Refresh period in seconds', default
=0)
188 ap
.add_argument('--limit', type=int, default
=10,
189 help='Limit to top X (default = 10)')
190 ap
.add_argument('--no-progress', action
="store_true",
191 help='Don\'t display the progress bar')
192 ap
.add_argument('--gmt', action
="store_true",
193 help='Manipulate timestamps based on GMT instead '
195 ap
.add_argument('--begin', type=str, help='start time: '
196 'hh:mm:ss[.nnnnnnnnn]')
197 ap
.add_argument('--end', type=str, help='end time: '
198 'hh:mm:ss[.nnnnnnnnn]')
199 ap
.add_argument('--timerange', type=str, help='time range: '
202 if self
._enable
_proc
_filter
_args
:
203 ap
.add_argument('--procname', type=str, default
=0,
204 help='Filter the results only for this list of '
206 ap
.add_argument('--pid', type=str, default
=0,
207 help='Filter the results only for this list '
210 if self
._enable
_max
_min
_arg
:
211 ap
.add_argument('--max', type=float, default
=-1,
212 help='Filter out, duration longer than max usec')
213 ap
.add_argument('--min', type=float, default
=-1,
214 help='Filter out, duration shorter than min usec')
216 if self
._enable
_max
_min
_size
_arg
:
217 ap
.add_argument('--maxsize', type=float, default
=-1,
218 help='Filter out, I/O operations working with '
219 'more that maxsize bytes')
220 ap
.add_argument('--minsize', type=float, default
=-1,
221 help='Filter out, I/O operations working with '
222 'less that minsize bytes')
224 if self
._enable
_freq
_arg
:
225 ap
.add_argument('--freq', action
="store_true",
226 help='Show the frequency distribution of '
228 ap
.add_argument('--freq-resolution', type=int, default
=20,
229 help='Frequency distribution resolution '
232 if self
._enable
_log
_arg
:
233 ap
.add_argument('--log', action
="store_true",
234 help='Display the events in the order they '
237 if self
._enable
_stats
_arg
:
238 ap
.add_argument('--stats', action
="store_true",
239 help='Display the statistics')
242 self
._add
_arguments
_cb
(ap
)
244 # version of the specific command
245 ap
.add_argument('-V', '--version', action
='version',
246 version
=self
._VERSION
)
249 args
= ap
.parse_args()
251 self
._validate
_transform
_common
_args
(args
)
256 def _create_automaton(self
):
257 self
._automaton
= linuxautomaton
.automaton
.Automaton()
This page took 0.039621 seconds and 5 git commands to generate.