Beispiel #1
0
    def __init__(self,
                 status_code,
                 subdir,
                 operation,
                 message,
                 fields,
                 timestamp=None):
        """Construct a status.log entry.

        @param status_code: A message status code. Must match the codes
            accepted by autotest_lib.common_lib.log.is_valid_status.
        @param subdir: A valid job subdirectory, or None.
        @param operation: Description of the operation, or None.
        @param message: A printable string describing event to be recorded.
        @param fields: A dictionary of arbitrary alphanumeric key=value pairs
            to be included in the log, or None.
        @param timestamp: An optional integer timestamp, in the same format
            as a time.time() timestamp. If unspecified, the current time is
            used.

        @raise ValueError: if any of the parameters are invalid
        """

        if not log.is_valid_status(status_code):
            raise ValueError('status code %r is not valid' % status_code)
        self.status_code = status_code

        if subdir and self.BAD_CHAR_REGEX.search(subdir):
            raise ValueError('Invalid character in subdir string')
        self.subdir = subdir

        if operation and self.BAD_CHAR_REGEX.search(operation):
            raise ValueError('Invalid character in operation string')
        self.operation = operation

        # break the message line into a single-line message that goes into the
        # database, and a block of additional lines that goes into the status
        # log but will never be parsed
        message_lines = message.split('\n')
        self.message = message_lines[0].replace('\t', ' ' * 8)
        self.extra_message_lines = message_lines[1:]
        if self.BAD_CHAR_REGEX.search(self.message):
            raise ValueError('Invalid character in message %r' % self.message)

        if not fields:
            self.fields = {}
        else:
            self.fields = fields.copy()
        for key, value in self.fields.iteritems():
            if self.BAD_CHAR_REGEX.search(key + value):
                raise ValueError('Invalid character in %r=%r field' %
                                 (key, value))

        # build up the timestamp
        if timestamp is None:
            timestamp = int(time.time())
        self.fields[self.TIMESTAMP_FIELD] = str(timestamp)
        self.fields[self.LOCALTIME_FIELD] = time.strftime(
            '%b %d %H:%M:%S', time.localtime(timestamp))
Beispiel #2
0
    def __init__(self, status_code, subdir, operation, message, fields,
                 timestamp=None):
        """Construct a status.log entry.

        @param status_code: A message status code. Must match the codes
            accepted by autotest_lib.common_lib.log.is_valid_status.
        @param subdir: A valid job subdirectory, or None.
        @param operation: Description of the operation, or None.
        @param message: A printable string describing event to be recorded.
        @param fields: A dictionary of arbitrary alphanumeric key=value pairs
            to be included in the log, or None.
        @param timestamp: An optional integer timestamp, in the same format
            as a time.time() timestamp. If unspecified, the current time is
            used.

        @raise ValueError: if any of the parameters are invalid
        """

        if not log.is_valid_status(status_code):
            raise ValueError('status code %r is not valid' % status_code)
        self.status_code = status_code

        if subdir and self.BAD_CHAR_REGEX.search(subdir):
            raise ValueError('Invalid character in subdir string')
        self.subdir = subdir

        if operation and self.BAD_CHAR_REGEX.search(operation):
            raise ValueError('Invalid character in operation string')
        self.operation = operation

        # break the message line into a single-line message that goes into the
        # database, and a block of additional lines that goes into the status
        # log but will never be parsed
        message_lines = message.split('\n')
        self.message = message_lines[0].replace('\t', ' ' * 8)
        self.extra_message_lines = message_lines[1:]
        if self.BAD_CHAR_REGEX.search(self.message):
            raise ValueError('Invalid character in message %r' % self.message)

        if not fields:
            self.fields = {}
        else:
            self.fields = fields.copy()
        for key, value in self.fields.iteritems():
            if type(value) is int:
                value = str(value)
            if self.BAD_CHAR_REGEX.search(key + value):
                raise ValueError('Invalid character in %r=%r field'
                                 % (key, value))

        # build up the timestamp
        if timestamp is None:
            timestamp = int(time.time())
        self.fields[self.TIMESTAMP_FIELD] = str(timestamp)
        self.fields[self.LOCALTIME_FIELD] = time.strftime(
            '%b %d %H:%M:%S', time.localtime(timestamp))
Beispiel #3
0
    def _render_record(self, status_code, subdir, operation, status='',
                       epoch_time=None, record_prefix=None,
                       optional_fields=None):
        """
        Internal Function to generate a record to be written into a
        status log. For use by server_job.* classes only.
        """
        if subdir:
            if re.match(r'[\n\t]', subdir):
                raise ValueError('Invalid character in subdir string')
            substr = subdir
        else:
            substr = '----'

        if not log.is_valid_status(status_code):
            raise ValueError('Invalid status code supplied: %s' % status_code)
        if not operation:
            operation = '----'
        if re.match(r'[\n\t]', operation):
            raise ValueError('Invalid character in operation string')
        operation = operation.rstrip()
        status = status.rstrip()
        status = re.sub(r"\t", "  ", status)
        # Ensure any continuation lines are marked so we can
        # detect them in the status file to ensure it is parsable.
        status = re.sub(r"\n", "\n" + self.record_prefix + "  ", status)

        if not optional_fields:
            optional_fields = {}

        # Generate timestamps for inclusion in the logs
        if epoch_time is None:
            epoch_time = int(time.time())
        local_time = time.localtime(epoch_time)
        optional_fields["timestamp"] = str(epoch_time)
        optional_fields["localtime"] = time.strftime("%b %d %H:%M:%S",
                                                     local_time)

        fields = [status_code, substr, operation]
        fields += ["%s=%s" % x for x in optional_fields.iteritems()]
        fields.append(status)

        if record_prefix is None:
            record_prefix = self.record_prefix

        msg = '\t'.join(str(x) for x in fields)
        return record_prefix + msg + '\n'
Beispiel #4
0
    def record(self, status_code, subdir, operation, status = '',
               optional_fields=None):
        """
        Record job-level status

        The intent is to make this file both machine parseable and
        human readable. That involves a little more complexity, but
        really isn't all that bad ;-)

        Format is <status code>\t<subdir>\t<operation>\t<status>

        status code: (GOOD|WARN|FAIL|ABORT)
                or   START
                or   END (GOOD|WARN|FAIL|ABORT)

        subdir: MUST be a relevant subdirectory in the results,
        or None, which will be represented as '----'

        operation: description of what you ran (e.g. "dbench", or
                                        "mkfs -t foobar /dev/sda9")

        status: error message or "completed sucessfully"

        ------------------------------------------------------------

        Initial tabs indicate indent levels for grouping, and is
        governed by self.group_level

        multiline messages have secondary lines prefaced by a double
        space ('  ')
        """

        if subdir:
            if re.match(r'[\n\t]', subdir):
                raise ValueError("Invalid character in subdir string")
            substr = subdir
        else:
            substr = '----'

        if not log.is_valid_status(status_code):
            raise ValueError("Invalid status code supplied: %s" % status_code)
        if not operation:
            operation = '----'

        if re.match(r'[\n\t]', operation):
            raise ValueError("Invalid character in operation string")
        operation = operation.rstrip()

        if not optional_fields:
            optional_fields = {}

        status = status.rstrip()
        status = re.sub(r"\t", "  ", status)
        # Ensure any continuation lines are marked so we can
        # detect them in the status file to ensure it is parsable.
        status = re.sub(r"\n", "\n" + "\t" * self.group_level + "  ", status)

        # Generate timestamps for inclusion in the logs
        epoch_time = int(time.time())  # seconds since epoch, in UTC
        local_time = time.localtime(epoch_time)
        optional_fields["timestamp"] = str(epoch_time)
        optional_fields["localtime"] = time.strftime("%b %d %H:%M:%S",
                                                     local_time)

        fields = [status_code, substr, operation]
        fields += ["%s=%s" % x for x in optional_fields.iteritems()]
        fields.append(status)

        msg = '\t'.join(str(x) for x in fields)
        msg = '\t' * self.group_level + msg

        msg_tag = ""
        if "." in self.log_filename:
            msg_tag = self.log_filename.split(".", 1)[1]

        self.harness.test_status_detail(status_code, substr, operation, status,
                                        msg_tag)
        self.harness.test_status(msg, msg_tag)

        # log to stdout (if enabled)
        #if self.log_filename == self.DEFAULT_LOG_FILENAME:
        logging.info(msg)

        # log to the "root" status log
        status_file = os.path.join(self.resultdir, self.log_filename)
        open(status_file, "a").write(msg + "\n")

        # log to the subdir status log (if subdir is set)
        if subdir:
            dir = os.path.join(self.resultdir, subdir)
            status_file = os.path.join(dir, self.DEFAULT_LOG_FILENAME)
            open(status_file, "a").write(msg + "\n")