Documentation

Log

Présentation

Il est absolument nécessaire de pouvoir suivre l'exécution du code d'une application. Pendant le développement, ou quand on doit faire du débuggage, on veut savoir quelles sont les fonctions qui sont exécutées et dans quel ordre. Pour une application en production, on veut tracer toutes les erreurs, pour pouvoir les traiter spécifiquement.

Temma offre un mécanisme de logging basé sur l'objet \Temma\Base\Log.

Log simple

La manière la plus simple d'écrire un message de log est d'appeler la méthode statique l(), en lui donnant en paramètre le message à écrire dans le fichier de log. Le message peut soit être une chaîne de caractères (qui sera affichée telle quelle), ou bien n'importe quelle donnée PHP (qui sera alors sérialisée avec la fonction print_r).

Voici quelques exemples :

use \Temma\Base\Log as TµLog;

TµLog::l("Message qui sera écrit systématiquement");
TµLog::l(['zone' => 'internal', 'idx' => 3]);
  • Ligne 1 : On crée un alias pour faciliter l'appel à l'objet de log.
  • Ligne 3 : Le message textuel apparaîtra forcément dans le fichier de log.
  • Ligne 4 : Les données fournies en paramètre seront aussi forcément écrites dans le fichier de log, après avoir été converties dans une représentation textuelle.

Log avancé

Pour l'utiliser, il suffit d'appeler la méthode statique log(), en lui fournissant 3 paramètres (les deux premiers sont optionnels) :

  • Une classe de log, c'est-à-dire un label qui permettra au système de connaître le seuil de criticité au-delà duquel le message apparaîtra.
  • Un niveau de criticité, sous forme de chaîne de caractères courte, qui sert à indiquer s'il s'agit d'un simple message de débuggage, ou d'une information remontant une erreur critique.
  • Le texte du message de log. Cela peut être une chaîne de caractère (qui sera affichée telle quelle), ou bien n'importe quelle donnée PHP (qui sera alors sérialisée avec la fonction print_r).

Voici la liste des niveaux de criticités gérés par \Temma\Base\Log :

  • DEBUG : message de débuggage (criticité la plus faible)
  • INFO : message d'information (niveau par défaut des messages dont la criticité n'est pas précisée)
  • NOTE : notification ; message normal mais significatif (seuil par défaut)
  • WARN : message d'alerte ; l'application ne fonctionne pas normalement mais elle peut continuer à fonctionner
  • ERROR : message d'erreur ; l'application ne fonctionne pas normalement et elle doit s'arrêter
  • CRIT : message d'erreur critique ; l'application risque d'endommager son environnement (criticité la plus élevée)

Pour qu'un message soit écrit dans le fichier de log, il faut que son niveau de criticité soit supérieur ou égale au seuil prévu pour sa classe de log. Les classes de logs sont définies dans le fichiers de configuration temma.json (voir Configuration).
Un message de log dont le niveau de criticité n'est pas défini est vu comme un message d'information (INFO).
Si la classe d'un message n'est pas définie, on lui affecte une classe par défaut, dont le seuil d'apparition est NOTE.

Voici quelques exemples :

use \Temma\Base\Log as TµLog;

TµLog::log("Message de log utilisant les seuils par défaut.");
TµLog::log('NOTE', "Notice liée à la classe par défaut.");
TµLog::log('myapp', 'DEBUG', "Ceci est un message de débug.");
TµLog::log('data', 'INFO', ['zone' => 'internal', 'idx' => 3]);
  • Ligne 1 : On crée un alias pour faciliter l'appel à l'objet de log.
  • Ligne 3 : Ce message a une criticité par défaut (INFO), et une classe par défaut (default, dont le seuil est NOTE). La criticité étant moins importante que le seuil, le message n'apparaîtra pas.
  • Ligne 4 : Ce message a la criticité NOTE, et une classe par défaut (default, dont le seuil est NOTE). La criticité étant égale au seuil, le message apparaîtra.
  • Ligne 5 : Ce message a la criticité DEBUG (la moins importante), et la classe myapp. Si le seuil de cette classe est défini à DEBUG, le message apparaîtra.
  • Ligne 6 : Ce message a la criticité INFO, et la classe data. Si le seuil de cette classe est défini à INFO ou à DEBUG, le message apparaîtra. Le message étant un tableau associatif, le message de log le fera apparaître après conversion en texte.

Gestionnaire de log

Dans le fichier de configuration temma.json, la directive logManager permet de définir un objet (ou plusieurs) qui va prendre en charge les logs générés par l'application.
Cela peut être utile si vos logs doivent être envoyés sur un serveur centralisé (Graylog, LogStash, Fluentd, rsyslog, syslog-ng, Nagios, ELK, Datadog…), et pas uniquement − ou à la place de − de l'écriture dans un fichier.

Un gestionnaire de log est un objet qui implémente l'interface \Temma\Web\LogManager. Il doit contenir une méthode statique log(), qui sera appelée à chaque nouveau message de log, en recevant trois paramètres :

  1. Le texte du message de log.
  2. La priorité du message (DEBUG, NOTE, INFO, …). Peut être nul.
  3. La "classe de log" du message. Peut être nul.

Exemple :

/** Gestionnaire de log qui envoie les message vers un serveur Syslog. */
class SyslogManager implements \Temma\Web\LogManager {
    /**
     * Envoi les logs applicatifs vers le serveur Syslog du système local.
     * @param  string   $text      Texte du message.
     * @param  ?string  $priority  Priorité du message.
     * @param  ?string  $class     Classe de log du message.
     */
    static public function log(string $text, ?string $priority, ?string $class) {
        // tableau de correspondance de priorités syslog
        $prioMapping = [
            'DEBUG' => LOG_DEBUG,
            'INFO'  => LOG_INFO,
            'NOTE'  => LOG_NOTICE,
            'WARN'  => LOG_WARNING,
            'ERROR' => LOG_ERR,
            'CRIT'  => LOG_CRIT,
        ];
        // envoi vers syslog
        $prio = $prioMapping[$priority] ?? LOG_NOTICE;
        syslog($prio, "$class $text");
    }
}

Dans cet exemple, le gestionnaire de log envoie tous les messages de log vers le serveur Syslog du système local. Les chaînes de priorité (DEBUG, INFO…) sont converties en valeurs utilisables par la fonction PHP syslog() (LOG_DEBUG, LOG_INFO, …).

Si la méthode statique log() ne retourne rien (ou retourne null), le système passera au gestionnaire de log suivant (dans le cas où une liste de gestionnaires avait été configurée) ou enfin à l'écriture dans le fichier temma.log (sauf si la directive logFile a été utilisée de manière à désactiver l'écriture dans le fichier).

Si la méthode retourne la valeur booléenne false, le système de log s'arrêtera : les gestionnaires suivants ne seront pas exécutés, et le message ne sera pas écrit dans le fichier temma.log.

Enfin, la méthode peut retourner un tableau associatif, contenant une ou plusieurs des clés suivantes :

  • logPath : Pour changer le chemin d'écriture du fichier de log. Ce doit être un chemin absolu.
  • logToStdOut : Mis à true, les messages de log seront écrits sur la sortie standard (et se retrouveront donc dans le flux de sortie du framework).
  • logToStdErr : Mis à true, les messages de log seront écrits sur la sortie d'erreur (et se retrouveront dans le fichier de log du serveur HTTP).
Précédent : Routage
Suivant : Contrôleurs

Table des matières