Source code for abilian.core.logging

# coding=utf-8
"""
Special loggers
---------------

Changing `patch_logger` logging level must be done very early, because it may
emit logging during imports. Ideally, it's should be the very first action in
your entry point before anything has been imported:

.. code-block:: python

 import logging
 logging.getLogger('PATCH').setLevel(logging.INFO)

"""
from __future__ import absolute_import, print_function, division

import logging

__all__ = ['patch_logger']

logging.basicConfig()

_mk_fmt = '[%(name)s] %(message)s at %(pathname)s:%(lineno)d'
_mk_format = logging.Formatter(fmt=_mk_fmt)

_patch_handler = logging.StreamHandler()
_patch_handler.setFormatter(_mk_format)
_patch_logger = logging.getLogger('PATCH')
_patch_logger.addHandler(_patch_handler)
_patch_logger.propagate = False

if _patch_logger.level is logging.NOTSET:
  _patch_logger.setLevel(logging.WARNING)

class PatchLoggerAdapter(logging.LoggerAdapter):

  def process(self, msg, kwargs):
    if isinstance(msg, basestring):
      return super(PatchLoggerAdapter, self).process(msg, kwargs)

    func = msg
    location = func.__module__
    if hasattr(func, 'im_class'):
      cls = func.__self__.__class__
      func = func.__func__
      location = '{}.{}'.format(cls.__module__, cls.__name__)

    return '{}.{}'.format(location, func.__name__), kwargs


#: logger for monkey patchs. use like this:
#: patch_logger.info(<func>`patched_func`)
patch_logger = PatchLoggerAdapter(_patch_logger, None)