Registro

Flask utiliza el estándar de Python logging. Los mensajes sobre tu aplicación Flask se registran con app.logger, que toma el mismo nombre que app.name. Este registrador también se puede utilizar para registrar sus propios mensajes.

@app.route('/login', methods=['POST'])
def login():
    user = get_user(request.form['username'])

    if user.check_password(request.form['password']):
        login_user(user)
        app.logger.info('%s logged in successfully', user.username)
        return redirect(url_for('index'))
    else:
        app.logger.info('%s failed to log in', user.username)
        abort(401)

Si no configuras el registro, el nivel de registro por defecto de Python suele ser “warning”. Nada por debajo del nivel configurado será visible.

Configuración básica

Cuando quieras configurar el logging para tu proyecto, debes hacerlo lo antes posible al iniciar el programa. Si se accede a app.logger antes de configurar el registro, se añadirá un manejador por defecto. Si es posible, configure el registro antes de crear el objeto de la aplicación.

Este ejemplo utiliza dictConfig() para crear una configuración de registro similar a la predeterminada de Flask, excepto para todos los registros:

from logging.config import dictConfig

dictConfig({
    'version': 1,
    'formatters': {'default': {
        'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
    }},
    'handlers': {'wsgi': {
        'class': 'logging.StreamHandler',
        'stream': 'ext://flask.logging.wsgi_errors_stream',
        'formatter': 'default'
    }},
    'root': {
        'level': 'INFO',
        'handlers': ['wsgi']
    }
})

app = Flask(__name__)

Configuración por defecto

Si no configuras el registro tú mismo, Flask añadirá un StreamHandler a app.logger automáticamente. Durante las peticiones, escribirá en el flujo especificado por el servidor WSGI en environ['wsgi.errors'] (que suele ser sys.stderr). Fuera de una petición, se registrará en sys.stderr.

Eliminación del manejador por defecto

Si has configurado el registro después de acceder a app.logger, y necesitas eliminar el manejador por defecto, puedes importarlo y eliminarlo:

from flask.logging import default_handler

app.logger.removeHandler(default_handler)

Errores de correo electrónico a los administradores

Cuando se ejecuta la aplicación en un servidor remoto para producción, probablemente no mirará los mensajes de registro muy a menudo. El servidor WSGI probablemente enviará los mensajes de registro a un archivo, y usted sólo revisará ese archivo si un usuario le dice que algo salió mal.

Para ser proactivo a la hora de descubrir y arreglar errores, puedes configurar un logging.handlers.SMTPHandler para que envíe un correo electrónico cuando se registren errores y superiores

import logging
from logging.handlers import SMTPHandler

mail_handler = SMTPHandler(
    mailhost='127.0.0.1',
    fromaddr='server-error@example.com',
    toaddrs=['admin@example.com'],
    subject='Application Error'
)
mail_handler.setLevel(logging.ERROR)
mail_handler.setFormatter(logging.Formatter(
    '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
))

if not app.debug:
    app.logger.addHandler(mail_handler)

Esto requiere que tengas un servidor SMTP configurado en el mismo servidor. Consulte los documentos de Python para obtener más información sobre la configuración del gestorr.

Solicitud de información sobre inyecciones

Ver más información sobre la solicitud, como la dirección IP, puede ayudar a depurar algunos errores. Puedes subclasificar logging.Formatter para inyectar tus propios campos que pueden ser utilizados en los mensajes. Puedes cambiar el formateador por el manejador por defecto de Flask, el manejador de correo definido arriba, o cualquier otro manejador.

from flask import has_request_context, request
from flask.logging import default_handler

class RequestFormatter(logging.Formatter):
    def format(self, record):
        if has_request_context():
            record.url = request.url
            record.remote_addr = request.remote_addr
        else:
            record.url = None
            record.remote_addr = None

        return super().format(record)

formatter = RequestFormatter(
    '[%(asctime)s] %(remote_addr)s requested %(url)s\n'
    '%(levelname)s in %(module)s: %(message)s'
)
default_handler.setFormatter(formatter)
mail_handler.setFormatter(formatter)

Otras bibliotecas

Otras bibliotecas pueden utilizar el registro extensivamente, y usted quiere ver los mensajes relevantes de esos registros también. La forma más sencilla de hacerlo es añadir manejadores al logger raíz en lugar de sólo al logger de la aplicación.

from flask.logging import default_handler

root = logging.getLogger()
root.addHandler(default_handler)
root.addHandler(mail_handler)

Dependiendo de su proyecto, puede ser más útil configurar cada registrador que le interese por separado, en lugar de configurar sólo el registrador raíz.

for logger in (
    app.logger,
    logging.getLogger('sqlalchemy'),
    logging.getLogger('other_package'),
):
    logger.addHandler(default_handler)
    logger.addHandler(mail_handler)

Werkzeug

Werkzeug registra la información básica de solicitud/respuesta en el logger 'werkzeug'. Si el logger raíz no tiene configurado ningún manejador, Werkzeug añade un StreamHandler a su logger.

Extensiones de Flask

Dependiendo de la situación, una extensión puede elegir registrar en app.logger o en su propio logger con nombre. Consulte la documentación de cada extensión para más detalles.