On Tue, Aug 9, 2011 at 2:17 PM, Gregory Smith <[email protected]> wrote: > Compress /var/log/messages during client test sysinfo collection. > Compress all log messages saved by the autoserv logfile_monitor system > before writing them to disk. > > Both of these help alleviate the problem of an insane amount of disk space > being used by copies of kernel logs that occur during some stress tests that > are intentionally triggering verbose error logs from the kernel. > > Side effect: there will be multiple logfile_monitor.log.nnnn-nnn.gz files > instead of a single logfile_monitor.log file as the logfile monitor is stopped > and started a few times during some autoserv runs.
I went through this, looks good to me, thanks! http://autotest.kernel.org/changeset/5527 > Signed-off-by: Gregory Smith <[email protected]> > > --- autotest/client/bin/base_sysinfo.py 2011-01-06 14:57:07.000000000 -0800 > +++ autotest/client/bin/base_sysinfo.py 2011-07-18 16:27:20.000000000 -0700 > @@ -1,4 +1,4 @@ > -import os, shutil, re, glob, subprocess, logging > +import os, shutil, re, glob, subprocess, logging, gzip > > from autotest_lib.client.common_lib import log > from autotest_lib.client.bin import utils, package > @@ -324,11 +324,19 @@ > if current_inode == self._messages_inode: > bytes_to_skip = self._messages_size > in_messages = open("/var/log/messages") > - in_messages.seek(bytes_to_skip) > - out_messages = open(os.path.join(logdir, "messages"), "w") > - out_messages.write(in_messages.read()) > - in_messages.close() > - out_messages.close() > + out_file_name = os.path.join(logdir, "messages.gz") > + out_messages = gzip.GzipFile(out_file_name, "w") > + try: > + in_messages.seek(bytes_to_skip) > + while True: > + # Read data in managable chunks rather than all at once. > + in_data = in_messages.read(200000) > + if not in_data: > + break > + out_messages.write(in_data) > + finally: > + out_messages.close() > + in_messages.close() > except Exception, e: > logging.error("/var/log/messages collection failed with %s", e) > > --- autotest/server/crashcollect.py 2011-02-03 22:24:17.000000000 -0800 > +++ autotest/server/crashcollect.py 2011-07-18 16:27:20.000000000 -0700 > @@ -1,4 +1,4 @@ > -import os, time, pickle, logging, shutil > +import os, time, pickle, logging, shutil, gzip > > from autotest_lib.server import utils > > @@ -175,11 +175,13 @@ > else: > size_at_start = 0 > raw_messages_file = open(messages_raw) > - messages_file = open(messages, "w") > - raw_messages_file.seek(size_at_start) > - shutil.copyfileobj(raw_messages_file, messages_file) > - raw_messages_file.close() > - messages_file.close() > + messages_file = gzip.GzipFile(messages+".gz", "w") > + try: > + raw_messages_file.seek(size_at_start) > + shutil.copyfileobj(raw_messages_file, messages_file) > + raw_messages_file.close() > + finally: > + messages_file.close() > > # get rid of the "raw" versions of messages > os.remove(messages_raw) > --- autotest/server/hosts/logfile_monitor.py 2010-03-12 14:43:13.000000000 > -0800 > +++ autotest/server/hosts/logfile_monitor.py 2011-07-18 16:27:20.000000000 > -0700 > @@ -133,7 +133,6 @@ > # Setup warning stream before we actually launch > warning_stream = os.fdopen(r, 'r', 0) > > - devnull_r = open(os.devnull, 'r') > devnull_w = open(os.devnull, 'w') > # Launch console.py locally > console_proc = subprocess.Popen( > --- autotest/server/hosts/monitors/console.py 2009-11-19 11:23:31.000000000 > -0800 > +++ autotest/server/hosts/monitors/console.py 2011-07-18 16:27:20.000000000 > -0700 > @@ -3,8 +3,9 @@ > # Script for translating console output (from STDIN) into Autotest > # warning messages. > > -import optparse, os, sys > -import monitors_util > +import gzip, optparse, os, signal, sys, time > +import common > +from autotest_lib.server.hosts.monitors import monitors_util > > PATTERNS_PATH = os.path.join(os.path.dirname(__file__), 'console_patterns') > > @@ -20,13 +21,53 @@ > help='Path to alert hook patterns file') > > > +def _open_logfile(logfile_base_name): > + """Opens an output file using the given name. > + > + A timestamp and compression is added to the name. > + > + @param logfile_base_name - The log file path without a compression > suffix. > + @returns An open file like object. Its close method must be called > before > + exiting or data may be lost due to internal buffering. > + """ > + timestamp = int(time.time()) > + while True: > + logfile_name = '%s.%d-%d.gz' % (logfile_base_name, > + timestamp, os.getpid()) > + if not os.path.exists(logfile_name): > + break > + timestamp += 1 > + logfile = gzip.GzipFile(logfile_name, 'w') > + return logfile > + > + > +def _set_logfile_close_signal_handler(logfile): > + """Setup a signal handler to explicitly call logfile.close() and exit. > + > + Because we are writing a compressed file we need to make sure we properly > + close to flush our internal buffer on exit. logfile_monitor.py sends us > + a SIGTERM and waits 5 seconds for before sending a SIGKILL so we have > + plenty of time to do this. > + > + @param logfile - An open file object to be closed on SIGTERM. > + """ > + def _on_signal_close_logfile_before_exit(unused_signal_no, unused_frame): > + logfile.close() > + os.exit(1) > + signal.signal(signal.SIGTERM, _on_signal_close_logfile_before_exit) > + > + > +def _unset_signal_handler(): > + signal.signal(signal.SIGTERM, signal.SIG_DFL) > + > + > def main(): > (options, args) = parser.parse_args() > if len(args) != 2: > parser.print_help() > sys.exit(1) > > - logfile = open(args[0], 'a', 0) > + logfile = _open_logfile(args[0]) > warnfile = os.fdopen(int(args[1]), 'w', 0) > # For now we aggregate all the alert_hooks. > alert_hooks = [] > @@ -34,8 +75,13 @@ > alert_hooks.extend(monitors_util.build_alert_hooks_from_path( > patterns_path, warnfile)) > > - monitors_util.process_input( > - sys.stdin, logfile, options.log_timestamp_format, alert_hooks) > + _set_logfile_close_signal_handler(logfile) > + try: > + monitors_util.process_input( > + sys.stdin, logfile, options.log_timestamp_format, alert_hooks) > + finally: > + logfile.close() > + _unset_signal_handler() > > > if __name__ == '__main__': > ==== (added) > //depot/google_vendor_src_branch/autotest/server/hosts/monitors/console_unittest.py#1 > ==== > --- /dev/null 2011-05-19 20:30:53.561792601 -0700 > +++ autotest/server/hosts/monitors/console_unittest.py 2011-07-18 > 16:27:20.000000000 -0700 > @@ -0,0 +1,56 @@ > +#!/usr/bin/python > + > +"""Tests for console.py""" > + > +import os, shutil, signal, StringIO, tempfile > + > +import common > +from autotest_lib.client.common_lib.test_utils import mock > +from autotest_lib.client.common_lib.test_utils import unittest > +from autotest_lib.server.hosts.monitors import console > + > +class console_test(unittest.TestCase): > + def setUp(self): > + self.god = mock.mock_god() > + self.tempdir = tempfile.mkdtemp() > + > + > + def tearDown(self): > + shutil.rmtree(self.tempdir) > + > + > + def test_open_logfile(self): > + path = os.path.join(self.tempdir, 'its-log-log') > + fun_log = console._open_logfile(path) > + fun_log.write("it's big it's heavy it's wood.\n") > + fun_log.close() > + > + # Open it again to ensure the original gets renamed. > + fun_log = console._open_logfile(path) > + fun_log.write("it's better than bad, it's good!\n") > + fun_log.close() > + > + log_file_list = os.listdir(self.tempdir) > + self.assertEqual(2, len(log_file_list)) > + for name in log_file_list: > + self.assertTrue(name.startswith('its-log-log.'), > + 'unexpected name %s' % name) > + self.assertTrue(name.endswith('.gz'), 'unexpected name %s' % > name) > + > + > + def test_logfile_close_signal_handler(self): > + self.god.stub_function(os, 'exit') > + os.exit.expect_call(1) > + logfile = StringIO.StringIO() > + console._set_logfile_close_signal_handler(logfile) > + try: > + self.assertFalse(logfile.closed) > + os.kill(os.getpid(), signal.SIGTERM) > + finally: > + console._unset_signal_handler() > + self.god.check_playback() > + self.assertTrue(logfile.closed) > + > + > +if __name__ == '__main__': > + unittest.main() > _______________________________________________ > Autotest mailing list > [email protected] > http://test.kernel.org/cgi-bin/mailman/listinfo/autotest > -- Lucas _______________________________________________ Autotest mailing list [email protected] http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
