Stocker les logs de votre application Flask en base de données avec SQLAlchemy
Vous désirez stocker les logs de votre application dans votre base de données plutôt qu'afficher les erreurs dans la console ou dans un fichier ? Voici un petit récapitulatif des actions à effectuer pour arriver à votre but.
Nous utiliserons une application Flask avec l'extension Flask-SQLAlchemy dans cet exemple.
Création de notre application
Créons dans un premier temps notre application et initialisons notre extension afin de les utiliser par la suite.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) # notre application
# nous utilisons dans cet exemple une base de données sqlite
# vous devez adapter cette ligne selon votre base de données
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////tmp/test.db"
db = SQLAlchemy(app=app) # notre extension
with app.app_context():
db.create_all() # création des tables
Définition du modèle de base de données
from sqlalchemy.sql import func
from myapp.app import db
class LogModel(db.Model):
"""Notre modèle de base de données pour stocker les logs."""
id = db.Column(db.Integer, primary_key=True)
level = db.Column(db.Integer, nullable=False)
msg = db.Column(db.String, nullable=False)
created_at = db.Column(db.DateTime, default=func.now())
Rien de révolutionnaire ici, nous avons juste créé une nouvelle table grâce à SQLAlchemy pour y stocker nos logs. Vous pouvez y retrouver les champs classiques d'un log :
level
→ Le LogLevel de notre entréemsg
→ Le message de notre entréecreated_at
→ La date de création de l'entrée
Ajouter un handler aux logs de notre application
Les applications Flask disposent d'un logger
global lié à l'instance app
que nous avons créée précédemment, il est accessible via l'attribut app.logger
. Il s'agit d'un objet logging.Logger dont le comportement peut être modifié grâce à des Formatters ou des Handlers.
La configuration par défaut d'une application Flask lie notre objet app.logger
à un StreamHandler qui écrira les logs de l'application généralement dans sys.stderr
.
Implémentons un handler nommé SQLAlchemyHandler
qui se chargera de stocker nos logs dans notre base de données.
import logging
from myapp.log import LogModel
class SQLAlchemyHandler(logging.Handler):
"""Ajouter les logs de l'application dans la table log."""
def emit(self, record: logging.LogRecord):
log = LogModel(
level=record.levelno,
msg=record.msg,
)
db.session.add(log)
db.session.commit()
Plutôt facile non ? Nous récupérons l'objet LogRecord
pour initialiser une instance du modèle que nous avons défini et l'ajouter à notre session.
Ajoutons maintenant notre handler à notre application en modifiant notre premier fichier Python.
import logging
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from myapp.handler import SQLAlchemyHandler
app = Flask(__name__) # notre application
# nous utilisons dans cet exemple une base de données sqlite
# vous devez adapter cette ligne selon votre base de données
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////tmp/test.db"
db = SQLAlchemy(app=app) # notre extension
with app.app_context():
db.create_all() # création des tables
handler = SQLAlchemyHandler()
handler.setLevel(logging.NOTSET) # définissez votre niveau de log
app.logger.addHandler(handler)
Dorénavant chaque log de notre application sera également stocké en base de données dans notre table log
.