forked from orbit-oss/flask
Always log now, even if debug is off.
This commit is contained in:
parent
0ce3db88cf
commit
84ad89ffa4
9 changed files with 68 additions and 21 deletions
3
CHANGES
3
CHANGES
|
|
@ -37,6 +37,9 @@ Version 1.0
|
||||||
result in the HTTP error of their choosing, but may be caught with
|
result in the HTTP error of their choosing, but may be caught with
|
||||||
a custom error handler if desired.
|
a custom error handler if desired.
|
||||||
- Added :meth:`flask.Config.from_mapping`.
|
- Added :meth:`flask.Config.from_mapping`.
|
||||||
|
- Flask will now log by default even if debug is disabled. The log format is
|
||||||
|
now hardcoded but the default log handling can be disabled through the
|
||||||
|
``LOGGER_HANDLER_POLICY`` configuration key.
|
||||||
|
|
||||||
Version 0.10.2
|
Version 0.10.2
|
||||||
--------------
|
--------------
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,14 @@ The following configuration values are used internally by Flask:
|
||||||
by this.
|
by this.
|
||||||
``USE_X_SENDFILE`` enable/disable x-sendfile
|
``USE_X_SENDFILE`` enable/disable x-sendfile
|
||||||
``LOGGER_NAME`` the name of the logger
|
``LOGGER_NAME`` the name of the logger
|
||||||
|
``LOGGER_HANDLER_POLICY`` the policy of the default logging
|
||||||
|
handler. The default is ``'always'``
|
||||||
|
which means that the default logging
|
||||||
|
handler is always active. ``'debug'``
|
||||||
|
will only activate logging in debug
|
||||||
|
mode, ``'production'`` will only log in
|
||||||
|
production and ``'never'`` disables it
|
||||||
|
entirely.
|
||||||
``SERVER_NAME`` the name and port number of the server.
|
``SERVER_NAME`` the name and port number of the server.
|
||||||
Required for subdomain support (e.g.:
|
Required for subdomain support (e.g.:
|
||||||
``'myapp.dev:5000'``) Note that
|
``'myapp.dev:5000'``) Note that
|
||||||
|
|
@ -229,7 +237,7 @@ The following configuration values are used internally by Flask:
|
||||||
``SESSION_REFRESH_EACH_REQUEST``
|
``SESSION_REFRESH_EACH_REQUEST``
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
``TEMPLATES_AUTO_RELOAD``
|
``TEMPLATES_AUTO_RELOAD``, ``LOGGER_HANDLER_POLICY``
|
||||||
|
|
||||||
Configuring from Files
|
Configuring from Files
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,16 @@ installation, make sure to pass it the ``-U`` parameter::
|
||||||
|
|
||||||
$ easy_install -U Flask
|
$ easy_install -U Flask
|
||||||
|
|
||||||
|
.. _upgrading-to-10:
|
||||||
|
|
||||||
|
Version 1.0
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Flask 1.0 removed the ``debug_log_format`` attribute from Flask
|
||||||
|
applications. Instead the new ``LOGGER_HANDLER_POLICY`` configuration can
|
||||||
|
be used to disable the default log handlers and custom log handlers can be
|
||||||
|
set up.
|
||||||
|
|
||||||
.. _upgrading-to-010:
|
.. _upgrading-to-010:
|
||||||
|
|
||||||
Version 0.10
|
Version 0.10
|
||||||
|
|
|
||||||
13
flask/app.py
13
flask/app.py
|
|
@ -260,18 +260,6 @@ class Flask(_PackageBoundObject):
|
||||||
#: will be removed in favor of Blueprints
|
#: will be removed in favor of Blueprints
|
||||||
enable_modules = True
|
enable_modules = True
|
||||||
|
|
||||||
#: The logging format used for the debug logger. This is only used when
|
|
||||||
#: the application is in debug mode, otherwise the attached logging
|
|
||||||
#: handler does the formatting.
|
|
||||||
#:
|
|
||||||
#: .. versionadded:: 0.3
|
|
||||||
debug_log_format = (
|
|
||||||
'-' * 80 + '\n' +
|
|
||||||
'%(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n' +
|
|
||||||
'%(message)s\n' +
|
|
||||||
'-' * 80
|
|
||||||
)
|
|
||||||
|
|
||||||
#: The JSON encoder class to use. Defaults to :class:`~flask.json.JSONEncoder`.
|
#: The JSON encoder class to use. Defaults to :class:`~flask.json.JSONEncoder`.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 0.10
|
#: .. versionadded:: 0.10
|
||||||
|
|
@ -297,6 +285,7 @@ class Flask(_PackageBoundObject):
|
||||||
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
|
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
|
||||||
'USE_X_SENDFILE': False,
|
'USE_X_SENDFILE': False,
|
||||||
'LOGGER_NAME': None,
|
'LOGGER_NAME': None,
|
||||||
|
'LOGGER_HANDLER_POLICY': 'always',
|
||||||
'SERVER_NAME': None,
|
'SERVER_NAME': None,
|
||||||
'APPLICATION_ROOT': None,
|
'APPLICATION_ROOT': None,
|
||||||
'SESSION_COOKIE_NAME': 'session',
|
'SESSION_COOKIE_NAME': 'session',
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,24 @@
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from logging import getLogger, StreamHandler, Formatter, getLoggerClass, DEBUG
|
from logging import getLogger, StreamHandler, Formatter, getLoggerClass, \
|
||||||
|
DEBUG, ERROR
|
||||||
|
|
||||||
|
|
||||||
|
PROD_LOG_FORMAT = '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
|
||||||
|
DEBUG_LOG_FORMAT = (
|
||||||
|
'-' * 80 + '\n' +
|
||||||
|
'%(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n' +
|
||||||
|
'%(message)s\n' +
|
||||||
|
'-' * 80
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def should_log_for(app, mode):
|
||||||
|
policy = app.config['LOGGER_HANDLER_POLICY']
|
||||||
|
if policy == mode or policy == 'always':
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def create_logger(app):
|
def create_logger(app):
|
||||||
|
|
@ -30,16 +47,28 @@ def create_logger(app):
|
||||||
return Logger.getEffectiveLevel(x)
|
return Logger.getEffectiveLevel(x)
|
||||||
|
|
||||||
class DebugHandler(StreamHandler):
|
class DebugHandler(StreamHandler):
|
||||||
def emit(x, record):
|
def emit(self, record):
|
||||||
StreamHandler.emit(x, record) if app.debug else None
|
if app.debug and should_log_for(app, 'debug'):
|
||||||
|
StreamHandler.emit(self, record)
|
||||||
|
|
||||||
|
class ProductionHandler(StreamHandler):
|
||||||
|
def emit(self, record):
|
||||||
|
if not app.debug and should_log_for(app, 'production'):
|
||||||
|
StreamHandler.emit(self, record)
|
||||||
|
|
||||||
|
debug_handler = DebugHandler()
|
||||||
|
debug_handler.setLevel(DEBUG)
|
||||||
|
debug_handler.setFormatter(Formatter(DEBUG_LOG_FORMAT))
|
||||||
|
|
||||||
|
prod_handler = ProductionHandler()
|
||||||
|
prod_handler.setLevel(ERROR)
|
||||||
|
prod_handler.setFormatter(Formatter(PROD_LOG_FORMAT))
|
||||||
|
|
||||||
handler = DebugHandler()
|
|
||||||
handler.setLevel(DEBUG)
|
|
||||||
handler.setFormatter(Formatter(app.debug_log_format))
|
|
||||||
logger = getLogger(app.logger_name)
|
logger = getLogger(app.logger_name)
|
||||||
# just in case that was not a new logger, get rid of all the handlers
|
# just in case that was not a new logger, get rid of all the handlers
|
||||||
# already attached to it.
|
# already attached to it.
|
||||||
del logger.handlers[:]
|
del logger.handlers[:]
|
||||||
logger.__class__ = DebugLogger
|
logger.__class__ = DebugLogger
|
||||||
logger.addHandler(handler)
|
logger.addHandler(debug_handler)
|
||||||
|
logger.addHandler(prod_handler)
|
||||||
return logger
|
return logger
|
||||||
|
|
|
||||||
|
|
@ -559,6 +559,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
||||||
def test_teardown_request_handler_error(self):
|
def test_teardown_request_handler_error(self):
|
||||||
called = []
|
called = []
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||||
@app.teardown_request
|
@app.teardown_request
|
||||||
def teardown_request1(exc):
|
def teardown_request1(exc):
|
||||||
self.assert_equal(type(exc), ZeroDivisionError)
|
self.assert_equal(type(exc), ZeroDivisionError)
|
||||||
|
|
@ -621,6 +622,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
||||||
|
|
||||||
def test_error_handling(self):
|
def test_error_handling(self):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
def not_found(e):
|
def not_found(e):
|
||||||
return 'not found', 404
|
return 'not found', 404
|
||||||
|
|
@ -920,6 +922,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
||||||
|
|
||||||
def test_none_response(self):
|
def test_none_response(self):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
app.testing = True
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def test():
|
def test():
|
||||||
return None
|
return None
|
||||||
|
|
@ -989,6 +992,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
||||||
def test_exception_propagation(self):
|
def test_exception_propagation(self):
|
||||||
def apprunner(configkey):
|
def apprunner(configkey):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
1 // 0
|
1 // 0
|
||||||
|
|
@ -996,7 +1000,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
||||||
if config_key is not None:
|
if config_key is not None:
|
||||||
app.config[config_key] = True
|
app.config[config_key] = True
|
||||||
try:
|
try:
|
||||||
resp = c.get('/')
|
c.get('/')
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ class ModuleTestCase(FlaskTestCase):
|
||||||
@emits_module_deprecation_warning
|
@emits_module_deprecation_warning
|
||||||
def test_error_handling(self):
|
def test_error_handling(self):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||||
admin = flask.Module(__name__, 'admin')
|
admin = flask.Module(__name__, 'admin')
|
||||||
@admin.app_errorhandler(404)
|
@admin.app_errorhandler(404)
|
||||||
def not_found(e):
|
def not_found(e):
|
||||||
|
|
|
||||||
|
|
@ -473,6 +473,7 @@ class LoggingTestCase(FlaskTestCase):
|
||||||
def test_exception_logging(self):
|
def test_exception_logging(self):
|
||||||
out = StringIO()
|
out = StringIO()
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||||
app.logger_name = 'flask_tests/test_exception_logging'
|
app.logger_name = 'flask_tests/test_exception_logging'
|
||||||
app.logger.addHandler(StreamHandler(out))
|
app.logger.addHandler(StreamHandler(out))
|
||||||
|
|
||||||
|
|
@ -492,6 +493,7 @@ class LoggingTestCase(FlaskTestCase):
|
||||||
|
|
||||||
def test_processor_exceptions(self):
|
def test_processor_exceptions(self):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def before_request():
|
def before_request():
|
||||||
if trigger == 'before':
|
if trigger == 'before':
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ class TestToolsTestCase(FlaskTestCase):
|
||||||
|
|
||||||
def test_test_client_context_binding(self):
|
def test_test_client_context_binding(self):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
flask.g.value = 42
|
flask.g.value = 42
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue