mirror of https://github.com/xemu-project/xemu.git
scripts/kvm/kvm_stat: Make tui function a class
The tui function itself had a few sub-functions and therefore basically already was class-like. Making it an actual one with proper methods improved readability. The curses wrapper was dropped in favour of __entry/exit__ methods that implement the same behaviour. Also renamed single character variable name, so the name reflects the content. Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com> Message-Id: <1452525484-32309-28-git-send-email-frankja@linux.vnet.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9c0ab054ed
commit
8a2a33316c
|
@ -539,58 +539,92 @@ class Stats(object):
|
||||||
LABEL_WIDTH = 40
|
LABEL_WIDTH = 40
|
||||||
NUMBER_WIDTH = 10
|
NUMBER_WIDTH = 10
|
||||||
|
|
||||||
def tui(screen, stats):
|
class Tui(object):
|
||||||
curses.use_default_colors()
|
def __init__(self, stats):
|
||||||
|
self.stats = stats
|
||||||
|
self.screen = None
|
||||||
|
self.drilldown = False
|
||||||
|
self.fields_filter = self.stats.fields_filter
|
||||||
|
self.update_drilldown()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
"""Initialises curses for later use. Based on curses.wrapper
|
||||||
|
implementation from the Python standard library."""
|
||||||
|
self.screen = curses.initscr()
|
||||||
curses.noecho()
|
curses.noecho()
|
||||||
drilldown = False
|
curses.cbreak()
|
||||||
fields_filter = stats.fields_filter
|
|
||||||
def update_drilldown():
|
# The try/catch works around a minor bit of
|
||||||
if not fields_filter:
|
# over-conscientiousness in the curses module, the error
|
||||||
if drilldown:
|
# return from C start_color() is ignorable.
|
||||||
stats.fields_filter = None
|
try:
|
||||||
|
curses.start_color()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
curses.use_default_colors()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *exception):
|
||||||
|
"""Resets the terminal to its normal state. Based on curses.wrappre
|
||||||
|
implementation from the Python standard library."""
|
||||||
|
if self.screen:
|
||||||
|
self.screen.keypad(0)
|
||||||
|
curses.echo()
|
||||||
|
curses.nocbreak()
|
||||||
|
curses.endwin()
|
||||||
|
|
||||||
|
def update_drilldown(self):
|
||||||
|
if not self.fields_filter:
|
||||||
|
if self.drilldown:
|
||||||
|
self.stats.fields_filter = None
|
||||||
else:
|
else:
|
||||||
stats.fields_filter = r'^[^\(]*$'
|
self.stats.fields_filter = r'^[^\(]*$'
|
||||||
update_drilldown()
|
|
||||||
def refresh(sleeptime):
|
def refresh(self, sleeptime):
|
||||||
screen.erase()
|
self.screen.erase()
|
||||||
screen.addstr(0, 0, 'kvm statistics')
|
self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
|
||||||
screen.addstr(2, 1, 'Event')
|
self.screen.addstr(2, 1, 'Event')
|
||||||
screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH - len('Total'), 'Total')
|
self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH -
|
||||||
screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 - len('Current'), 'Current')
|
len('Total'), 'Total')
|
||||||
|
self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
|
||||||
|
len('Current'), 'Current')
|
||||||
row = 3
|
row = 3
|
||||||
s = stats.get()
|
stats = self.stats.get()
|
||||||
def sortkey(x):
|
def sortkey(x):
|
||||||
if s[x][1]:
|
if stats[x][1]:
|
||||||
return (-s[x][1], -s[x][0])
|
return (-stats[x][1], -stats[x][0])
|
||||||
else:
|
else:
|
||||||
return (0, -s[x][0])
|
return (0, -stats[x][0])
|
||||||
for key in sorted(s.keys(), key=sortkey):
|
for key in sorted(stats.keys(), key=sortkey):
|
||||||
if row >= screen.getmaxyx()[0]:
|
|
||||||
|
if row >= self.screen.getmaxyx()[0]:
|
||||||
break
|
break
|
||||||
values = s[key]
|
values = stats[key]
|
||||||
if not values[0] and not values[1]:
|
if not values[0] and not values[1]:
|
||||||
break
|
break
|
||||||
col = 1
|
col = 1
|
||||||
screen.addstr(row, col, key)
|
self.screen.addstr(row, col, key)
|
||||||
col += LABEL_WIDTH
|
col += LABEL_WIDTH
|
||||||
screen.addstr(row, col, '%10d' % (values[0],))
|
self.screen.addstr(row, col, '%10d' % (values[0],))
|
||||||
col += NUMBER_WIDTH
|
col += NUMBER_WIDTH
|
||||||
if values[1] is not None:
|
if values[1] is not None:
|
||||||
screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
|
self.screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
|
||||||
row += 1
|
row += 1
|
||||||
screen.refresh()
|
self.screen.refresh()
|
||||||
|
|
||||||
|
def show_stats(self):
|
||||||
sleeptime = 0.25
|
sleeptime = 0.25
|
||||||
while True:
|
while True:
|
||||||
refresh(sleeptime)
|
self.refresh(sleeptime)
|
||||||
curses.halfdelay(int(sleeptime * 10))
|
curses.halfdelay(int(sleeptime * 10))
|
||||||
sleeptime = 3
|
sleeptime = 3
|
||||||
try:
|
try:
|
||||||
c = screen.getkey()
|
char = self.screen.getkey()
|
||||||
if c == 'x':
|
if char == 'x':
|
||||||
drilldown = not drilldown
|
self.drilldown = not self.drilldown
|
||||||
update_drilldown()
|
self.update_drilldown()
|
||||||
if c == 'q':
|
if char == 'q':
|
||||||
break
|
break
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
break
|
break
|
||||||
|
@ -698,7 +732,8 @@ def main():
|
||||||
if options.log:
|
if options.log:
|
||||||
log(stats)
|
log(stats)
|
||||||
elif not options.once:
|
elif not options.once:
|
||||||
curses.wrapper(tui, stats)
|
with Tui(stats) as tui:
|
||||||
|
tui.show_stats()
|
||||||
else:
|
else:
|
||||||
batch(stats)
|
batch(stats)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue