Manuel:Journalisation structurée

From mediawiki.org
This page is a translated version of the page Manual:Structured logging and the translation is 100% complete.
Version de MediaWiki :
1.25

La journalisation structurée est l'enregistrement opérationnel (debogage) dans le journal, des données structurées pour faciliter ensuite un post traitement. C'est différent de Enregistrer dans Special:Log qui est la journalisation pour le bénéfice des contributeurs au wiki; la journalisation structurée s'adresse aux développeurs.

Depuis MediaWiki 1.25, le standard de connexion PSR-3 est utilisable par le noyau MediaWiki et les extensions pour remplacer les appels de débogage wfDebug et wfDebugLog. La norme PSR-3 permet de joindre un tableau de données contextuelles à chaque message de journal pour fournir des paires clé-valeur structurées.

Obtenir un journal à partir de LoggerFactory

use MediaWiki\Logger\LoggerFactory;

$logger = LoggerFactory::getInstance( 'MyCoolLoggingChannel' );

Le paramètre passé à LoggerFactory::getInstance (ici MyCoolLoggingChannel) est le nom du canal de journalisation. La manière dont le nom de canal est utilisé dépend de la configuration de la journalisation (voir ci-dessous) mais typiquement des canaux de journalisation séparés peuvent être dirigés vers des fichiers séparés ou leurs équivalents. Vous devez utiliser quelque chose d'unique (comme le nom de votre extension) pour le nom du canal afin de pouvoir distinguer les entrées du journal qui n'ont pas de rapport.

Envoyer des messages au journal

Une fois que vous disposez d'un objet de journalisation, vous pouvez utiliser ses méthodes associées aux niveaux de sévérité PSR-3 pour tracer les messages :

$logger->debug( 'Entered ' . __METHOD__ )
Ce sont des messages qui sont utiles pour le développement local et sont généralement trop perturbants pour sortir sur un wiki de production. Cela inclurait généralement tout ce qui est actuellement enregistré via wfDebug.
$logger->info( 'Restoring page' )
Informations de modification d'état précieuses. Ce niveau permet d'enregistrer des informations qui seraient utiles dans un environnement de production pour tracer le chemin d'une demande qui a finalement rencontré une erreur. Il s'agit actuellement du niveau automatiquement associé aux appels wfDebugLog lorsqu'il est mappé à PSR-3.
$logger->warning( 'Page is protected' )
Condition d'erreur logicielle, telle qu'une erreur récupérable ou une autre condition qui ne doit généralement pas être vue mais qui ne s'interrompt pas pour l'opération en cours.
$logger->error( 'Page not found' )
Erreur sévère, telle qu'une exception interceptée sans chemin de récupération.

La norme PSR-3 inclut d'autres niveaux de gravité, mais ils ne sont pas recommandés pour une utilisation dans MediaWiki.

Ajouter des données structurées au contexte de journalisation

Toutes les méthodes de journalisation utilisent un tableau facultatif de contexte, par exemple :

$logger->warning( 'page not found', [ 'user' => $user->getName(), 'title' => $page->getPrefixedText() ] );

Vous devez ajouter des informations structurées utiles à vos messages de journalisation dans cet objet de contexte que d'autres pourront utiliser pour rechercher les messages associés ou les enregistrements associés dans la base de données et remonter à la cause de l'erreur. Ceci est particulièrement important et utile pour les messages de niveau avertissement et erreur où l'opérateur du wiki ne connaît peut-être pas le chemin du code et doit être capable de produire un bon rapport de bogue.

  • Si vous passez un objet Exception dans le paramètre de contexte, il DOIT être dans la clé 'exception' (par ex. $logger->error( 'got exception', [ 'exception' => $e ] )) [1]
    • Vous pouvez également générer un objet d'exception à la volée, ce qui est un bon moyen pour attacher la trace de la pile par exemple lors de l'enregistrement d'une erreur dans une fonction d'utilitaire qui est appelée de plusieurs endroits : $logger->warning( 'called with a user which does not exist', [ 'user' => $user->getName(), 'exception' => new RuntimeException() ] )
  • Joindre les paramètres ou tout autre état intéressant aux messages. Il est bon de vérifier que les éléments du tableau du contexte sont bien des chaînes de caractères. (vous pouvez utiliser tout autre type en fonction du service de journalisation utilisé par le wiki, mais le comportement pour des valeurs qui ne sont pas des chaînes est souvent contre-intuitif). Plusieurs classes du noyau MediaWiki possèdent une méthode __toString qui génère la description des objets dans un format utile au débogage afin de n'avoir à utiliser que des éléments du type (string)$titleValue.
    • Si vous tenez à passer des valeurs qui ne soient pas des chaînes de caractères, essayez d'utiliser raisonnablement des noms de champs uniques. Ceci est essentiellement nécessaire pour la production de Wikimedia qui envoie les données de contexte à Logstash, qui exige que toutes les données de contexte utilisant la même clé soient du même type (globales sur tous les canaux de journaux).
  • Les paramètres standard (nom du wiki, nom du serveur, etc.) seront ajoutés automatiquement. Les détails dépendent du service de journalisation que vous utilisez, mais vous utiliserez probablement MediaWiki\Logger\Monolog\WikiProcessor.
  • Remplacez les fausses structures telles que les éléments séparés par des tabulations, les paires étiquette=valeur/étiquette : valeur ou la sérialisation json.

De nombreux agrégateurs de journaux essaient de supprimer les doublons dans les journaux, alors essayez de garder les détails modifiables hors du message et placez-les dans le contexte. Le logger remplacera tous les jetons à l'intérieur des accolades par la valeur correspondante du contexte. Par exemple, le code

$logger->error( 'Caught exception while trying to create user {user}: {exception}', [
    'user' => $user->getName(),
    'exception' => $e,
] );

aboutira à quelque chose comme :

Caught exception while trying to create user Foo: exception DatabaseException with message 'Unique constraint violation' in /srv/mediawiki/includes/Database.php:123
#0 /srv/mediawiki/includes/Database.php(456): Database::query()
...

Pour une compatibilité maximale avec les différents serveurs de journalisation, n'utilisez pas ces clés dans vos données de contexte :

  • message
  • channel
  • host
  • level
  • type
  • @timestamp
  • @version

Utiliser des objets compatibles PSR-3

Générez des exceptions qui implémentent INormalizedException (ou, si vous n'avez pas besoin d'une classe d'exception personnalisée, utilisez NormalizedException) afin que les messages d'exceptions connexes puissent être groupés ensemble dans les journaux.

Vous pouvez convertir les objets Status et StatusValue dans la journalisation PSR-3 avec :

$statusFormatter = MediaWikiServices::getInstance()->getFormatterFactory()->getStatusFormatter( RequestContext::getMain() );
[ $message, $context ] = $statusFormatter->getPsr3MessageAndContext( $status );
$logger->error( $message, $context );

Ceci est le meilleur effort - l'objet Status a une structure interne désordonnée donc parfois cela finira par quelque chose comme [ '{message}', 'message' => '...the error message in the Status object' ]. Mais pour les statuts contenant un seul message, il traduit de belles chaînes de messages qui sont faciles à regrouper.

Configuration de votre wiki pour la journalisation structurée

Avertissement Avertissement : L'implémentation de l'ancienne journalisation par défaut dans MediaWiki "supprime" la plupart des informations de contexte !

Pour la compatibilité ascendante, si vous utilisez la configuration par défaut de MediaWiki en ayant configuré la journalisation de base et que vous fournissiez un objet de contexte à ces méthodes de journalisation ou aux fonctions globales de MediaWiki telles que wfDebugLog( 'myChannel', $someMessage, 'private', $someContext ), les informations de l'objet de contexte n'apparaissent pas dans les fichiers journaux que vous avez configurés. Vous devez implémenter un meilleur outil de journalisation, tel que monolog, en tant qu'interface de fournisseur de services d'enregistrement. Voir $wgMWLoggerDefaultSpi et Manual:MonologSpi .

Voir aussi