summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Raspl <stefan.raspl@de.ibm.com>2018-02-22 06:16:29 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2018-02-23 19:43:45 -0500
commitdf72ecfc790fa01de1c41f836ff51d12f9c40318 (patch)
tree4b0dfa3f80d4eb3c6730e52136015304b4b6cc38
parent18e8f4100ef14f924514fbd91eb67bd5fa5396b7 (diff)
tools/kvm_stat: group child events indented after parent
We keep the current logic that sorts all events (parent and child), but re-shuffle the events afterwards, grouping the children after the respective parent. Note that the percentage column for child events gives the percentage of the parent's total. Since we rework the logic anyway, we modify the total average calculation to use the raw numbers instead of the (rounded) averages. Note that this can result in differing numbers (between total average and the sum of the individual averages) due to rounding errors. Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rwxr-xr-xtools/kvm/kvm_stat/kvm_stat89
1 files changed, 59 insertions, 30 deletions
diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat
index 6b6630ee6daf..862c997932e2 100755
--- a/tools/kvm/kvm_stat/kvm_stat
+++ b/tools/kvm/kvm_stat/kvm_stat
@@ -1124,6 +1124,45 @@ class Tui(object):
1124 def is_child_field(field): 1124 def is_child_field(field):
1125 return field.find('(') != -1 1125 return field.find('(') != -1
1126 1126
1127 def insert_child(sorted_items, child, values, parent):
1128 num = len(sorted_items)
1129 for i in range(0, num):
1130 # only add child if parent is present
1131 if parent.startswith(sorted_items[i][0]):
1132 sorted_items.insert(i + 1, (' ' + child, values))
1133
1134 def get_sorted_events(self, stats):
1135 """ separate parent and child events """
1136 if self._sorting == SORT_DEFAULT:
1137 def sortkey((_k, v)):
1138 # sort by (delta value, overall value)
1139 return (v.delta, v.value)
1140 else:
1141 def sortkey((_k, v)):
1142 # sort by overall value
1143 return v.value
1144
1145 childs = []
1146 sorted_items = []
1147 # we can't rule out child events to appear prior to parents even
1148 # when sorted - separate out all children first, and add in later
1149 for key, values in sorted(stats.items(), key=sortkey,
1150 reverse=True):
1151 if values == (0, 0):
1152 continue
1153 if key.find(' ') != -1:
1154 if not self.stats.child_events:
1155 continue
1156 childs.insert(0, (key, values))
1157 else:
1158 sorted_items.append((key, values))
1159 if self.stats.child_events:
1160 for key, values in childs:
1161 (child, parent) = key.split(' ')
1162 insert_child(sorted_items, child, values, parent)
1163
1164 return sorted_items
1165
1127 row = 3 1166 row = 3
1128 self.screen.move(row, 0) 1167 self.screen.move(row, 0)
1129 self.screen.clrtobot() 1168 self.screen.clrtobot()
@@ -1143,44 +1182,34 @@ class Tui(object):
1143 # we don't have any fields, or all non-child events are filtered 1182 # we don't have any fields, or all non-child events are filtered
1144 total = ctotal 1183 total = ctotal
1145 1184
1146 if self._sorting == SORT_DEFAULT:
1147 def sortkey((_k, v)):
1148 # sort by (delta value, overall value)
1149 return (v.delta, v.value)
1150 else:
1151 def sortkey((_k, v)):
1152 # sort by overall value
1153 return v.value
1154
1155 sorted_items = sorted(stats.items(), key=sortkey, reverse=True)
1156
1157 # print events 1185 # print events
1158 tavg = 0 1186 tavg = 0
1159 for key, values in sorted_items: 1187 tcur = 0
1160 if row >= self.screen.getmaxyx()[0] - 1: 1188 for key, values in get_sorted_events(self, stats):
1189 if row >= self.screen.getmaxyx()[0] - 1 or values == (0, 0):
1161 break 1190 break
1162 if values == (0, 0): 1191 if self._display_guests:
1163 continue 1192 key = self.get_gname_from_pid(key)
1164 if not self.stats.child_events and key.find(' ') != -1: 1193 if not key:
1165 continue 1194 continue
1166 if values.value is not None: 1195 cur = int(round(values.delta / sleeptime)) if values.delta else ''
1167 cur = int(round(values.delta / sleeptime)) if values.delta else '' 1196 if key[0] != ' ':
1168 if self._display_guests: 1197 if values.delta:
1169 key = self.get_gname_from_pid(key) 1198 tcur += values.delta
1170 if not key: 1199 ptotal = values.value
1171 continue 1200 ltotal = total
1172 self.screen.addstr(row, 1, '%-40s %10d%7.1f %8s' % (key 1201 else:
1173 .split(' ')[0], values.value, 1202 ltotal = ptotal
1174 values.value * 100 / total, cur)) 1203 self.screen.addstr(row, 1, '%-40s %10d%7.1f %8s' % (key,
1175 if cur != '' and key.find('(') == -1: 1204 values.value,
1176 tavg += cur 1205 values.value * 100 / float(ltotal), cur))
1177 row += 1 1206 row += 1
1178 if row == 3: 1207 if row == 3:
1179 self.screen.addstr(4, 1, 'No matching events reported yet') 1208 self.screen.addstr(4, 1, 'No matching events reported yet')
1180 else: 1209 else:
1210 tavg = int(round(tcur / sleeptime)) if tcur > 0 else ''
1181 self.screen.addstr(row, 1, '%-40s %10d %8s' % 1211 self.screen.addstr(row, 1, '%-40s %10d %8s' %
1182 ('Total', total, tavg if tavg else ''), 1212 ('Total', total, tavg), curses.A_BOLD)
1183 curses.A_BOLD)
1184 self.screen.refresh() 1213 self.screen.refresh()
1185 1214
1186 def _show_msg(self, text): 1215 def _show_msg(self, text):