8 Commits

5 changed files with 67 additions and 28 deletions

View File

@@ -1,12 +1,11 @@
language: python language: python
python: python:
- "3.5" - "3.6"
sudo: false sudo: false
env: env:
- TOXENV=py27 - TOXENV=py27
- TOXENV=py33
- TOXENV=py34 - TOXENV=py34
- TOXENV=py35 - TOXENV=py36
install: install:
- pip install -U pip - pip install -U pip
- pip install -U Flask tox coverage codecov - pip install -U Flask tox coverage codecov

View File

@@ -32,7 +32,7 @@ no value is present in the message record.
import logging import logging
from flask import has_request_context, request from flask import has_request_context, request, current_app, has_app_context
__version_info__ = ('0', '0', '1') __version_info__ = ('0', '0', '1')
__version__ = '.'.join(__version_info__) __version__ = '.'.join(__version_info__)
@@ -121,14 +121,21 @@ class FlaskExtraLogger(logging.getLoggerClass()):
del(kwargs['app']) del(kwargs['app'])
self.app = None self.app = None
self._valid_keywords = [] self._valid_keywords = {}
self._blueprint_var = None self._blueprint_var = None
self._blueprint_app = None self._blueprint_app = None
self._blueprint_norequest = None self._blueprint_norequest = None
super(FlaskExtraLogger, self).__init__(*args, **kwargs) super(FlaskExtraLogger, self).__init__(*args, **kwargs)
if hasattr(self.__class__, '__default_config__'):
self.config = self.__class__.__default_config__
self.init_from_config()
def _log(self, *args, **kwargs): def _log(self, *args, **kwargs):
if has_app_context() and self.app is None:
self.init_app(current_app)
if 'extra' not in kwargs: if 'extra' not in kwargs:
kwargs['extra'] = {} kwargs['extra'] = {}
@@ -155,6 +162,42 @@ class FlaskExtraLogger(logging.getLoggerClass()):
'reserved for internal use.' 'reserved for internal use.'
.format(keyword=word)) .format(keyword=word))
def init_from_config(self):
"""Intialize the logger class from a Flask config dict
The class reads its necessary configuration from the config provided.
If the application doesnt call this, or doesnt have the `FLASK_LOGGING_EXTRAS_KEYWORDS`
in its config, no extra functionality will be added.
:raises ValueError: if the app tries to register a keyword that is
reserved for internal use
"""
if not isinstance(self.config, dict):
self.config = {
'FLASK_LOGGING_EXTRAS_KEYWORDS': getattr(self.config, 'FLASK_LOGGING_EXTRAS_KEYWORDS', {}),
'FLASK_LOGGING_EXTRAS_BLUEPRINT': getattr(self.config, 'FLASK_LOGGING_EXTRAS_BLUEPRINT', (None, '<app>', '<not a request>',)),
}
self.config.setdefault('FLASK_LOGGING_EXTRAS_KEYWORDS', {})
self.config.setdefault('FLASK_LOGGING_EXTRAS_BLUEPRINT',
(None, '<app>', '<not a request>'))
for kw in self.config['FLASK_LOGGING_EXTRAS_KEYWORDS']:
self._check_reserved_word(kw)
self._check_reserved_word(
self.config['FLASK_LOGGING_EXTRAS_BLUEPRINT'][0])
self._valid_keywords = self.config['FLASK_LOGGING_EXTRAS_KEYWORDS']
(
self._blueprint_var,
self._blueprint_app,
self._blueprint_norequest,
) = self.config['FLASK_LOGGING_EXTRAS_BLUEPRINT']
def init_app(self, app): def init_app(self, app):
""" """
Intialize the logger class with a Flask application Intialize the logger class with a Flask application
@@ -172,25 +215,12 @@ class FlaskExtraLogger(logging.getLoggerClass()):
reserved for internal use reserved for internal use
""" """
app.config.setdefault('FLASK_LOGGING_EXTRAS_KEYWORDS', {}) self.app = app
app.config.setdefault('FLASK_LOGGING_EXTRAS_BLUEPRINT', self.config = app.config
(None, '<app>', '<not a request>')) self.init_from_config()
for kw in app.config['FLASK_LOGGING_EXTRAS_KEYWORDS']:
self._check_reserved_word(kw)
self._check_reserved_word(
app.config['FLASK_LOGGING_EXTRAS_BLUEPRINT'][0])
self._valid_keywords = app.config['FLASK_LOGGING_EXTRAS_KEYWORDS']
(
self._blueprint_var,
self._blueprint_app,
self._blueprint_norequest,
) = app.config['FLASK_LOGGING_EXTRAS_BLUEPRINT']
def register_logger_class(cls=FlaskExtraLogger): def register_logger_class(cls=FlaskExtraLogger, config=None):
""" """
Register a new logger class Register a new logger class
@@ -219,5 +249,6 @@ def register_logger_class(cls=FlaskExtraLogger):
old_class = logging.getLoggerClass() old_class = logging.getLoggerClass()
logging.setLoggerClass(cls) logging.setLoggerClass(cls)
cls.__default_config__ = config
return old_class return old_class

View File

@@ -8,7 +8,7 @@ Flask-Logging-Extras provides extra logging functionality for Flask apps.
from setuptools import setup from setuptools import setup
setup(name='Flask-Logging-Extras', setup(name='Flask-Logging-Extras',
version='0.1.0', version='0.2.0',
url='https://github.com/gergelypolonkai/flask-logging-extras', url='https://github.com/gergelypolonkai/flask-logging-extras',
license='MIT', license='MIT',
author='Gergely Polonkai', author='Gergely Polonkai',

View File

@@ -191,10 +191,10 @@ class LoggerBlueprintTestCase(TestCase):
self.stream = ListStream() self.stream = ListStream()
formatter = logging.Formatter(fmt) formatter = logging.Formatter(fmt)
handler = TestingStreamHandler(stream=self.stream) self.handler = TestingStreamHandler(stream=self.stream)
handler.setLevel(logging.DEBUG) self.handler.setLevel(logging.DEBUG)
handler.setFormatter(formatter) self.handler.setFormatter(formatter)
app.logger.addHandler(handler) app.logger.addHandler(self.handler)
app.logger.setLevel(logging.DEBUG) app.logger.setLevel(logging.DEBUG)
bp = Blueprint('test_blueprint', 'test_bpg13') bp = Blueprint('test_blueprint', 'test_bpg13')
@@ -218,6 +218,15 @@ class LoggerBlueprintTestCase(TestCase):
def tearDown(self): def tearDown(self):
logging.setLoggerClass(self.original_logger_class) logging.setLoggerClass(self.original_logger_class)
def test_autoconfig(self):
logger = logging.getLogger('test')
logger.addHandler(self.handler)
with self.app.app_context():
logger.warning('Hello')
self.assertEqual('<norequest> Hello\n', self.stream.lines[-1])
def test_request_log(self): def test_request_log(self):
self.client.get('/app') self.client.get('/app')
self.assertEqual('<app> Message\n', self.stream.lines[-1]) self.assertEqual('<app> Message\n', self.stream.lines[-1])

View File

@@ -1,5 +1,5 @@
[tox] [tox]
envlist = py27, py33, py34, py35, py36 envlist = py27, py34, py36
[testenv] [testenv]
commands = commands =