Browse Source

Merge pull request #5 from gergelypolonkai/rewrite-as-formatter

Rewrite the whole thing as a Formatter
master
Gergely Polonkai 1 year ago
parent
commit
ddb469a8d2
No account linked to committer's email address
4 changed files with 155 additions and 357 deletions
  1. 2
    2
      docs/conf.py
  2. 60
    173
      flask_logging_extras/__init__.py
  3. 1
    1
      setup.py
  4. 92
    181
      tests/test_logger_keywords.py

+ 2
- 2
docs/conf.py View File

@@ -60,9 +60,9 @@ author = 'Gergely Polonkai'
60 60
 # built documents.
61 61
 #
62 62
 # The short X.Y version.
63
-version = '0.1'
63
+version = '1.0'
64 64
 # The full version, including alpha/beta/rc tags.
65
-release = '0.1.1'
65
+release = '1.0.0'
66 66
 
67 67
 # The language for content autogenerated by Sphinx. Refer to documentation
68 68
 # for a list of supported languages.

+ 60
- 173
flask_logging_extras/__init__.py View File

@@ -34,15 +34,15 @@ import logging
34 34
 
35 35
 from flask import has_request_context, request, current_app, has_app_context
36 36
 
37
-__version_info__ = ('0', '0', '1')
37
+__version_info__ = ('1', '0', '0')
38 38
 __version__ = '.'.join(__version_info__)
39 39
 __author__ = 'Gergely Polonkai'
40 40
 __license__ = 'MIT'
41
-__copyright__ = '(c) 2015 GT2'
41
+__copyright__ = '(c) 2015-2018 Benchmarked.games'
42 42
 
43
-class FlaskExtraLogger(logging.getLoggerClass()):
44
-    """
45
-    A logger class that is capable of adding extra keywords to log
43
+
44
+class FlaskExtraLoggerFormatter(logging.Formatter):
45
+    """A log formatter class that is capable of adding extra keywords to log
46 46
     formatters and logging the blueprint name
47 47
 
48 48
     Usage:
@@ -50,205 +50,92 @@ class FlaskExtraLogger(logging.getLoggerClass()):
50 50
     .. code-block:: python
51 51
 
52 52
        import logging
53
-
54
-       from flask_logging_extras import register_logger_class
55
-
56
-       # This must be done before the app is initialized!
57
-       register_logger_class(cls=FlaskExtraLogger)
53
+       from logging.config import dictConfig
54
+
55
+       dictConfig({
56
+           'formatters': {
57
+               'extras': {
58
+                   'format': '[%(asctime)s] [%(levelname)s] [%(category)s] [%(blueprint)s] %(message)s',
59
+               },
60
+           },
61
+           'handlers': {
62
+               'extras_handler': {
63
+                   'class': 'logging.FileHandler',
64
+                   'args': ('app.log', 'a'),
65
+                   'formatter': 'extras',
66
+                   'level': 'INFO',
67
+               },
68
+           },
69
+           'loggers': {
70
+               'my_app': {
71
+                   'handlers': ['extras_handler'],
72
+               }
73
+           },
74
+       })
58 75
 
59 76
        app = Flask(__name__)
60 77
        app.config['FLASK_LOGGING_EXTRAS_KEYWORDS'] = {'category': '<unset>'}
61 78
        app.config['FLASK_LOGGING_EXTRAS_BLUEPRINT'] = ('blueprint',
62 79
                                                        '<APP>',
63 80
                                                        '<NOT REQUEST>')
64
-       app.logger.init_app()
65 81
 
66 82
        bp = Blueprint('my_blueprint', __name__)
67 83
        app.register_blueprint(bp)
68 84
 
69
-       formatter = logging.Formatter(
70
-           '[%(asctime)s] [%(levelname)s] [%(category)s] %(message)s')
71
-       handler = logging.FileHandler('app.log', mode='a')
72
-       handler.setFormatter(formatter)
73
-       handler.setLevel(logging.INFO)
74
-
75
-       app.logger.addHandler(handler)
76
-
77
-       app.logger.info('The message', category='my category')
85
+       logger = logging.getLogger('my_app')
78 86
 
79 87
        # This will produce something like this in app.log:
80
-       # [2017-01-16 08:44:48.944] [INFO] [my category] The message
81
-
82
-       formatter = logging.Formatter('[%(blueprint)s] %(message)s')
83
-       handler = logging.FileHandler('other.log', mode='a')
84
-       handler.setFormatter(formatter)
85
-       handler.setLevel(logging.INFO)
86
-
87
-       app.logger.addHandler(handler)
88
+       # [2018-05-02 12:44:48.944] [INFO] [my category] [<NOT REQUEST>] The message
89
+       logger.info('The message', extra=dict(category='my category'))
88 90
 
89
-       @app.route('/1/')
91
+       @app.route('/1')
90 92
        def route_1():
91
-           # This will produce this log message:
92
-           # [<APP>] Message
93
-           current_app.logger.info('Message')
93
+           # This will produce a log message like this:
94
+           # [2018-05-02 12:44:48.944] [INFO] [<unset>] [<APP>] Message
95
+           logger.info('Message')
94 96
 
95 97
            return ''
96 98
 
97 99
        @bp.route('/2')
98 100
        def route_2():
99
-           # This will produce this log message:
100
-           # [my blueprint] Message
101
-           current_app.logger.info('Message')
101
+           # This will produce a log message like this:
102
+           # [2018-05-02 12:44:48.944] [INFO] [<unset>] [my_blueprint] Message
103
+           logger.info('Message')
102 104
 
103 105
            return ''
104 106
 
105
-       # This will produce this log message:
106
-       [<NOT REQUEST>] Message
107
-       app.logger.info('Message')
107
+       # This will produce a log message like this:
108
+       # [2018-05-02 12:44:48.944] [INFO] [<unset>] [<NOT REQUEST>] Message
109
+       logger.info('Message')
108 110
     """
109 111
 
110
-    _RESERVED_KEYWORDS = ('exc_info', 'extra', 'stack_info')
111
-
112
-    def __init__(self, *args, **kwargs):
113
-        if 'app' in kwargs:
114
-            if kwargs['app'] is not None:
115
-                raise TypeError(
116
-                    "Cannot initialise {classname} with an app.  See the"
117
-                    "documentation of Flask-Logging-Extras for more info."
118
-                    .format(classname=self.__class__.__name__))
119
-            else:
120
-                # If app is None, treat it as if it wasn’t there
121
-                del(kwargs['app'])
122
-
123
-        self.app = None
124
-        self._valid_keywords = {}
125
-        self._blueprint_var = None
126
-        self._blueprint_app = None
127
-        self._blueprint_norequest = None
128
-
129
-        super(FlaskExtraLogger, self).__init__(*args, **kwargs)
130
-
131
-        if hasattr(self.__class__, '__default_config__'):
132
-            self.config = self.__class__.__default_config__
133
-            self.init_from_config()
134
-
135
-    def _log(self, *args, **kwargs):
136
-        if has_app_context() and self.app is None:
137
-            self.init_app(current_app)
138
-
139
-        if 'extra' not in kwargs:
140
-            kwargs['extra'] = {}
141
-
142
-        # If we were asked to log the blueprint name, add it to the extra list
143
-        if self._blueprint_var is not None:
144
-            if has_request_context():
145
-                kwargs['extra'][self._blueprint_var] = request.blueprint or self._blueprint_app
146
-            else:
147
-                kwargs['extra'][self._blueprint_var] = self._blueprint_norequest
148
-
149
-        for kw in self._valid_keywords:
150
-            if kw in kwargs:
151
-                kwargs['extra'][kw] = kwargs[kw]
152
-                del(kwargs[kw])
153
-            else:
154
-                kwargs['extra'][kw] = self._valid_keywords[kw]
155
-
156
-        super(FlaskExtraLogger, self)._log(*args, **kwargs)
157
-
158
-    def _check_reserved_word(self, word):
159
-        if word in self._RESERVED_KEYWORDS:
160
-            raise ValueError(
161
-                '"{keyword}" cannot be used as an extra keyword, as it is '
162
-                'reserved for internal use.'
163
-                .format(keyword=word))
164
-
165
-    def init_from_config(self):
166
-        """Intialize the logger class from a Flask config dict
167
-
168
-        The class reads its necessary configuration from the config provided.
169
-
170
-        If the application doesn’t call this, or doesn’t have the `FLASK_LOGGING_EXTRAS_KEYWORDS`
171
-        in its config, no extra functionality will be added.
172
-
173
-        :raises ValueError: if the app tries to register a keyword that is
174
-                             reserved for internal use
175
-
176
-        """
177
-
178
-        if not isinstance(self.config, dict):
179
-            self.config = {
180
-                'FLASK_LOGGING_EXTRAS_KEYWORDS': getattr(self.config, 'FLASK_LOGGING_EXTRAS_KEYWORDS', {}),
181
-                'FLASK_LOGGING_EXTRAS_BLUEPRINT': getattr(self.config, 'FLASK_LOGGING_EXTRAS_BLUEPRINT', (None, '<app>', '<not a request>',)),
182
-            }
183
-
184
-        self.config.setdefault('FLASK_LOGGING_EXTRAS_KEYWORDS', {})
185
-        self.config.setdefault('FLASK_LOGGING_EXTRAS_BLUEPRINT',
186
-                               (None, '<app>', '<not a request>'))
187
-
188
-        for kw in self.config['FLASK_LOGGING_EXTRAS_KEYWORDS']:
189
-            self._check_reserved_word(kw)
190
-
191
-        self._check_reserved_word(
192
-            self.config['FLASK_LOGGING_EXTRAS_BLUEPRINT'][0])
193
-
194
-        self._valid_keywords = self.config['FLASK_LOGGING_EXTRAS_KEYWORDS']
195
-        (
196
-            self._blueprint_var,
197
-            self._blueprint_app,
198
-            self._blueprint_norequest,
199
-        ) = self.config['FLASK_LOGGING_EXTRAS_BLUEPRINT']
200
-
201
-    def init_app(self, app):
112
+    def _collect_keywords(self, record):
113
+        """Collect all valid keywords and add them to the log record if not present
202 114
         """
203
-        Intialize the logger class with a Flask application
204 115
 
205
-        The class reads its necessary configuration from the config of this
206
-        application.
116
+        # We assume we do have an active app context here
117
+        defaults = current_app.config.get('FLASK_LOGGING_EXTRAS_KEYWORDS', {})
207 118
 
208
-        If the application doesn’t call this, or doesn’t have the
209
-        `FLASK_LOGGING_EXTRAS_KEYWORDS` in its config, no extra
210
-        functionality will be added.
119
+        for keyword, default in defaults.items():
120
+            if keyword not in record.__dict__:
121
+                setattr(record, keyword, default)
211 122
 
212
-        :param app: a Flask application
213
-        :type app: Flask
214
-        :raises ValueError: if the app tries to register a keyword that is
215
-                             reserved for internal use
216
-        """
123
+    def format(self, record):
124
+        bp_var, bp_app, bp_noreq = ('blueprint', '<app>', '<not a request>')
125
+        blueprint = None
217 126
 
218
-        self.app = app
219
-        self.config = app.config
220
-        self.init_from_config()
127
+        if has_app_context():
128
+            self._collect_keywords(record)
221 129
 
130
+            bp_var, bp_app, bp_noreq = current_app.config.get('FLASK_LOGGING_EXTRAS_BLUEPRINT',
131
+                                                              (bp_var, bp_app, bp_noreq))
222 132
 
223
-def register_logger_class(cls=FlaskExtraLogger, config=None):
224
-    """
225
-    Register a new logger class
226
-
227
-    It is effectively a wrapper around `logging.setLoggerClass()`, with an
228
-    added check to make sure the class can be used as a logger.
229
-
230
-    To use the extra features of the logger class in a Flask app, you must
231
-    call it before the app is instantiated.
232
-
233
-    This function returns the logger class that was the default before
234
-    calling.  This might be useful if you only want to use `cls` in the
235
-    Flask app object, but not anywhere else in your code.  In this case,
236
-    simply call `register_logger_class()` again with the return value from
237
-    the first invocation.
238
-
239
-    :param cls: a logger class to register as the default one
240
-    :type cls: class(logging.Logger)
241
-    :returns: the old default logger class
242
-    :rtype: class
243
-    :raises TypeError: if the class is not a subclass of `logging.Logger`
244
-    """
133
+            if bp_var and has_request_context():
134
+                blueprint = request.blueprint or bp_app
245 135
 
246
-    if not issubclass(cls, logging.Logger):
247
-        raise TypeError(
248
-            "The logger class must be a subclass of logging.Logger!")
136
+        if bp_var and bp_var not in record.__dict__:
137
+            blueprint = blueprint or bp_noreq
249 138
 
250
-    old_class = logging.getLoggerClass()
251
-    logging.setLoggerClass(cls)
252
-    cls.__default_config__ = config
139
+            setattr(record, bp_var, blueprint)
253 140
 
254
-    return old_class
141
+        return super(FlaskExtraLoggerFormatter, self).format(record)

+ 1
- 1
setup.py View File

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

+ 92
- 181
tests/test_logger_keywords.py View File

@@ -1,9 +1,9 @@
1 1
 # -*- coding: utf-8 -*-
2
-"""
3
-Unit tests for Flask-Logging-Extras
2
+"""Unit tests for Flask-Logging-Extras
4 3
 """
5 4
 
6 5
 import logging
6
+from logging.config import dictConfig
7 7
 import sys
8 8
 from unittest import TestCase
9 9
 
@@ -11,203 +11,124 @@ from flask import Flask, Blueprint, current_app
11 11
 
12 12
 import flask_logging_extras
13 13
 
14
-class ListStream(object):
15
-    """
16
-    Primitive stream that stores its input lines in a list
17
-    """
18 14
 
15
+class ListHandler(logging.StreamHandler):
19 16
     def __init__(self, *args, **kwargs):
20
-        self.lines = []
21
-
22
-        super(ListStream, self).__init__(*args, **kwargs)
23
-
24
-    def write(self, data):
25
-        if len(self.lines) == 0 or self.lines[-1].endswith('\n'):
26
-            self.lines.append(data)
27
-        else:
28
-            self.lines[-1] += data
29
-
30
-
31
-class TestingStreamHandler(logging.StreamHandler):
32
-    def handleError(self, record):
33
-        exc, exc_msg, trace = sys.exc_info()
34
-
35
-        super(logging.StreamHandler, self).handleError(record)
36
-
37
-        raise(exc(exc_msg))
17
+        super(ListHandler, self).__init__(*args, **kwargs)
18
+
19
+        self.logs = []
20
+
21
+    def emit(self, record):
22
+        try:
23
+            msg = self.format(record)
24
+        except (KeyError, IndexError) as exc:
25
+            msg = (exc.__class__.__name__, str(exc))
26
+
27
+        self.logs.append(msg)
28
+
29
+
30
+def configure_loggers(extra_var):
31
+    dictConfig({
32
+        'version': 1,
33
+        'disable_existing_loggers': True,
34
+        'formatters': {
35
+            'selftest': {
36
+                'class': 'flask_logging_extras.FlaskExtraLoggerFormatter',
37
+                'format': '%(message)s %({extra_var})s'.format(extra_var=extra_var),
38
+            },
39
+        },
40
+        'handlers': {
41
+            'selftest': {
42
+                'class': 'test_logger_keywords.ListHandler',
43
+                'formatter': 'selftest',
44
+            },
45
+        },
46
+        'loggers': {
47
+            'selftest': {
48
+                'handlers': ['selftest'],
49
+                'level': 'INFO',
50
+            },
51
+        },
52
+    })
53
+
54
+    formatter = flask_logging_extras.FlaskExtraLoggerFormatter(
55
+        fmt='%(message)s %({extra_var})s'.format(extra_var=extra_var))
56
+
57
+    logger = logging.getLogger('selftest')
58
+    handlers = [handler for handler in logger.handlers if isinstance(handler, ListHandler)]
59
+    handler = handlers[0]
60
+    # TODO: Why doesn’t this happen automatically in Python 2.7?
61
+    handler.setFormatter(formatter)
62
+
63
+    return logger, handler
38 64
 
39 65
 
40 66
 class LoggerKeywordsTestCase(TestCase):
41 67
     def setUp(self):
42
-        self.original_logger_class = logging.getLoggerClass()
43
-
44
-    def tearDown(self):
45
-        logging.setLoggerClass(self.original_logger_class)
46
-
47
-    def test_logger_registration(self):
48
-        class NotLoggerClass(object):
49
-            pass
50
-
51
-        with self.assertRaises(TypeError):
52
-            flask_logging_extras.register_logger_class(cls=NotLoggerClass)
53
-
54
-        original_logging_class = logging.getLoggerClass()
55
-
56
-        old_class = flask_logging_extras.register_logger_class()
57
-
58
-        # If no class is specified, FlaskExtraLogger should be registered
59
-        self.assertEqual(logging.getLoggerClass(),
60
-                         flask_logging_extras.FlaskExtraLogger)
61
-        # The return value of this function should be the old default
62
-        self.assertEqual(original_logging_class, old_class)
63
-
64
-        class MyLogger(logging.Logger):
65
-            pass
66
-
67
-        # Calling register_logger_class() with any subclass of
68
-        # logging.Logger should succeed
69
-        flask_logging_extras.register_logger_class(cls=MyLogger)
70
-
71
-    def test_logger_class(self):
72
-        # If app is present during __init__, and is not None, we should get
73
-        # a TypeError
74
-        with self.assertRaises(TypeError):
75
-            flask_logging_extras.FlaskExtraLogger('test_logger',
76
-                                                  app='test value')
77
-
78
-        # If app is present, but is None, no exception should be raised
79
-        flask_logging_extras.FlaskExtraLogger('test_logger', app=None)
80
-
81
-    def test_logger_class_init_app(self):
82
-        logger = flask_logging_extras.FlaskExtraLogger('test')
83
-        app = Flask('test_app')
84
-
85
-        logger.init_app(app)
86
-
87
-        self.assertEqual({}, logger._valid_keywords)
88
-
89
-        app.config['FLASK_LOGGING_EXTRAS_KEYWORDS'] = {'exc_info': None}
90
-
91
-        with self.assertRaises(ValueError):
92
-            logger.init_app(app)
93
-
94
-        app.config['FLASK_LOGGING_EXTRAS_KEYWORDS'] = {'my_keyword': '<unset>'}
95
-
96
-        logger.init_app(app)
97
-        self.assertEqual({'my_keyword': '<unset>'}, logger._valid_keywords)
98
-
99
-        # Without registration first, app.logger should not be of class
100
-        # FlaskExtraLogger (even though logger.init_app() succeeded without
101
-        # it.)
102
-        self.assertNotIsInstance(app.logger,
103
-                                 flask_logging_extras.FlaskExtraLogger)
68
+        self.logger, self.handler = configure_loggers('extra_keyword')
69
+        self.app = Flask('test_app')
70
+        self.app.config['FLASK_LOGGING_EXTRAS_KEYWORDS'] = {
71
+            'extra_keyword': 'placeholder',
72
+        }
104 73
 
105
-        flask_logging_extras.register_logger_class()
74
+        # Make sure we don’t try to log the current blueprint for this test case
75
+        self.app.config['FLASK_LOGGING_EXTRAS_BLUEPRINT'] = (None, '', '')
106 76
 
107
-        # Even after registratiiion, existing apps are (obviously) not
108
-        # tampered with
77
+    def test_keywords_no_app_ctx(self):
78
+        """With the current formatter, the last log line must be a just the message
79
+        """
109 80
 
110
-        self.assertNotIsInstance(app.logger,
111
-                                 flask_logging_extras.FlaskExtraLogger)
81
+        self.logger.info('message')
82
+        self.assertIn(('KeyError', "'extra_keyword'"), self.handler.logs)
112 83
 
113
-        app = Flask('test_app')
114
-
115
-        # Newly created apps, though, should be made with this class
116
-        self.assertIsInstance(app.logger,
117
-                              flask_logging_extras.FlaskExtraLogger)
118
-
119
-    def _create_app_with_logger(self, fmt, keywords=[]):
120
-        app = Flask('test_app')
121
-
122
-        self.assertIsInstance(app.logger,
123
-                              flask_logging_extras.FlaskExtraLogger)
124
-
125
-        app.config['FLASK_LOGGING_EXTRAS_KEYWORDS'] = keywords
126
-        app.logger.init_app(app)
127
-
128
-        formatter = logging.Formatter(fmt)
129
-        stream = ListStream()
130
-
131
-        handler = TestingStreamHandler(stream=stream)
132
-        handler.setLevel(logging.DEBUG)
133
-        handler.setFormatter(formatter)
134
-
135
-        app.logger.addHandler(handler)
136
-        app.logger.setLevel(logging.DEBUG)
137
-
138
-        return app, stream
139
-
140
-    def test_keywords(self):
141
-        # Register our logger class as the default
142
-        old_logger_class = flask_logging_extras.register_logger_class()
143
-
144
-        app, log_stream = self._create_app_with_logger('%(message)s')
145
-
146
-        app.logger.info('message')
147
-        # With the current formatter, the last log line must be a just the
148
-        # message
149
-        self.assertEqual(log_stream.lines[-1], 'message\n')
150
-
151
-        app, log_stream = self._create_app_with_logger(
152
-            '%(message)s %(extra_keyword)s')
153
-
154
-        # If we don’t register 'extra_keyword' in the app config, we get a
84
+    def test_keywords_app_ctx_assign_value(self):
85
+        """If we don’t register 'extra_keyword' in the app config, we get a
155 86
         # KeyError.  We set logging.raiseExceptions to False here; the
156 87
         # reason is that this doesn’t mean an actual exception is raised,
157 88
         # but our TestingStreamHandler does that for us (which we need for
158 89
         # testing purposes)
159
-        old_raiseExceptions = logging.raiseExceptions
160
-        logging.raiseExceptions = False
161
-        with self.assertRaises(KeyError):
162
-            app.logger.info('message')
163
-        logging.raiseExceptions = old_raiseExceptions
90
+        """
164 91
 
165
-        app, log_stream = self._create_app_with_logger(
166
-            '%(message)s [%(extra_keyword)s]',
167
-            keywords={'extra_keyword': '<unset>'})
92
+        with self.app.app_context():
93
+            self.logger.info('message', extra=dict(extra_keyword='test'))
168 94
 
169
-        app.logger.info('message', extra_keyword='test')
170
-        self.assertEqual('message [test]\n', log_stream.lines[-1])
95
+        self.assertIn('message test', self.handler.logs)
171 96
 
172
-        # If we don’t provide a value for a registered extra keyword, the
97
+    def test_keywords_app_ctx_no_value(self):
98
+        """If we don’t provide a value for a registered extra keyword, the
173 99
         # string "<unset>" will be assigned.
174
-        app.logger.info('message')
175
-        self.assertEqual('message [<unset>]\n', log_stream.lines[-1])
100
+        """
101
+
102
+        with self.app.app_context():
103
+            self.logger.info('message')
104
+
105
+        self.assertIn('message placeholder', self.handler.logs)
176 106
 
177 107
 
178 108
 class LoggerBlueprintTestCase(TestCase):
179 109
     def setUp(self):
180 110
         # Register our logger class
181
-        self.original_logger_class = logging.getLoggerClass()
182
-        flask_logging_extras.register_logger_class()
183 111
 
184 112
         app = Flask('test_app')
185 113
         self.app = app
186
-        app.config['FLASK_LOGGING_EXTRAS_BLUEPRINT'] = (
187
-            'bp', '<app>', '<norequest>')
188
-        app.logger.init_app(app)
114
+        app.config['FLASK_LOGGING_EXTRAS_BLUEPRINT'] = ('bp', '<app>', '<norequest>')
189 115
 
190
-        fmt = '%(bp)s %(message)s'
191
-        self.stream = ListStream()
116
+        configure_loggers('bp')
117
+        self.logger = logging.getLogger('selftest')
118
+        handlers = [handler for handler in self.logger.handlers if isinstance(handler, ListHandler)]
119
+        self.handler = handlers[0]
192 120
 
193
-        formatter = logging.Formatter(fmt)
194
-        self.handler = TestingStreamHandler(stream=self.stream)
195
-        self.handler.setLevel(logging.DEBUG)
196
-        self.handler.setFormatter(formatter)
197
-        app.logger.addHandler(self.handler)
198
-        app.logger.setLevel(logging.DEBUG)
199
-
200
-        bp = Blueprint('test_blueprint', 'test_bpg13')
121
+        bp = Blueprint('test_blueprint', 'test_bp')
201 122
 
202 123
         @app.route('/app')
203 124
         def route_1():
204
-            current_app.logger.info('Message')
125
+            self.logger.info('Message')
205 126
 
206 127
             return ''
207 128
 
208 129
         @bp.route('/blueprint')
209 130
         def route_2():
210
-            current_app.logger.info('Message')
131
+            self.logger.info('Message')
211 132
 
212 133
             return ''
213 134
 
@@ -215,26 +136,16 @@ class LoggerBlueprintTestCase(TestCase):
215 136
 
216 137
         self.client = app.test_client()
217 138
 
218
-    def tearDown(self):
219
-        logging.setLoggerClass(self.original_logger_class)
220
-
221
-    def test_autoconfig(self):
222
-        logger = logging.getLogger('test')
223
-        logger.addHandler(self.handler)
224
-
225
-        with self.app.app_context():
226
-            logger.warning('Hello')
227
-
228
-        self.assertEqual('<norequest> Hello\n', self.stream.lines[-1])
229
-
230
-    def test_request_log(self):
139
+    def test_blueprint_log_no_blueprint(self):
231 140
         self.client.get('/app')
232
-        self.assertEqual('<app> Message\n', self.stream.lines[-1])
141
+        self.assertIn('Message <app>', self.handler.logs)
233 142
 
234
-        page = self.client.get('/blueprint')
235
-        self.assertEqual('test_blueprint Message\n', self.stream.lines[-1])
143
+    def test_blueprint_log_blueprint(self):
144
+        self.client.get('/blueprint')
145
+        self.assertIn('Message test_blueprint', self.handler.logs)
236 146
 
147
+    def test_blueprint_log_no_request(self):
237 148
         with self.app.app_context():
238
-            current_app.logger.info('Message')
149
+            self.logger.info('Message')
239 150
 
240
-        self.assertEqual('<norequest> Message\n', self.stream.lines[-1])
151
+        self.assertIn('Message <norequest>', self.handler.logs)

Loading…
Cancel
Save