| Index: client/cros/cros_logging.py
|
| diff --git a/client/cros/cros_logging.py b/client/cros/cros_logging.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..cc1f636071f845d2772c130a6db49bcb30c4813b
|
| --- /dev/null
|
| +++ b/client/cros/cros_logging.py
|
| @@ -0,0 +1,136 @@
|
| +# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +import logging, os, re
|
| +import common
|
| +from constants import CLEANUP_LOGS_PAUSED_FILE
|
| +from autotest_lib.client.bin import utils
|
| +from autotest_lib.client.common_lib import error
|
| +
|
| +class LogReader(object):
|
| + """
|
| + A class to read system log files.
|
| + """
|
| +
|
| + def __init__(self, filename='/var/log/messages'):
|
| + self._start_line = 1
|
| + self._filename = filename
|
| + if not os.path.exists(CLEANUP_LOGS_PAUSED_FILE):
|
| + raise error.TestError('LogReader created without ' +
|
| + CLEANUP_LOGS_PAUSED_FILE)
|
| +
|
| +
|
| + def set_start_by_regexp(self, index, regexp):
|
| + """Set the start of logs based on a regular expression.
|
| +
|
| + @param index: line matching regexp to start at, earliest log at 0.
|
| + Negative numbers indicate matches since end of log.
|
| + """
|
| + regexp_compiled = re.compile(regexp)
|
| + file_handle = open(self._filename, 'r')
|
| + starts = []
|
| + line_number = 1
|
| + for line in file_handle:
|
| + if regexp_compiled.match(line):
|
| + starts.append(line_number)
|
| + line_number += 1
|
| + if index < -len(starts):
|
| + self._start_line = 1
|
| + elif index >= len(starts):
|
| + self.set_start_by_current()
|
| + else:
|
| + self._start_line = starts[index]
|
| +
|
| +
|
| + def set_start_by_reboot(self, index):
|
| + """ Set the start of logs (must be system log) based on reboot.
|
| +
|
| + @param index: reboot to start at, earliest log at 0. Negative
|
| + numbers indicate reboots since end of log.
|
| + """
|
| + return self.set_start_by_regexp(index,
|
| + r'.*000\] Linux version \d')
|
| +
|
| +
|
| + def set_start_by_current(self, relative=1):
|
| + """ Set start of logs based on current last line.
|
| +
|
| + @param relative: line relative to current to start at. 1 means
|
| + to start the log after this line.
|
| + """
|
| + lines = utils.system_output('wc -l %s' % self._filename)
|
| + self._start_line = int(lines.split(' ')[0]) + relative
|
| +
|
| +
|
| + def get_logs(self):
|
| + """ Get logs since the start line.
|
| +
|
| + Start line is set by set_start_* functions or
|
| + since the start of the file if none were called.
|
| +
|
| + @return string of contents of file since start line.
|
| + """
|
| + return utils.system_output('tail -n +%d %s' %
|
| + (self._start_line, self._filename))
|
| +
|
| + def can_find(self, string):
|
| + """ Try to find string in the logs.
|
| +
|
| + @return boolean indicating if we found the string.
|
| + """
|
| + return string in self.get_logs()
|
| +
|
| +
|
| +class LogRotationPauser(object):
|
| + """
|
| + Class to control when logs are rotated from either server or client.
|
| +
|
| + Assumes all setting of CLEANUP_LOGS_PAUSED_FILE is done by this class
|
| + and that all calls to begin and end are properly
|
| + nested. For instance, [ a.begin(), b.begin(), b.end(), a.end() ] is
|
| + supported, but [ a.begin(), b.begin(), a.end(), b.end() ] is not.
|
| + We do support redundant calls to the same class, such as
|
| + [ a.begin(), a.begin(), a.end() ].
|
| + """
|
| + def __init__(self, host=None):
|
| + self._host = host
|
| + self._begun = False
|
| + self._is_nested = True
|
| +
|
| +
|
| + def _run(self, command, *args, **dargs):
|
| + if self._host:
|
| + return self._host.run(command, *args, **dargs).exit_status
|
| + else:
|
| + return utils.system(command, *args, **dargs)
|
| +
|
| +
|
| + def begin(self):
|
| + """Make sure that log rotation is disabled."""
|
| + if self._begun:
|
| + return
|
| + print "in begin " + str(self._begun)
|
| + self._is_nested = (self._run(('[ -r %s ]' %
|
| + CLEANUP_LOGS_PAUSED_FILE),
|
| + ignore_status=True) == 0)
|
| + print "in begin is nested: " + str(self._is_nested)
|
| + if self._is_nested:
|
| + print logging.__file__
|
| + logging.info('File %s was already present' %
|
| + CLEANUP_LOGS_PAUSED_FILE)
|
| + print 1
|
| + else:
|
| + self._run('touch ' + CLEANUP_LOGS_PAUSED_FILE)
|
| + print 2
|
| + self._begun = True
|
| +
|
| +
|
| + def end(self):
|
| + print "in end" + str(self._begun)
|
| + assert self._begun
|
| + if not self._is_nested:
|
| + self._run('rm -f ' + CLEANUP_LOGS_PAUSED_FILE)
|
| + else:
|
| + logging.info('Leaving existing %s file' % CLEANUP_LOGS_PAUSED_FILE)
|
| + self._begun = False
|
|
|