From: Stefan Raspl <raspl@linux.ibm.com>
To: kvm@vger.kernel.org
Cc: pbonzini@redhat.com
Subject: [PATCH 2/3] tools/kvm_stat: Add command line switch '-L' to log to file
Date: Tue, 31 Mar 2020 22:00:41 +0200 [thread overview]
Message-ID: <20200331200042.2026-3-raspl@linux.ibm.com> (raw)
In-Reply-To: <20200331200042.2026-1-raspl@linux.ibm.com>
From: Stefan Raspl <raspl@de.ibm.com>
To integrate with logrotate, we have a signal handler that will re-open
the logfile.
Assuming we have a systemd unit file with
ExecStart=kvm_stat -dtc -s 10 -L /var/log/kvm_stat.csv
ExecReload=/bin/kill -HUP $MAINPID
and a logrotate config featuring
postrotate
/bin/systemctl restart kvm_stat.service
endscript
Then the overall flow will look like this:
(1) systemd starts kvm_stat, logging to A.
(2) At some point, logrotate runs, moving A to B.
kvm_stat continues to write to B at this point.
(3) After rotating, logrotate restarts the kvm_stat unit via systemctl.
(4) The kvm_stat unit sends a SIGHUP to kvm_stat, finally making it
switch over to writing to A again.
Note that in order to keep the structure of the cvs output in tact, we
make sure to, in contrast to the standard log format, only write the
header once at the beginning of a file. This implies that the header is
suppressed when appending to an existing file. Unlike the standard
format, where we append to an existing file by starting out with a
header.
Signed-off-by: Stefan Raspl <raspl@linux.ibm.com>
---
tools/kvm/kvm_stat/kvm_stat | 75 +++++++++++++++++++++++++++++----
tools/kvm/kvm_stat/kvm_stat.txt | 5 +++
2 files changed, 71 insertions(+), 9 deletions(-)
diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat
index 54000ac508f9..e4f67f0629ee 100755
--- a/tools/kvm/kvm_stat/kvm_stat
+++ b/tools/kvm/kvm_stat/kvm_stat
@@ -32,6 +32,7 @@ import resource
import struct
import re
import subprocess
+import signal
from collections import defaultdict, namedtuple
from functools import reduce
from datetime import datetime
@@ -228,6 +229,8 @@ IOCTL_NUMBERS = {
'RESET': 0x00002403,
}
+signal_received = False
+
ENCODING = locale.getpreferredencoding(False)
TRACE_FILTER = re.compile(r'^[^\(]*$')
@@ -1533,25 +1536,73 @@ class CSVFormat(object):
def log(stats, opts, frmt, keys):
"""Prints statistics as reiterating key block, multiple value blocks."""
+ global signal_received
line = 0
banner_repeat = 20
- banner_printed = False
+ f = None
+
+ def do_banner(opts):
+ nonlocal f
+ if opts.log_to_file:
+ if not f:
+ try:
+ f = open(opts.log_to_file, 'a')
+ except (IOError, OSError):
+ sys.exit("Error: Could not open file: %s" %
+ opts.log_to_file)
+ if isinstance(frmt, CSVFormat) and f.tell() != 0:
+ return
+ f.write(frmt.get_banner())
+ f.write('\n')
+ else:
+ print(frmt.get_banner())
+
+ def do_statline(opts):
+ statline = frmt.get_statline(keys, stats.get())
+ if len(statline) == 0:
+ return False
+ statline = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + statline
+ if opts.log_to_file:
+ f.write(statline)
+ f.write('\n')
+ else:
+ print(statline)
+ return True
+
+ do_banner(opts)
+ banner_printed = True
while True:
try:
time.sleep(opts.set_delay)
- if line % banner_repeat == 0 and not banner_printed:
- print(frmt.get_banner())
+ if signal_received:
+ banner_printed = True
+ line = 0
+ f.close()
+ do_banner(opts)
+ signal_received = False
+ if (line % banner_repeat == 0 and not banner_printed and
+ not (opts.log_to_file and isinstance(frmt, CSVFormat))):
+ do_banner(opts)
banner_printed = True
- statline = frmt.get_statline(keys, stats.get())
- if len(statline) == 0:
+ if not do_statline(opts):
continue
- print(datetime.now().strftime("%Y-%m-%d %H:%M:%S") + statline)
line += 1
banner_printed = False
except KeyboardInterrupt:
break
+ if opts.log_to_file:
+ f.close()
+
+
+def handle_signal(sig, frame):
+ global signal_received
+
+ signal_received = True
+
+ return
+
def is_delay_valid(delay):
"""Verify delay is in valid value range."""
@@ -1652,6 +1703,10 @@ Press any other key to refresh statistics immediately.
default=False,
help='run in logging mode (like vmstat)',
)
+ argparser.add_argument('-L', '--log-to-file',
+ type=str,
+ help="like '--log', but logging to a file"
+ )
argparser.add_argument('-p', '--pid',
type=int,
default=0,
@@ -1675,9 +1730,9 @@ Press any other key to refresh statistics immediately.
help='omit records with all zeros in logging mode',
)
options = argparser.parse_args()
- if options.csv and not options.log:
+ if options.csv and not (options.log or options.log_to_file):
sys.exit('Error: Option -c/--csv requires -l/--log')
- if options.skip_zero_records and not options.log:
+ if options.skip_zero_records and not (options.log or options.log_to_file):
sys.exit('Error: Option -z/--skip-zero-records requires -l/--log')
try:
# verify that we were passed a valid regex up front
@@ -1758,7 +1813,9 @@ def main():
sys.stdout.write(' ' + '\n '.join(sorted(set(event_list))) + '\n')
sys.exit(0)
- if options.log:
+ if options.log or options.log_to_file:
+ if options.log_to_file:
+ signal.signal(signal.SIGHUP, handle_signal)
keys = sorted(stats.get().keys())
if options.csv:
frmt = CSVFormat(keys, options.skip_zero_records)
diff --git a/tools/kvm/kvm_stat/kvm_stat.txt b/tools/kvm/kvm_stat/kvm_stat.txt
index 24296dccc00a..de7c4a2497f9 100644
--- a/tools/kvm/kvm_stat/kvm_stat.txt
+++ b/tools/kvm/kvm_stat/kvm_stat.txt
@@ -92,6 +92,11 @@ OPTIONS
--log::
run in logging mode (like vmstat)
+
+-L::
+--log-to-file::
+ like '--log', but logging to a file
+
-p<pid>::
--pid=<pid>::
limit statistics to one virtual machine (pid)
--
2.17.1
next prev parent reply other threads:[~2020-03-31 20:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-31 20:00 [PATCH 0/3] tools/kvm_stat: add logfile support Stefan Raspl
2020-03-31 20:00 ` [PATCH 1/3] tools/kvm_stat: add command line switch '-z' to skip zero records Stefan Raspl
2020-03-31 21:45 ` Paolo Bonzini
2020-04-01 8:19 ` Stefan Raspl
2020-04-01 13:23 ` Paolo Bonzini
2020-03-31 20:00 ` Stefan Raspl [this message]
2020-03-31 21:02 ` [PATCH 2/3] tools/kvm_stat: Add command line switch '-L' to log to file Paolo Bonzini
2020-04-01 12:59 ` Stefan Raspl
2020-04-01 13:24 ` Paolo Bonzini
2020-03-31 20:00 ` [PATCH 3/3] tools/kvm_stat: add sample systemd unit file Stefan Raspl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200331200042.2026-3-raspl@linux.ibm.com \
--to=raspl@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.