9.Créer un fichier de logs/traces

9.3.Loguer des messages avec Monolog

9.3.1.Introduction

Nous vous avons présenté dans un chapitre précédent le standard PSR-3 visant à harmoniser l'interface des différentes implémentations de Logger. Monolog ayant été écrit avant cette "norme", il n'a pas été conçu pour y répondre mais s'est adapté pour pouvoir être utilisé en tant qu'implémentation PSR-3. Et c'est essentiellement ceci que nous allons mettre en oeuvre dans ce chapitre.

9.3.2.Installation

Nous supposons que vous êtes familier avec composer[c'est quoi?] et que vous ne réalisez plus de projet sans y avoir recours.
Pour pouvoir utiliser monolog vous devez ajouter une ligne du type "monolog/monolog": "^1.0" dans votre fichier composer.json. Ce qui peut se faire en lançant (depuis le dossier racine de votre projet) la commande > composer require monolog/monolog.

9.3.3.Instanciation

La classe à instancier s'appelle Monolog\Logger (et elle implémente bien Psr\Log\LoggerInterface du standard PSR-3). L'instanciation doit se faire en passant obligatoirement un paramètre: une chaîne de caractères identifiant le loguer (un identifiant de canal qui, par défaut, viendra s'ajouter au message logué).
<?php
use Monolog\Logger;

$logger = new Logger('monLoggerA');

9.3.4.Ajout des flux de sortie

Pour ajouter un flux de sortie, il faut faire appel à la méthode pushHandler() à laquelle on passe un objet implémentant Monolog\Handler\HandlerInterface parmi lesquels nous trouvons notamment:
  • Monolog\Handler\StreamHandler pour stocker le message dans un fichier (ou le renvoyer dans la sortie standard si l'on précise 'php://stdout' comme nom de fichier)
Les handlers permettent également de filtrer les messages pour ne laisser passer que les messages ayant au minimum une certaine criticité. Dans le cas de StreamHandler c'est le second paramètre du constructeur qui permet de définir le niveau voulu.
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('monLoggerA');
$logger->pushHandler(new StreamHandler('/tmp/monfichier.log', Logger::WARNING));

9.3.5.Log

L'utilisation proprement dite, quant à elle, est conforme à ce qui est décrit dans la PSR-3[c'est quoi?] avec des méthodes comme debug(), error(), warning(), etc.
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('monLoggerA');
$logger->pushHandler(new StreamHandler('/tmp/monfichier.log', Logger::WARNING));

$logger->debug('Ce message ne sera pas stocké dans le fichier car debug');
$logger->warning('Ce message sera stocké dans le fichier');
$logger->error('Celui-ci aussi');
On aura alors dans le fichier
[2018-05-10 21:41:16] monLoggerA.WARNING: Ce message sera stocké dans le fichier [] []
[2018-05-10 21:41:16] monLoggerA.ERROR: Celui-ci aussi [] []
Il s'agit là du comportement par défaut mais la chaîne de sortie peut être reformattée. En l'occurrence nous avons la date, le nom du canal, le niveau d'alerte, le message, les données de contexte (ici, un tableau vide) et des données en "extra" (ici, un tableau vide également).

9.3.6.Contexte et substitution de mots clés

Nous avons vu que la PSR-3 invite (sans l'imposer) les implémentations à proposer un système de substitution de mots clés dans les messages: Substitution réalisées sur la base d'informations complémentaires passées en second paramètre des méthodes de log. Par défaut, cette substitution n'est pas réalisée par l'implémentation de Monolog. Pour qu'elle soit active, il faut déclarer le "processeur" Monolog\Processor\PsrLogMessageProcessor via la méthode pushProcessor comme suit:
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Processor\PsrLogMessageProcessor;

$logger = new Logger('monLoggerA');
$logger->pushHandler(new StreamHandler('/tmp/monfichier.log', Logger::WARNING));
$logger->pushProcessor(new PsrLogMessageProcessor());

$logger->error('C\'est {utilisateur} qui a tout cassé', ['utilisateur' => 'Pierre']);
Ce qui pourra donner
[2018-05-16 21:58:02] monLoggerA.ERROR: C'est Pierre qui a tout cassé {"utilisateur":"Pierre"} []
On notera que même s'il y a eu substitution, toutes les données du contexte apparaîssent dans le message logué. A noter, le contexte peut contenir plus d'informations que celles effectivement utilisées à des fins de substitution.