From 79562c63b9f327b85ed2f345daf9c27762623355 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 13 Sep 2010 08:01:27 +0200 Subject: [PATCH] Some documentation updates --- docs/logging.rst | 126 +++++++++++++++++++++++++++++++++++++++++++++++ flask/app.py | 4 +- 2 files changed, 128 insertions(+), 2 deletions(-) diff --git a/docs/logging.rst b/docs/logging.rst index 46b2178f37..23ea2a1244 100644 --- a/docs/logging.rst +++ b/docs/logging.rst @@ -56,4 +56,130 @@ This document only specifies a logbook setup. If you are interested in the documentation for the old logging system, have a look at :ref:`old-logging`. +Making the Switch +----------------- + +The default configuration of Logbook is fine and Flask even adds a small +little improvement on top of that. However you currently have to opt-in +for Logbook support:: + + from flask import Flask + app = Flask(__name__, logging_system='logbook') + +The other options for the logging system are: + +``'logging'`` + Deprecated support for logging to the logging system. + +``'logbook'`` + Logging to `Logbook`_, requires that the library is installed. + +``'none'`` + Configure a dummy logger for internal usage but do not set up a + real logging system. + +In Flask 1.0 the logging system parameter will become a no-op and Logbook +will always be used. In case Logbook is not installed in 1.0 and later, +it will dynamically fall back to the dummy logger which currently is not +the case. + +Logging Messages +---------------- + +If you have used logging before in Flask applications you will have used +the :attr:`~flask.Flask.logger` attribute. While that is nice and you can +continue to use this logger, it is recommended to use a logger for logging +directly. The reason for this is that you have better control over what +you are doing and can shut down a logger completely to reduce runtime +overhead. + +To make the switch, replace calls to this:: + + @app.route('/') + def index(): + app.logger.warn('A message') + ... + +With something like this:: + + from logbook import Logger + logger = Logger('My component') + + @app.route('/') + def index(): + logger.warn('A message') + ... + +Note that Logbook is using Python 2.6's new string formatting feature +instead of the printf style string formatting that was in use by logging:: + + app.logger.warn('Hello %s!', name) + +Becomes this now:: + + app.logger.warn('Hello {0}!', name) + +You can also use named parameters:: + + app.logger.warn('Hello {name}!', name=name) + +Logbook ships with a pure Python implementation of the new string +formatting for Python 2.5 which is why it is recommended to use Python 2.6 +in case you are doing a lot of logging calls that are delivered to +handlers in production. It will of course not affect logging calls that +don't happen because their level is too low (like debug log calls on a +production system that only cares about warnings and higher priority +records). + +Consult the `Logbook documentation`_ for more information. + +Error Mails +----------- + +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 +tries to be a zero-configuration framework. Where should it drop the logs +for you if there is no configuration? Guessing is not a good idea because +chances are, the place it guessed is not the place where the user has +permission to create a logfile. Also, for most small applications nobody +will look at the logs anyways. + +In fact, I promise you right now that if you configure a logfile for the +application errors you will never look at it except for debugging an issue +when a user reported it for you. What you want instead is a mail the +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 +you mails for errors which is probably what you want. Here is how you can +configure the Flask logger to send you mails for exceptions:: + + ADMINS = ['yourname@example.com'] + if not app.debug: + import logging + from logging.handlers import SMTPHandler + mail_handler = SMTPHandler('127.0.0.1', + 'server-error@example.com', + ADMINS, 'YourApplication Failed') + mail_handler.setLevel(logging.ERROR) + app.logger.addHandler(mail_handler) + +So what just happened? We created a new +:class:`~logging.handlers.SMTPHandler` that will send mails with the mail +server listening on ``127.0.0.1`` to all the `ADMINS` from the address +*server-error@example.com* with the subject "YourApplication Failed". If +your mail server requires credentials, these can also be provided. For +that check out the documentation for the +:class:`~logging.handlers.SMTPHandler`. + +We also tell the handler to only send errors and more critical messages. +Because we certainly don't want to get a mail for warnings or other +useless logs that might happen during request handling. + +Before you run that in production, please also look at :ref:`logformat` to +put more information into that error mail. That will save you from a lot +of frustration. + + .. _Logbook: http://logbook.pocoo.org/ +.. _Logbook documentation: http://logbook.pocoo.org/ diff --git a/flask/app.py b/flask/app.py index bb89c848b6..ad05ed87bd 100644 --- a/flask/app.py +++ b/flask/app.py @@ -173,7 +173,7 @@ class Flask(_PackageBoundObject): logger_name = ConfigAttribute('LOGGER_NAME') #: the logbook setup that should be in use. This is only used in case - #: the `LOGGING_SYSTEM` is ``'logbook'``. It can point to any + #: the logging system is ``'logbook'``. It can point to any #: :class:`logbook.Processor`, :class:`logbook.Handler` or #: :class:`logbook.NestedSetup`. In case it's `None`, the default #: application wide setup is used. For further customization you can @@ -321,7 +321,7 @@ def logger(self): app.logger.warning('A warning ocurred (%d apples)', 42) app.logger.error('An error occoured') - In case the `LOGGING_SYSTEM` is ``'logbook'`` it is strongly + In case the logging system is ``'logbook'`` it is strongly recommended against using this logger and create your own. Unlike logging, logbook automatically will handle writing to the :attr:`logbook_setup`.