Bug 1021943 - Add some additional features to mozlog.structured to help with informational level logging;r=jgraham

This commit is contained in:
William Lachance 2014-06-12 11:28:19 -04:00
Родитель a256b73ccf
Коммит c6f074b1e3
6 изменённых файлов: 48 добавлений и 2 удалений

Просмотреть файл

@ -19,6 +19,10 @@ loggers with the same name share the same internal state (the "Borg"
pattern). In particular the list of handler functions is the same for
all loggers with the same name.
Typically, you would only instantiate one logger object per
program. Two convenience methods are provided to set and get the
default logger in the program.
Logging is threadsafe, with access to handlers protected by a
``threading.Lock``. However it is `not` process-safe. This means that
applications using multiple processes, e.g. via the
@ -192,6 +196,7 @@ StructuredLogger Objects
------------------------
.. automodule:: mozlog.structured.structuredlog
:members: set_default_logger, get_default_logger
.. autoclass:: StructuredLogger
:members: add_handler, remove_handler, handlers, suite_start,

Просмотреть файл

@ -4,3 +4,4 @@
import commandline
import structuredlog
from structuredlog import get_default_logger, set_default_logger

Просмотреть файл

@ -5,7 +5,7 @@
import argparse
import sys
from structuredlog import StructuredLogger
from structuredlog import StructuredLogger, set_default_logger
import handlers
import formatters
@ -52,6 +52,9 @@ def setup_logging(suite, args, defaults):
"""
Configure a structuredlogger based on command line arguments.
The created structuredlogger will also be set as the default logger, and
can be retrieved with :py:func:`get_default_logger`.
:param suite: The name of the testsuite being run
:param args: A dictionary of {argument_name:value} produced from
parsing the command line arguments for the application
@ -90,4 +93,6 @@ def setup_logging(suite, args, defaults):
logger.add_handler(handlers.StreamHandler(stream=value,
formatter=formatter_cls()))
set_default_logger(logger)
return logger

Просмотреть файл

@ -83,6 +83,9 @@ class BaseMachFormatter(base.BaseFormatter):
data["command"])
def log(self, data):
if data.get('component'):
return " ".join([data["component"], data["level"], data["message"]])
return "%s %s" % (data["level"], data["message"])
def _get_subtest_data(self, data):

Просмотреть файл

@ -17,6 +17,9 @@ class TbplFormatter(BaseMachFormatter):
return getattr(self, data["action"])(data)
def log(self, data):
if data.get('component'):
return "%s %s\n" % (data["component"], data["message"])
return "%s\n" % (data["message"])
def process_output(self, data):

Просмотреть файл

@ -52,8 +52,34 @@ Subfields for all messages:
thread - name for the thread emitting the message
pid - id of the python process in which the logger is running
source - name for the source emitting the message
component - name of the subcomponent emitting the message
"""
_default_logger_name = None
def get_default_logger(component=None):
"""Gets the default logger if available, optionally tagged with component
name. Will return None if not yet set
:param component: The component name to tag log messages with
"""
global _default_logger_name
if not _default_logger_name:
return None
return StructuredLogger(_default_logger_name, component=component)
def set_default_logger(default_logger):
"""Sets the default logger to logger.
It can then be retrieved with :py:func:`get_default_logger`
:param default_logger: The logger to set to default.
"""
global _default_logger_name
_default_logger_name = default_logger.name
log_levels = dict((k.upper(), v) for v, k in
enumerate(["critical", "error", "warning", "info", "debug"]))
@ -67,8 +93,9 @@ class StructuredLogger(object):
:param name: The name of the logger.
"""
def __init__(self, name):
def __init__(self, name, component=None):
self.name = name
self.component = component
def add_handler(self, handler):
"""Add a handler to the current logger"""
@ -101,6 +128,8 @@ class StructuredLogger(object):
"thread": current_thread().name,
"pid": current_process().pid,
"source": self.name}
if self.component:
all_data['component'] = self.component
all_data.update(data)
return all_data