mirror of https://github.com/pallets/flask.git
Always log now, even if debug is off.
This commit is contained in:
parent
0ce3db88cf
commit
84ad89ffa4
3
CHANGES
3
CHANGES
|
@ -37,6 +37,9 @@ Version 1.0
|
|||
result in the HTTP error of their choosing, but may be caught with
|
||||
a custom error handler if desired.
|
||||
- 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
|
||||
--------------
|
||||
|
|
|
@ -99,6 +99,14 @@ The following configuration values are used internally by Flask:
|
|||
by this.
|
||||
``USE_X_SENDFILE`` enable/disable x-sendfile
|
||||
``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.
|
||||
Required for subdomain support (e.g.:
|
||||
``'myapp.dev:5000'``) Note that
|
||||
|
@ -229,7 +237,7 @@ The following configuration values are used internally by Flask:
|
|||
``SESSION_REFRESH_EACH_REQUEST``
|
||||
|
||||
.. versionadded:: 1.0
|
||||
``TEMPLATES_AUTO_RELOAD``
|
||||
``TEMPLATES_AUTO_RELOAD``, ``LOGGER_HANDLER_POLICY``
|
||||
|
||||
Configuring from Files
|
||||
----------------------
|
||||
|
|
|
@ -19,6 +19,16 @@ installation, make sure to pass it the ``-U`` parameter::
|
|||
|
||||
$ 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:
|
||||
|
||||
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
|
||||
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`.
|
||||
#:
|
||||
#: .. versionadded:: 0.10
|
||||
|
@ -297,6 +285,7 @@ class Flask(_PackageBoundObject):
|
|||
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
|
||||
'USE_X_SENDFILE': False,
|
||||
'LOGGER_NAME': None,
|
||||
'LOGGER_HANDLER_POLICY': 'always',
|
||||
'SERVER_NAME': None,
|
||||
'APPLICATION_ROOT': None,
|
||||
'SESSION_COOKIE_NAME': 'session',
|
||||
|
|
|
@ -11,7 +11,24 @@
|
|||
|
||||
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):
|
||||
|
@ -30,16 +47,28 @@ def create_logger(app):
|
|||
return Logger.getEffectiveLevel(x)
|
||||
|
||||
class DebugHandler(StreamHandler):
|
||||
def emit(x, record):
|
||||
StreamHandler.emit(x, record) if app.debug else None
|
||||
def emit(self, record):
|
||||
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)
|
||||
# just in case that was not a new logger, get rid of all the handlers
|
||||
# already attached to it.
|
||||
del logger.handlers[:]
|
||||
logger.__class__ = DebugLogger
|
||||
logger.addHandler(handler)
|
||||
logger.addHandler(debug_handler)
|
||||
logger.addHandler(prod_handler)
|
||||
return logger
|
||||
|
|
|
@ -559,6 +559,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
|||
def test_teardown_request_handler_error(self):
|
||||
called = []
|
||||
app = flask.Flask(__name__)
|
||||
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||
@app.teardown_request
|
||||
def teardown_request1(exc):
|
||||
self.assert_equal(type(exc), ZeroDivisionError)
|
||||
|
@ -621,6 +622,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
|||
|
||||
def test_error_handling(self):
|
||||
app = flask.Flask(__name__)
|
||||
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||
@app.errorhandler(404)
|
||||
def not_found(e):
|
||||
return 'not found', 404
|
||||
|
@ -920,6 +922,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
|||
|
||||
def test_none_response(self):
|
||||
app = flask.Flask(__name__)
|
||||
app.testing = True
|
||||
@app.route('/')
|
||||
def test():
|
||||
return None
|
||||
|
@ -989,6 +992,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
|||
def test_exception_propagation(self):
|
||||
def apprunner(configkey):
|
||||
app = flask.Flask(__name__)
|
||||
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||
@app.route('/')
|
||||
def index():
|
||||
1 // 0
|
||||
|
@ -996,7 +1000,7 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
|||
if config_key is not None:
|
||||
app.config[config_key] = True
|
||||
try:
|
||||
resp = c.get('/')
|
||||
c.get('/')
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
|
|
|
@ -137,6 +137,7 @@ class ModuleTestCase(FlaskTestCase):
|
|||
@emits_module_deprecation_warning
|
||||
def test_error_handling(self):
|
||||
app = flask.Flask(__name__)
|
||||
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||
admin = flask.Module(__name__, 'admin')
|
||||
@admin.app_errorhandler(404)
|
||||
def not_found(e):
|
||||
|
|
|
@ -473,6 +473,7 @@ class LoggingTestCase(FlaskTestCase):
|
|||
def test_exception_logging(self):
|
||||
out = StringIO()
|
||||
app = flask.Flask(__name__)
|
||||
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||
app.logger_name = 'flask_tests/test_exception_logging'
|
||||
app.logger.addHandler(StreamHandler(out))
|
||||
|
||||
|
@ -492,6 +493,7 @@ class LoggingTestCase(FlaskTestCase):
|
|||
|
||||
def test_processor_exceptions(self):
|
||||
app = flask.Flask(__name__)
|
||||
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||
@app.before_request
|
||||
def before_request():
|
||||
if trigger == 'before':
|
||||
|
|
|
@ -136,6 +136,7 @@ class TestToolsTestCase(FlaskTestCase):
|
|||
|
||||
def test_test_client_context_binding(self):
|
||||
app = flask.Flask(__name__)
|
||||
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||
@app.route('/')
|
||||
def index():
|
||||
flask.g.value = 42
|
||||
|
|
Loading…
Reference in New Issue