Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools/kvm_stat: add command line switch '-c' to log in csv format

Add an alternative format that can be more easily used for further
processing later on.
Note that we add a timestamp in the first column for both, the regular
and the new csv format.

Signed-off-by: Stefan Raspl <raspl@linux.ibm.com>
Message-Id: <20200306114250.57585-5-raspl@linux.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Stefan Raspl and committed by
Paolo Bonzini
0c794dce 3cbb394d

+55 -16
+51 -16
tools/kvm/kvm_stat/kvm_stat
··· 33 33 import re 34 34 import subprocess 35 35 from collections import defaultdict, namedtuple 36 + from functools import reduce 37 + from datetime import datetime 36 38 37 39 VMX_EXIT_REASONS = { 38 40 'EXCEPTION_NMI': 0, ··· 1491 1489 pass 1492 1490 1493 1491 1494 - def log(stats, opts): 1492 + class StdFormat(object): 1493 + def __init__(self, keys): 1494 + self._banner = '' 1495 + for key in keys: 1496 + self._banner += key.split(' ')[0] + ' ' 1497 + 1498 + def get_banner(self): 1499 + return self._banner 1500 + 1501 + @staticmethod 1502 + def get_statline(keys, s): 1503 + res = '' 1504 + for key in keys: 1505 + res += ' %9d' % s[key].delta 1506 + return res 1507 + 1508 + 1509 + class CSVFormat(object): 1510 + def __init__(self, keys): 1511 + self._banner = 'timestamp' 1512 + self._banner += reduce(lambda res, key: "{},{!s}".format(res, 1513 + key.split(' ')[0]), keys, '') 1514 + 1515 + def get_banner(self): 1516 + return self._banner 1517 + 1518 + @staticmethod 1519 + def get_statline(keys, s): 1520 + return reduce(lambda res, key: "{},{!s}".format(res, s[key].delta), 1521 + keys, '') 1522 + 1523 + 1524 + def log(stats, opts, frmt, keys): 1495 1525 """Prints statistics as reiterating key block, multiple value blocks.""" 1496 - keys = sorted(stats.get().keys()) 1497 - 1498 - def banner(): 1499 - for key in keys: 1500 - print(key.split(' ')[0], end=' ') 1501 - print() 1502 - 1503 - def statline(): 1504 - s = stats.get() 1505 - for key in keys: 1506 - print(' %9d' % s[key].delta, end=' ') 1507 - print() 1508 1526 line = 0 1509 1527 banner_repeat = 20 1510 1528 while True: 1511 1529 try: 1512 1530 time.sleep(opts.set_delay) 1513 1531 if line % banner_repeat == 0: 1514 - banner() 1515 - statline() 1532 + print(frmt.get_banner()) 1533 + print(datetime.now().strftime("%Y-%m-%d %H:%M:%S") + 1534 + frmt.get_statline(keys, stats.get())) 1516 1535 line += 1 1517 1536 except KeyboardInterrupt: 1518 1537 break ··· 1607 1584 default=False, 1608 1585 help='run in batch mode for one second', 1609 1586 ) 1587 + argparser.add_argument('-c', '--csv', 1588 + action='store_true', 1589 + default=False, 1590 + help='log in csv format - requires option -l/--log', 1591 + ) 1610 1592 argparser.add_argument('-d', '--debugfs', 1611 1593 action='store_true', 1612 1594 default=False, ··· 1656 1628 help='retrieve statistics from tracepoints', 1657 1629 ) 1658 1630 options = argparser.parse_args() 1631 + if options.csv and not options.log: 1632 + sys.exit('Error: Option -c/--csv requires -l/--log') 1659 1633 try: 1660 1634 # verify that we were passed a valid regex up front 1661 1635 re.compile(options.fields) ··· 1738 1708 sys.exit(0) 1739 1709 1740 1710 if options.log: 1741 - log(stats, options) 1711 + keys = sorted(stats.get().keys()) 1712 + if options.csv: 1713 + frmt = CSVFormat(keys) 1714 + else: 1715 + frmt = StdFormat(keys) 1716 + log(stats, options, frmt, keys) 1742 1717 elif not options.once: 1743 1718 with Tui(stats, options) as tui: 1744 1719 tui.show_stats()
+4
tools/kvm/kvm_stat/kvm_stat.txt
··· 64 64 --batch:: 65 65 run in batch mode for one second 66 66 67 + -c:: 68 + --csv=<file>:: 69 + log in csv format - requires option -l/--log 70 + 67 71 -d:: 68 72 --debugfs:: 69 73 retrieve statistics from debugfs