fix: stats with 0 requests
[deliverable/lttng-analyses.git] / lttnganalysescli / lttnganalysescli / cputop.py
CommitLineData
4ed24f86
JD
1#!/usr/bin/env python3
2#
3# The MIT License (MIT)
4#
a3fa57c0 5# Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com>
0403ad20 6# 2015 - Antoine Busque <abusque@efficios.com>
4ed24f86
JD
7#
8# Permission is hereby granted, free of charge, to any person obtaining a copy
9# of this software and associated documentation files (the "Software"), to deal
10# in the Software without restriction, including without limitation the rights
11# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12# copies of the Software, and to permit persons to whom the Software is
13# furnished to do so, subject to the following conditions:
14#
15# The above copyright notice and this permission notice shall be included in
16# all copies or substantial portions of the Software.
17#
18# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24# SOFTWARE.
25
418527ca
JD
26from .command import Command
27import lttnganalyses.cputop
418527ca
JD
28from ascii_graph import Pyasciigraph
29import operator
30
31
32class Cputop(Command):
418527ca
JD
33 _DESC = """The cputop command."""
34
35 def __init__(self):
47ba125c 36 super().__init__(self._add_arguments, enable_proc_filter_args=True)
418527ca
JD
37
38 def _validate_transform_args(self):
39 pass
40
41 def run(self):
42 # parse arguments first
43 self._parse_args()
44 # validate, transform and save specific arguments
45 self._validate_transform_args()
46 # open the trace
47 self._open_trace()
48 # create the appropriate analysis/analyses
49 self._create_analysis()
50 # run the analysis
51 self._run_analysis(self._reset_total, self._refresh)
52 # process the results
53 self._compute_stats()
54 # print results
da6d0842 55 self._print_results(self.start_ns, self.trace_end_ts)
418527ca
JD
56 # close the trace
57 self._close_trace()
58
59 def _create_analysis(self):
6e01ed18 60 self._analysis = lttnganalyses.cputop.Cputop(self.state)
418527ca
JD
61
62 def _compute_stats(self):
0403ad20 63 self._analysis.compute_stats(self.start_ns, self.end_ns)
418527ca
JD
64
65 def _reset_total(self, start_ts):
0403ad20 66 self._analysis.reset(start_ts)
418527ca
JD
67
68 def _refresh(self, begin, end):
69 self._compute_stats()
da6d0842 70 self._print_results(begin, end)
418527ca
JD
71 self._reset_total(end)
72
0403ad20
AB
73 def _filter_process(self, proc):
74 # Exclude swapper
75 if proc.tid == 0:
76 return False
77
78 if self._arg_proc_list and proc.comm not in self._arg_proc_list:
79 return False
80
81 return True
82
da6d0842 83 def _print_results(self, begin_ns, end_ns):
0403ad20
AB
84 self._print_date(begin_ns, end_ns)
85 self._print_per_tid_usage()
86 self._print_per_cpu_usage()
87 self._print_total_cpu_usage()
88
89 def _print_per_tid_usage(self):
418527ca
JD
90 count = 0
91 limit = self._arg_limit
418527ca
JD
92 graph = Pyasciigraph()
93 values = []
0403ad20
AB
94
95 for tid in sorted(self._analysis.tids.values(),
96 key=operator.attrgetter('usage_percent'),
97 reverse=True):
98 if not self._filter_process(tid):
9113301d 99 continue
0403ad20
AB
100
101 output_str = '%s (%d)' % (tid.comm, tid.tid)
418527ca 102 if tid.migrate_count > 0:
0403ad20
AB
103 output_str += ', %d migrations' % (tid.migrate_count)
104
105 values.append((output_str, tid.usage_percent))
106
107 count += 1
418527ca
JD
108 if limit > 0 and count >= limit:
109 break
0403ad20 110
73b71522 111 for line in graph.graph('Per-TID CPU Usage', values, unit=' %'):
418527ca
JD
112 print(line)
113
0403ad20
AB
114 def _print_per_cpu_usage(self):
115 graph = Pyasciigraph()
418527ca 116 values = []
0403ad20
AB
117
118 for cpu in sorted(self._analysis.cpus.values(),
119 key=operator.attrgetter('usage_percent'),
120 reverse=True):
121 values.append(('CPU %d' % cpu.cpu_id, cpu.usage_percent))
122
73b71522 123 for line in graph.graph('Per-CPU Usage', values, unit=' %'):
418527ca 124 print(line)
0403ad20
AB
125
126 def _print_total_cpu_usage(self):
127 cpu_count = len(self.state.cpus)
128 usage_percent = 0
129
130 for cpu in sorted(self._analysis.cpus.values(),
131 key=operator.attrgetter('usage_percent'),
132 reverse=True):
133 usage_percent += cpu.usage_percent
134
135 # average per CPU
136 usage_percent /= cpu_count
137 print('\nTotal CPU Usage: %0.02f%%\n' % usage_percent)
418527ca
JD
138
139 def _add_arguments(self, ap):
140 # specific argument
141 pass
142
143
144# entry point
145def run():
146 # create command
147 cputopcmd = Cputop()
148
149 # execute command
150 cputopcmd.run()
This page took 0.031027 seconds and 5 git commands to generate.