a272b6ea0b2b124b623b0726ee854634a2fdf601
1 # The MIT License (MIT)
3 # Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com>
4 # 2015 - Antoine Busque <abusque@efficios.com>
5 # 2015 - Philippe Proulx <pproulx@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
26 from .command
import Command
27 from ..core
import cputop
29 from . import termgraph
32 class Cputop(Command
):
33 _DESC
= """The cputop command."""
34 _ANALYSIS_CLASS
= cputop
.Cputop
35 _MI_TITLE
= 'Top CPU usage'
36 _MI_DESCRIPTION
= 'Per-TID, per-CPU, and total top CPU usage'
37 _MI_TAGS
= [mi
.Tags
.CPU
, mi
.Tags
.TOP
]
38 _MI_TABLE_CLASS_PER_PROC
= 'per-process'
39 _MI_TABLE_CLASS_PER_CPU
= 'per-cpu'
40 _MI_TABLE_CLASS_TOTAL
= 'total'
41 _MI_TABLE_CLASS_SUMMARY
= 'summary'
44 _MI_TABLE_CLASS_PER_PROC
,
45 'Per-TID top CPU usage', [
46 ('process', 'Process', mi
.Process
),
47 ('migrations', 'Migration count', mi
.Integer
, 'migrations'),
48 ('prio_list', 'Chronological priorities', mi
.String
),
49 ('usage', 'CPU usage', mi
.Ratio
),
53 _MI_TABLE_CLASS_PER_CPU
,
54 'Per-CPU top CPU usage', [
55 ('cpu', 'CPU', mi
.Cpu
),
56 ('usage', 'CPU usage', mi
.Ratio
),
59 _MI_TABLE_CLASS_TOTAL
,
61 ('usage', 'CPU usage', mi
.Ratio
),
65 _MI_TABLE_CLASS_SUMMARY
,
66 'CPU usage - summary', [
67 ('time_range', 'Time range', mi
.TimeRange
),
68 ('usage', 'Total CPU usage', mi
.Ratio
),
73 def _analysis_tick(self
, begin_ns
, end_ns
):
74 per_tid_table
= self
._get
_per
_tid
_usage
_result
_table
(begin_ns
, end_ns
)
75 per_cpu_table
= self
._get
_per
_cpu
_usage
_result
_table
(begin_ns
, end_ns
)
76 total_table
= self
._get
_total
_usage
_result
_table
(begin_ns
, end_ns
)
79 self
._mi
_append
_result
_table
(per_tid_table
)
80 self
._mi
_append
_result
_table
(per_cpu_table
)
81 self
._mi
_append
_result
_table
(total_table
)
83 self
._print
_date
(begin_ns
, end_ns
)
84 self
._print
_per
_tid
_usage
(per_tid_table
)
85 self
._print
_per
_cpu
_usage
(per_cpu_table
)
88 self
._print
_total
_cpu
_usage
(total_table
)
90 def _create_summary_result_tables(self
):
91 total_tables
= self
._mi
_get
_result
_tables
(self
._MI
_TABLE
_CLASS
_TOTAL
)
92 begin
= total_tables
[0].timerange
.begin
93 end
= total_tables
[-1].timerange
.end
95 self
._mi
_create
_result
_table
(self
._MI
_TABLE
_CLASS
_SUMMARY
,
98 for total_table
in total_tables
:
99 usage
= total_table
.rows
[0].usage
100 summary_table
.append_row(
101 time_range
=total_table
.timerange
,
105 self
._mi
_clear
_result
_tables
()
106 self
._mi
_append
_result
_table
(summary_table
)
108 def _cleanup_prio_list(self
, prio_list
):
116 for p
in sorted(prios
.keys()):
118 count_str
= " (%s times)" % prios
[p
]
122 prio_str
= "[%s%s" % (p
, count_str
)
124 prio_str
= "%s, %s%s" % (prio_str
, p
, count_str
)
125 prio_str
= prio_str
+ "]"
128 def _get_per_tid_usage_result_table(self
, begin_ns
, end_ns
):
130 self
._mi
_create
_result
_table
(self
._MI
_TABLE
_CLASS
_PER
_PROC
,
134 for tid
in sorted(self
._analysis
.tids
.values(),
135 key
=operator
.attrgetter('usage_percent'),
137 prio_list
= self
._cleanup
_prio
_list
(tid
.prio_list
)
139 result_table
.append_row(
140 process
=mi
.Process(tid
.comm
, tid
=tid
.tid
),
141 migrations
=mi
.Integer(tid
.migrate_count
),
142 prio_list
=mi
.String(prio_list
),
143 usage
=mi
.Ratio
.from_percentage(tid
.usage_percent
)
147 if self
._args
.limit
> 0 and count
>= self
._args
.limit
:
152 def _get_per_cpu_usage_result_table(self
, begin_ns
, end_ns
):
154 self
._mi
_create
_result
_table
(self
._MI
_TABLE
_CLASS
_PER
_CPU
,
157 for cpu
in sorted(self
._analysis
.cpus
.values(),
158 key
=operator
.attrgetter('cpu_id')):
159 result_table
.append_row(
160 cpu
=mi
.Cpu(cpu
.cpu_id
),
161 usage
=mi
.Ratio
.from_percentage(cpu
.usage_percent
)
166 def _get_total_usage_result_table(self
, begin_ns
, end_ns
):
168 self
._mi
_create
_result
_table
(self
._MI
_TABLE
_CLASS
_TOTAL
,
171 cpu_count
= len(self
.state
.cpus
)
177 for cpu
in sorted(self
._analysis
.cpus
.values(),
178 key
=operator
.attrgetter('usage_percent'),
180 usage_percent
+= cpu
.usage_percent
183 usage_percent
/= cpu_count
184 result_table
.append_row(
185 usage
=mi
.Ratio
.from_percentage(usage_percent
),
190 def _print_per_tid_usage(self
, result_table
):
191 row_format
= '{:<25} {:>10} {}'
192 label_header
= row_format
.format('Process', 'Migrations', 'Priorities')
194 def format_label(row
):
195 return row_format
.format(
196 '%s (%d)' % (row
.process
.name
, row
.process
.tid
),
197 row
.migrations
.value
,
201 graph
= termgraph
.BarGraph(
202 title
='Per-TID Usage',
204 get_value
=lambda row
: row
.usage
.to_percentage(),
205 get_label
=format_label
,
206 label_header
=label_header
,
207 data
=result_table
.rows
212 def _print_per_cpu_usage(self
, result_table
):
213 graph
= termgraph
.BarGraph(
214 title
='Per-CPU Usage',
216 get_value
=lambda row
: row
.usage
.to_percentage(),
217 get_label
=lambda row
: 'CPU %d' % row
.cpu
.id,
218 data
=result_table
.rows
223 def _print_total_cpu_usage(self
, result_table
):
224 usage_percent
= result_table
.rows
[0].usage
.to_percentage()
225 print('\nTotal CPU Usage: %0.02f%%\n' % usage_percent
)
227 def _add_arguments(self
, ap
):
228 Command
._add
_proc
_filter
_args
(ap
)
229 Command
._add
_top
_args
(ap
)
233 cputopcmd
= Cputop(mi_mode
=mi_mode
)
This page took 0.035736 seconds and 4 git commands to generate.