flask-logging-extras/flask_logging_extras/__init__.py

125 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Extra functionality for Flask logging
Flask-Logging-Extras is a Flask extension that plugs into the logging
mechanism of Flask applications.
"""
import logging
__version_info__ = ('0', '0', '1')
__version__ = '.'.join(__version_info__)
__author__ = 'Gergely Polonkai'
__license__ = 'BSD'
__copyright__ = '(c) 2015 GT2'
class FlaskExtraLogger(logging.getLoggerClass()):
"""
A logger class that is capable of adding extra keywords to log formatters
Usage:
.. code-block:: python
import logging
from flask_logging_extras import register_logger_class
# This must be done before the app is initialized!
register_logger_class(cls=FlaskExtraLogger)
app = Flask(__name__)
app.config['FLASK_LOGGING_EXTRAS_KEYWORDS'] = ['category']
app.logger.init_app()
formatter = logging.Formatter(
'[%(asctime)s] [%(levelname)s] [%(category)s] %(message)s')
handler = logging.FileHandler('app.log', mode='a')
handler.setFormatter(formatter)
handler.setLevel(logging.INFO)
app.logger.addHandler(handler)
app.logger.info('The message', category='my category')
# This will produce something like this in app.log:
# [TIMESTAMP2017-01-16 08:44:48.944] [INFO] [my category] The message
"""
def __init__(self, *args, **kwargs):
if 'app' in kwargs and kwargs['app'] is not None:
raise TypeError(
"Cannot initialise {classname} with an app. "
"See the documentation of Flask-Logging-Extras for more info."
.format(classname=self.__class__.__name__))
super(FlaskExtraLogger, self).__init__(*args, **kwargs)
def _log(self, *args, **kwargs):
if 'extra' not in kwargs:
kwargs['extra'] = {}
for kw in self._valid_keywords:
if kw in kwargs:
kwargs['extra'][kw] = kwargs[kw]
super(FlaskExtraLogger, self)._log(*args, **kwargs)
def init_app(self, app):
"""
Intialize the logger class with a Flask application
The class reads its necessary configuration from the config of this
application.
If the application doesnt call this, or doesnt have the
`FLASK_LOGGING_EXTRAS_KEYWORDS` in its config, no extra
functionality will be added.
:param app: a Flask application
:type app: Flask
:raises ValueError: if the app tries to register a keyword that is
reserved for internal use
"""
app.config.setdefault('FLASK_LOGGING_EXTRAS_KEYWORDS', [])
for kw in app.config['FLASK_LOGGING_EXTRAS_KEYWORDS']:
if kw in ['exc_info', 'extra', 'stack_info']:
raise ValueError(
'"{keyword}" member of FLASK_LOGGING_EXTRAS_KEYWORDS is '
'reserved for internal use.')
def register_logger_class(cls=FlaskExtraLogger):
"""
Register a new logger class
It is effectively a wrapper around `logging.setLoggerClass()`, with an
added check to make sure the class can be used as a logger.
To use the extra features of the logger class in a Flask app, you must
call it before the app is instantiated.
This function returns the logger class that was the default before
calling. This might be useful if you only want to use `cls` in the
Flask app object, but not anywhere else in your code. In this case,
simply call `register_logger_class()` again with the return value from
the first invocation.
:param cls: a logger class to register as the default one
:type cls: class(logging.Logger)
:returns: the old default logger class
:rtype: class
:raises TypeError: if the class is not a subclass of `logging.Logger`
"""
if not issubclass(cls, logging.Logger):
raise TypeError(
"The logger class must be a subclass of logging.Logger!")
old_class = logging.get_logger_class()
logging.setLoggerClass(cls)
return old_class