From 85253ec496acb62299c01cfff8b6c97cae68120c Mon Sep 17 00:00:00 2001 From: James Graham Date: Wed, 13 Aug 2014 15:10:46 +0100 Subject: [PATCH] Bug 1050700 - Add support for exc_info to mozlog.structured log actions, r=chmanchester --- .../structured/formatters/machformatter.py | 9 +++++++-- .../structured/formatters/tbplformatter.py | 9 +++++++-- .../mozlog/mozlog/structured/logtypes.py | 4 ++++ .../mozlog/mozlog/structured/structuredlog.py | 19 +++++++++++++++++-- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py b/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py index f9a02ee94a76..f2d63a831a18 100644 --- a/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py +++ b/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py @@ -247,9 +247,14 @@ class MachFormatter(base.BaseFormatter): level = self.terminal.blue(level) if data.get('component'): - return " ".join([data["component"], level, data["message"]]) + rv = " ".join([data["component"], level, data["message"]]) + else: + rv = "%s %s" % (level, message) - return "%s %s" % (level, data["message"]) + if "stack" in data: + rv += "\n%s" % data["stack"] + + return rv def _get_subtest_data(self, data): test = self._get_test_id(data) diff --git a/testing/mozbase/mozlog/mozlog/structured/formatters/tbplformatter.py b/testing/mozbase/mozlog/mozlog/structured/formatters/tbplformatter.py index 3d010e553e8e..80027db9fd31 100644 --- a/testing/mozbase/mozlog/mozlog/structured/formatters/tbplformatter.py +++ b/testing/mozbase/mozlog/mozlog/structured/formatters/tbplformatter.py @@ -18,9 +18,14 @@ class TbplFormatter(BaseFormatter): def log(self, data): if data.get('component'): - return "%s %s\n" % (data["component"], data["message"]) + message = "%s %s" % (data["component"], data["message"]) + else: + message = data["message"] - return "%s\n" % (data["message"]) + if "stack" in data: + message += "\n%s" % data["stack"] + + return "%s\n" % message def process_output(self, data): return "PROCESS | %(process)s | %(data)s\n" % data diff --git a/testing/mozbase/mozlog/mozlog/structured/logtypes.py b/testing/mozbase/mozlog/mozlog/structured/logtypes.py index f3f4846081b2..0e7b7243198a 100644 --- a/testing/mozbase/mozlog/mozlog/structured/logtypes.py +++ b/testing/mozbase/mozlog/mozlog/structured/logtypes.py @@ -165,3 +165,7 @@ class List(DataType): class Int(DataType): def convert(self, data): return int(data) + +class Any(DataType): + def convert(self, data): + return data diff --git a/testing/mozbase/mozlog/mozlog/structured/structuredlog.py b/testing/mozbase/mozlog/mozlog/structured/structuredlog.py index 0fe556c802ed..411a1d2d2bfb 100644 --- a/testing/mozbase/mozlog/mozlog/structured/structuredlog.py +++ b/testing/mozbase/mozlog/mozlog/structured/structuredlog.py @@ -7,9 +7,11 @@ from __future__ import unicode_literals from multiprocessing import current_process from threading import current_thread, Lock import json +import sys import time +import traceback -from logtypes import Unicode, TestId, Status, SubStatus, Dict, List, log_action, convertor_registry +from logtypes import Unicode, TestId, Status, SubStatus, Dict, List, Any, log_action, convertor_registry """Structured Logging for recording test results. @@ -297,14 +299,27 @@ class StructuredLogger(object): def _log_func(level_name): - @log_action(Unicode("message")) + @log_action(Unicode("message"), + Any("exc_info", default=False)) def log(self, data): + exc_info = data.pop("exc_info", None) + if exc_info: + if not isinstance(exc_info, tuple): + exc_info = sys.exc_info() + if exc_info != (None, None, None): + bt = traceback.format_exception(*exc_info) + data["stack"] = u"\n".join(bt) + data["level"] = level_name self._log_data("log", data) log.__doc__ = """Log a message with level %s :param message: The string message to log +:param exc_info: Either a boolean indicating whether to include a traceback + derived from sys.exc_info() or a three-item tuple in the + same format as sys.exc_info() containing exception information + to log. """ % level_name log.__name__ = str(level_name).lower() return log