Lors d’un projet de refonte pour un client du secteur de la logistique, l’équipe a hésité longuement entre deux options pour journaliser les événements internes d’une extension de suivi de colis : intégrer Monolog, bibliothèque de référence dans l’écosystème PHP, ou écrire un wrapper minimal autour de la fonction native error_log(). Le débat mérite d’être posé sérieusement, car les deux choix ont des implications différentes selon la taille réelle de l’extension.
Ce comparatif s’appuie sur l’expérience concrète de ce projet, où les deux approches ont finalement été testées sur des modules différents de la même extension, avant qu’un choix définitif ne soit tranché pour l’ensemble.
Ce que Monolog apporte réellement
Monolog structure la journalisation autour d’une hiérarchie de niveaux normalisée par la norme PSR-3 : debug, info, notice, warning, error, critical, alert, emergency. Chaque niveau peut être routé vers un ou plusieurs handlers différents : fichier local, envoi vers un service externe, ou base de données, sans changer une ligne du code appelant.
use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\SlackWebhookHandler;
$logger = new Logger( 'suivi_colis' );
$logger->pushHandler( new RotatingFileHandler( WP_CONTENT_DIR . '/logs/suivi-colis.log', 14 ) );
$logger->pushHandler( new SlackWebhookHandler( 'https://hooks.slack.com/...', '#alertes-prod', null, true, null, false, false, Logger::CRITICAL ) );
$logger->warning( 'Colis introuvable chez le transporteur', array( 'colis_id' => 4821 ) );
Cette richesse a un prix concret : l’installation de Monolog via Composer entraîne, selon la version, jusqu’à six dépendances transitives supplémentaires, dont psr/log, nécessaires à son fonctionnement. Sur une extension WordPress classique, ces dépendances doivent être préfixées ou isolées, sous peine d’entrer en collision avec une autre extension du même site qui embarquerait elle aussi Monolog dans une version différente.
Ce qu’un wrapper maison couvre suffisamment
Pour la majorité des extensions d’agence que nous livrons, le besoin réel se limite à quelques niveaux de sévérité, un fichier de sortie unique, et une rotation simple par date. Un wrapper d’une soixantaine de lignes couvre ce périmètre sans dépendance externe :

class Suivi_Colis_Logger {
private static $chemin;
public static function init() {
self::$chemin = WP_CONTENT_DIR . '/logs/suivi-colis-' . gmdate( 'Y-m-d' ) . '.log';
}
public static function log( string $niveau, string $message, array $contexte = array() ) {
$ligne = sprintf(
'[%s] %s: %s %s' . PHP_EOL,
gmdate( 'Y-m-d H:i:s' ),
strtoupper( $niveau ),
$message,
$contexte ? wp_json_encode( $contexte ) : ''
);
error_log( $ligne, 3, self::$chemin );
}
public static function warning( string $message, array $contexte = array() ) {
self::log( 'warning', $message, $contexte );
}
}
Ce wrapper ne gère ni handlers multiples ni formatage avancé, mais il répond au besoin réel observé sur la grande majorité de nos extensions : consulter un fichier de log lisible en cas d’incident, sans configuration supplémentaire, sans dépendance à surveiller, sans conflit de version possible avec une autre extension du même site.
Le comparatif chiffré
| Critère | Monolog | Wrapper maison |
|---|---|---|
| Dépendances installées | 6 paquets Composer environ | Aucune |
| Multi-destinations (fichier, Slack, etc.) | Natif via handlers | À coder manuellement |
| Risque de collision entre extensions | Réel sans préfixage (PHP-Scoper) | Inexistant |
| Temps d’intégration initial | Une demi-journée avec préfixage inclus | Moins d’une heure |
Le vrai point de bascule
Sur le projet de suivi de colis, le module qui envoyait des alertes vers Slack en cas d’échec de synchronisation avec un transporteur a fini par adopter Monolog, précisément parce que ce besoin de handlers multiples existait réellement et n’aurait demandé, en wrapper maison, qu’une réécriture partielle de Monolog en moins soigné. Le module de journalisation interne, plus simple, lui, est resté sur le wrapper maison, sans perte fonctionnelle constatée.
- Un seul niveau de sévérité utile et un seul fichier de sortie : le wrapper maison suffit et évite toute dépendance.
- Plusieurs destinations distinctes selon la sévérité, ou un besoin de formats structurés type JSON pour un outil d’analyse externe : Monolog devient pertinent.
- Quoi qu’il arrive, isoler les dépendances Composer d’une extension distribuée à des tiers, pour éviter tout conflit de version avec une autre extension du même site.
Un repère qui a évité bien des débats internes sur ce sujet : si la liste des handlers nécessaires tient sur les doigts d’une main et ne dépasse pas un fichier local, mieux vaut économiser la dépendance que l’introduire par principe.
En résumé
Monolog reste un excellent choix technique, mais son adoption devrait répondre à un besoin réellement constaté de multi-destinations ou de format structuré avancé, pas à un réflexe de bibliothèque reconnue. Pour la majorité des extensions d’agence à la journalisation simple, un wrapper maison correctement pensé couvre le besoin sans alourdir la chaîne de dépendances ni exposer le projet à des conflits de version avec d’autres extensions du même site.