Journalisation dans les applications JavaScript : meilleures pratiques pour les débutants
La journalisation est la base du débogage et de la surveillance de toute application. Sans journaux de qualité, vous chercherez « une aiguille dans une botte de foin » quand quelque chose tournera mal. Dans cet article, nous allons analyser les meilleures pratiques de journalisation en JavaScript (Node.js), adaptées aussi bien aux petits projets qu'à la production.
1. Pourquoi ne pas se fier à console.log ?
De nombreux développeurs débutants utilisent console.log pour tout. C'est pratique en phase de développement, mais en environnement de production, cette approche entraîne des problèmes :
- Pas de niveaux de journalisation — vous ne pouvez pas filtrer les erreurs des messages d'information.
- Gestion difficile de la sortie — vous ne pouvez pas désactiver les journaux pour certains modules.
- Mauvaise performance — la sérialisation des objets dans
console.logpeut être coûteuse. - Absence de structure — les journaux n'ont pas de format unifié (JSON, horodatage, niveau).
Utilisez plutôt des bibliothèques spécialisées. Voici un exemple simple mais correct utilisant Winston :
// logger.jsconst winston = require('winston');
const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({ filename: 'combined.log' }), ],});
if (process.env.NODE_ENV !== 'production') { logger.add(new winston.transports.Console({ format: winston.format.simple(), }));}
module.exports = logger;2. Niveaux de journalisation : quand utiliser quoi
Les niveaux de journalisation standards (par ordre croissant de gravité) : debug, info, warn, error. Il est important de comprendre quand appliquer chaque niveau :
- debug — informations détaillées pour les développeurs (valeurs des variables, état du système). Désactivé en production.
- info — événements normaux du fonctionnement de l'application (requête traitée, utilisateur enregistré).
- warn — situations potentiellement dangereuses (faible mémoire disponible, API obsolète).
- error — erreurs nécessitant une intervention (exceptions, pannes de base de données).
Exemple d'utilisation correcte avec la bibliothèque Pino (la plus rapide pour Node.js) :
const pino = require('pino');
const logger = pino({ level: process.env.LOG_LEVEL || 'info', transport: { target: 'pino-pretty', options: { colorize: true } }});
// Utilisationlogger.info({ userId: 123 }, 'Utilisateur connecté');logger.error(new Error('Erreur de connexion à la base de données'), 'Erreur critique');logger.debug('Valeur de la variable x = 42'); // ne s'affichera pas si level = 'info'3. Journalisation structurée : JSON et contexte
Au lieu de chaînes de texte, utilisez des journaux structurés (généralement JSON). Cela permet :
- D'analyser facilement les journaux avec des outils (ELK, Graylog).
- D'ajouter du contexte (ID de requête, utilisateur, version).
- De filtrer et d'agréger les données.
Exemple de journal structuré avec contexte :
const logger = require('./logger');
app.use((req, res, next) => { req.requestId = uuidv4(); next();});
app.get('/api/users', async (req, res) => { logger.info({ requestId: req.requestId, method: req.method, url: req.originalUrl, ip: req.ip }, 'Requête entrante');
try { const users = await getUsers(); logger.info({ requestId: req.requestId, count: users.length }, 'Utilisateurs récupérés'); res.json(users); } catch (err) { logger.error({