Browse Source

Updated the logging documentation for recent changes.

pull/1161/head
Armin Ronacher 10 years ago
parent
commit
7c16054d81
  1. 29
      docs/errorhandling.rst
  2. 24
      flask/logging.py

29
docs/errorhandling.rst

@ -32,18 +32,16 @@ Error Mails
----------- -----------
If the application runs in production mode (which it will do on your If the application runs in production mode (which it will do on your
server) you won't see any log messages by default. Why is that? Flask server) you might not see any log messages. The reason for that is that
tries to be a zero-configuration framework. Where should it drop the logs Flask by default will just report to the WSGI error stream or stderr
for you if there is no configuration? Guessing is not a good idea because (depending on what's available). Where this ends up is sometimes hard to
chances are, the place it guessed is not the place where the user has find. Often it's in your webserver's log files.
permission to create a logfile. Also, for most small applications nobody
will look at the logs anyways. I can pretty much promise you however that if you only use a logfile for
the application errors you will never look at it except for debugging an
In fact, I promise you right now that if you configure a logfile for the issue when a user reported it for you. What you probably want instead is
application errors you will never look at it except for debugging an issue a mail the second the exception happened. Then you get an alert and you
when a user reported it for you. What you want instead is a mail the can do something about it.
second the exception happened. Then you get an alert and you can do
something about it.
Flask uses the Python builtin logging system, and it can actually send Flask uses the Python builtin logging system, and it can actually send
you mails for errors which is probably what you want. Here is how you can you mails for errors which is probably what you want. Here is how you can
@ -81,9 +79,10 @@ Logging to a File
Even if you get mails, you probably also want to log warnings. It's a Even if you get mails, you probably also want to log warnings. It's a
good idea to keep as much information around that might be required to good idea to keep as much information around that might be required to
debug a problem. Please note that Flask itself will not issue any debug a problem. By default as of Flask 1.0, errors are logged to your
warnings in the core system, so it's your responsibility to warn in the webserver's log automatically. Warnings however are not. Please note
code if something seems odd. that Flask itself will not issue any warnings in the core system, so it's
your responsibility to warn in the code if something seems odd.
There are a couple of handlers provided by the logging system out of the There are a couple of handlers provided by the logging system out of the
box but not all of them are useful for basic error logging. The most box but not all of them are useful for basic error logging. The most

24
flask/logging.py

@ -11,8 +11,12 @@
from __future__ import absolute_import from __future__ import absolute_import
import sys
from werkzeug.local import LocalProxy
from logging import getLogger, StreamHandler, Formatter, getLoggerClass, \ from logging import getLogger, StreamHandler, Formatter, getLoggerClass, \
DEBUG, ERROR DEBUG, ERROR
from .globals import _request_ctx_stack
PROD_LOG_FORMAT = '[%(asctime)s] %(levelname)s in %(module)s: %(message)s' PROD_LOG_FORMAT = '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
@ -24,7 +28,19 @@ DEBUG_LOG_FORMAT = (
) )
def should_log_for(app, mode): @LocalProxy
def _proxy_stream():
"""Finds the most appropriate error stream for the application. If a
WSGI request is in flight we log to wsgi.errors, otherwise this resolves
to sys.stderr.
"""
ctx = _request_ctx_stack.top
if ctx is not None:
return ctx.request.environ['wsgi.errors']
return sys.stderr
def _should_log_for(app, mode):
policy = app.config['LOGGER_HANDLER_POLICY'] policy = app.config['LOGGER_HANDLER_POLICY']
if policy == mode or policy == 'always': if policy == mode or policy == 'always':
return True return True
@ -48,19 +64,19 @@ def create_logger(app):
class DebugHandler(StreamHandler): class DebugHandler(StreamHandler):
def emit(self, record): def emit(self, record):
if app.debug and should_log_for(app, 'debug'): if app.debug and _should_log_for(app, 'debug'):
StreamHandler.emit(self, record) StreamHandler.emit(self, record)
class ProductionHandler(StreamHandler): class ProductionHandler(StreamHandler):
def emit(self, record): def emit(self, record):
if not app.debug and should_log_for(app, 'production'): if not app.debug and _should_log_for(app, 'production'):
StreamHandler.emit(self, record) StreamHandler.emit(self, record)
debug_handler = DebugHandler() debug_handler = DebugHandler()
debug_handler.setLevel(DEBUG) debug_handler.setLevel(DEBUG)
debug_handler.setFormatter(Formatter(DEBUG_LOG_FORMAT)) debug_handler.setFormatter(Formatter(DEBUG_LOG_FORMAT))
prod_handler = ProductionHandler() prod_handler = ProductionHandler(_proxy_stream)
prod_handler.setLevel(ERROR) prod_handler.setLevel(ERROR)
prod_handler.setFormatter(Formatter(PROD_LOG_FORMAT)) prod_handler.setFormatter(Formatter(PROD_LOG_FORMAT))

Loading…
Cancel
Save