Source code for structlog.twisted

# Copyright 2013 Hynek Schlawack
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Processors and tools specific to the `Twisted <http://twistedmatrix.com/>`_
networking engine.
"""

from __future__ import absolute_import, division, print_function

import sys

from structlog import processors
from structlog._compat import string_types
from twisted.python.failure import Failure


[docs]class LoggerFactory(object): """ Build a Twisted logger when an *instance* is called. >>> from structlog import configure >>> from structlog.twisted import LoggerFactory >>> configure(logger_factory=LoggerFactory()) """ def __call__(self, name=None): """ :rvalue: A new Twisted logger. """ from twisted.python import log return log
_FAIL_TYPES = (BaseException, Failure) def _extractStuffAndWhy(eventDict): """ Removes all possible *_why*s and *_stuff*s, analyzes exc_info and returns a tuple of `(_stuff, _why, eventDict)`. **Modifies** *eventDict*! """ _stuff = eventDict.pop('_stuff', None) _why = eventDict.pop('_why', None) event = eventDict.pop('event', None) if ( isinstance(_stuff, _FAIL_TYPES) and isinstance(event, _FAIL_TYPES) ): raise ValueError('Both _stuff and event contain an Exception/Failure.') # `log.err('event', _why='alsoEvent')` is ambiguous. if _why and isinstance(event, string_types): raise ValueError('Both `_why` and `event` supplied.') # Two failures are ambiguos too. if not isinstance(_stuff, _FAIL_TYPES) and isinstance(event, _FAIL_TYPES): _why = _why or 'error' _stuff = event if isinstance(event, string_types): _why = event if not _stuff and sys.exc_info() != (None, None, None): _stuff = Failure() # Either we used the error ourselves or the user supplied one for # formatting. Avoid log.err() to dump another traceback into the log. if isinstance(_stuff, BaseException): _stuff = Failure(_stuff) sys.exc_clear() return _stuff, _why, eventDict
[docs]class JSONRenderer(processors.JSONRenderer): """ Behaves like :class:`structlog.processors.JSONRenderer` except that it formats tracebacks and failures itself if called with `err()`. *Not* an adapter like :class:`EventAdapter` but a real formatter. Nor does it require to be adapted using it. """ def __call__(self, logger, name, eventDict): _stuff, _why, eventDict = _extractStuffAndWhy(eventDict) if name == 'err': eventDict['event'] = _why if isinstance(_stuff, Failure): eventDict['exception'] = _stuff.getTraceback(detail='verbose') _stuff.cleanFailure() else: eventDict['event'] = _why return processors.JSONRenderer.__call__(self, logger, name, eventDict)
[docs]class EventAdapter(object): """ Adapt an ``event_dict`` to Twisted logging system. Particularly, make a wrapped `twisted.python.log.err <http://twistedmatrix.com/documents/current/ api/twisted.python.log.html#err>`_ behave as expected. **Must** be the last processor in the chain and requires a `dictFormatter` for the actual formatting as an constructor argument in order to be able to fully support the original behaviors of ``log.msg()`` and ``log.err()``. """ def __init__(self, dictFormatter=None): """ :param dictFormatter: A processor used to format the log message. """ self._dictFormatter = dictFormatter or processors.KeyValueRenderer() def __call__(self, logger, name, eventDict): if name == 'err': # This aspires to handle the following cases correctly: # - log.err(failure, _why='event', **kw) # - log.err('event', **kw) # - log.err(_stuff=failure, _why='event', **kw) _stuff, _why, eventDict = _extractStuffAndWhy(eventDict) eventDict['event'] = _why return ((), { '_stuff': _stuff, '_why': self._dictFormatter(logger, name, eventDict), }) else: return self._dictFormatter(logger, name, eventDict)

Project Versions

This Page