Yii fournit une puissante base structurée (framework) d'enregistrement des messages qui est très personnalisable et extensible. En utilisant cette base structurée, vous pouvez facilement enregistrer des types variés de messages, les filtrer et les rassembler dans différentes cibles comme les bases de données et les courriels.
L'utilisation de la base structurée d'enregistrement des messages de Yii nécessite de suivre les étapes suivantes :
Dans cette section, nous décrivons principalement les deux premières étapes.
Enregistrer des messages est aussi simple que d'appeler une des méthodes suivantes :
Ces méthodes enregistrent les messages à différents niveaux de sévérité et dans différentes catégories. Elles partagent la même signature function ($message, $category = 'application')
, où $message
représente le message à enregistrer, tandis que $category
est la catégorie de ce message. Le code de l'exemple qui suit enregistre un message de trace dans la catégorie application
:
Yii::debug('start calculating average revenue');
Info : les messages enregistrés peuvent être des chaînes de caractères aussi bien que des données complexes telles que des tableaux ou des objets. Il est de la responsabilité des cibles d'enregistrement de traiter correctement ces messages. Par défaut, si un message enregistré n'est pas un chaîne de caractères, il est exporté comme une chaîne de caractères en appelant la méthode yii\helpers\VarDumper::export().
Pour mieux organiser et filtrer les messages enregistrés, il est recommandé que vous spécifiiez une catégorie appropriée pour chacun des messages. Vous pouvez choisir une schéma de nommage hiérarchisé pour les catégories, ce qui facilitera le filtrage des messages par les cibles d'enregistrement sur la base de ces catégories. Un schéma de nommage simple et efficace est d'utiliser la constante magique __METHOD__
de PHP dans les noms de catégorie. Par exemple :
Yii::debug('start calculating average revenue', __METHOD__);
La constante magique __METHOD__
est évaluée comme le nom de la méthode (préfixée par le nom pleinement qualifié de la classe), là où la constante apparaît. Par exemple, elle est égale à 'app\controllers\RevenueController::calculate'
si la ligne suivante est utilisée dans cette méthode.
Info : les méthodes d'enregistrement décrites plus haut sont en fait des raccourcis pour la méthode log() de l'objet logger qui est un singleton accessible via l'expression
Yii::getLogger()
. Lorsque suffisamment de messages ont été enregistrés, ou quand l'application se termine, l'objet logger appelle un distributeur de messages pour envoyer les messages enregistrés aux cibles d'enregistrement.
Une cible d'enregistrement est une instance de la classe yii\log\Target ou d'une de ses classe filles. Elle filtre les messages enregistrés selon leur degré de sévérité et leur catégorie et les exporte vers un média donné. Par exemple, une cible base données exporte les messages enregistrés et filtrés vers une base de données, tandis qu'une cible courriel exporte les messages vers l'adresse de courriel spécifiée.
Vous pouvez enregistrer plusieurs cibles d'enregistrement dans votre application en les configurant, via le composant d'applicationlog
dans la configuration de l'application, de la manière suivante :
return [
// le composant "log" doit être chargé lors de la période d'amorçage
'bootstrap' => ['log'],
// le composant "log" traite les messages avec un horodatage (timestamp). Définissez le fuseau horaire PHP pour créer l'horodate correcte :
'timeZone' => 'America/Los_Angeles',
'components' => [
'log' => [
'targets' => [
[
'class' => 'yii\log\DbTarget',
'levels' => ['error', 'warning'],
],
[
'class' => 'yii\log\EmailTarget',
'levels' => ['error'],
'categories' => ['yii\db\*'],
'message' => [
'from' => ['log@example.com'],
'to' => ['admin@example.com', 'developer@example.com'],
'subject' => 'Database errors at example.com',
],
],
],
],
],
];
Note : le composant
log
doit être chargé durant le processus d'amorçage afin qu'il puisse distribuer les messages enregistrés aux cibles rapidement. C'est pourquoi il est listé dans le tableaubootstrap
comme nous le montrons ci-dessus.
Dans le code précédent, deux cibles d'enregistrement sont enregistrées dan la propriété yii\log\Dispatcher::$targets :
yii\db\
, et les envoie dans un courriel à la fois à admin@example.com
et à developer@example.com
.Yii est fourni avec les cibles pré-construites suivantes. Reportez-vous à la documentation de l'API pour en savoir plus sur ces classes, en particulier comment les configurer et les utiliser.
syslog()
.Dans la suite de ce document, nous décrivons les fonctionnalités communes à toutes les cibles d'enregistrement.
Vous pouvez configurer les propriétés levels et categories de chacune des cibles d'enregistrement pour spécifier les niveaux de sévérité et les catégories que la cible doit traiter.
La propriété levels accepte un tableau constitué d'une ou plusieurs des valeurs suivantes :
error
: correspondant aux messages enregistrés par Yii::error().warning
: correspondant aux messages enregistrés par Yii::warning().info
: correspondant aux messages enregistrés par Yii::info().trace
: correspondant aux messages enregistrés par Yii::debug().profile
: correspondant aux messages enregistrés par Yii::beginProfile() et Yii::endProfile(), et qui sera expliqué en détails dans la sous-section Profilage de la performance.Si vous ne spécifiez pas la propriété levels, cela signifie que la cible traitera les messages de n'importe quel niveau de sévérité.
La propriété categories accepte un tableau constitué de noms ou de motifs de noms de catégorie de messages. Une cible ne traite
que les messages dont la catégorie est trouvée ou correspond aux motifs de ce tableau. Un motif de nom de catégorie est un préfixe de nom de catégorie
suivi d'une astérisque *
. Un nom de catégorie correspond à un motif de nom de catégorie s'il commence par le préfixe du motif.
Par exemple, yii\db\Command::execute
et yii\db\Command::query
sont utilisés comme noms de catégorie pour les messages enregistrés dans la classe yii\db\Command. Ils correspondent tous deux au motif yii\db\*
.
Si vous ne spécifiez pas la propriété categories, cela signifie que le cible traite les messages de n'importe quelle catégorie.
En plus d'inscrire des catégories en liste blanche via la propriété categories, vous pouvez également inscrire certaines catégories en liste noire via la propriété except. Si la catégorie d'un message est trouvée ou correspond à un des motifs de cette propriété, ce message n'est PAS traité par la cible.
La configuration suivante de cible spécifie que la cible traitera les messages d'erreur ou d'avertissement des catégories dont le nom correspond soit à yii\db\*
, soit yii\web\HttpException:*
, mais pas yii\web\HttpException:404
.
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
'categories' => [
'yii\db\*',
'yii\web\HttpException:*',
],
'except' => [
'yii\web\HttpException:404',
],
]
Info : lorsqu'une exception HTTP est capturée par le gestionnaire d'erreur, un message d'erreur est enregistré avec un non de catégorie dont le format est
yii\web\HttpException:ErrorCode
. Par exemple, l'exception yii\web\NotFoundHttpException provoque un message d'erreur de catégorieyii\web\HttpException:404
.
Les cibles d'enregistrement exportent les messages enregistrés et filtrés dans un certain format. Par exemple, si vous installez une cible d'enregistrement de classe yii\log\FileTarget, vous pouvez trouver un message enregistré similaire au suivant dans le fichier runtime/log/app.log
file:
2014-10-04 18:10:15 [::1][][-][trace][yii\base\Module::getModule] Loading module: debug
Par défaut, les messages enregistrés sont formatés comme suit par la méthode yii\log\Target::formatMessage():
Horodate [adresse IP][identifiant utilisateur][identifiant de session][niveau de sévérité][catégorie] Texte du message
Vous pouvez personnaliser ce format en configurant la propriété yii\log\Target::$prefix qui accepte une fonction PHP appelable qui retourne un message de préfixe personnalisé. Par exemple, le code suivant configure une cible d'enregistrement pour qu'elle préfixe chaque message enregistré avec l'identifiant de l'utilisateur courant (l'adresse IP et l'identifiant de session étant retirés pour des raisons de protection de la vie privée).
[
'class' => 'yii\log\FileTarget',
'prefix' => function ($message) {
$user = Yii::$app->has('user', true) ? Yii::$app->get('user') : null;
$userID = $user ? $user->getId(false) : '-';
return "[$userID]";
}
]
En plus des préfixes de messages, les cibles d'enregistrement ajoutent aussi quelques informations de contexte à chaque lot de messages enregistrés.
Par défaut, les valeurs de ces variables PHP globales sont incluses : $_GET
, $_POST
, $_FILES
, $_COOKIE
, $_SESSION
et $_SERVER
. Vous pouvez ajuster ce comportement en configurant la propriété yii\log\Target::$logVars avec les noms des variables globales que vous voulez que la cible d'enregistrement inclue. Par exemple, la cible d'enregistrement suivante spécifie que seules les valeurs de la variable $_SERVER
seront ajoutées aux messages enregistrés.
`
php
[
'class' => 'yii\log\FileTarget',
'logVars' => ['_SERVER'],
]
`
Vous pouvez configurer logVars
comme un tableau vide pour désactiver totalement l'inclusion d'informations de contexte. Ou si vous voulez mettre en œuvre votre propre façon de fournir les informations contextuelles, vous pouvez redéfinir la méthode yii\log\Target::getContextMessage().
Lors du développement, vous cherchez souvent à voir d'où provient chacun des messages enregistrés. Cela est possible en configurant la propriété traceLevel du composantlog
de la façon suivante :
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [...],
],
],
];
La configuration de l'application ci-dessus statue que le niveau de trace sera 3 si YII_DEBUG
est activé et 0 si YII_DEBUG
est désactivé. Cela veut dire que, si YII_DEBUG
est activé, au plus trois niveaux de la pile des appels seront ajoutés à chaque message enregistré, là où le messages est enregistré ; et, si YII_DEBUG
est désactivé, aucune information de la pile des appels ne sera incluse.
Info : obtenir les informations de la pile des appels n'a rien de trivial. En conséquence, vous ne devriez utiliser cette fonctionnalité que durant le développement ou le débogage d'une application.
Comme nous l'avons dit plus haut, les messages enregistrés sont conservés dans un tableau par l'objet *logger*. Pour limiter la consommation de mémoire par ce tableau, l'objet logger purge les messages enregistrés vers les cibles d'enregistrement chaque fois que leur nombre atteint une certaine valeur. Vous pouvez personnaliser ce nombre en configurant la propriété flushInterval du composant log
:
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'flushInterval' => 100, // default is 1000
'targets' => [...],
],
],
];
Info : la purge des messages intervient aussi lorsque l'application se termine, ce qui garantit que les cibles d'enregistrement reçoivent des messages enregistrés complets.
Lorsque l'objet *logger* purge les messages enregistrés vers les cibles d'enregistrement, ils ne sont pas exportés immédiatement. Au lieu de cela, l'exportation des messages ne se produit que lorsque la cible d'enregistrement a accumulé un certain nombre de messages filtrés. Vous pouvez personnaliser ce nombre en configurant la propriété exportInterval de chacune des cibles d'enregistrement, comme ceci :
[
'class' => 'yii\log\FileTarget',
'exportInterval' => 100, // default is 1000
]
À cause des niveaux de purge et d'exportation, par défaut, lorsque vous appelez Yii::debug()
ou toute autre méthode d'enregistrement, vous ne voyez PAS immédiatement le message enregistré dans la cible. Cela peut représenter un problème pour pour certaines applications de console qui durent longtemps. Pour faire en sorte que les messages apparaissent immédiatement dans les cibles d'enregistrement, vous devriez définir les propriétés flushInterval et exportInterval toutes deux à 1, comme montré ci-après :
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'flushInterval' => 1,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'exportInterval' => 1,
],
],
],
],
];
Note : la purge et l'exportation fréquentes de vos messages dégradent la performance de votre application.
Vous pouvez activer ou désactiver une cible d'enregistrement en configurant sa propriété enabled. Vous pouvez le faire via la configuration de la cible d'enregistrement ou en utilisant l'instruction suivante dans votre code PHP :
Yii::$app->log->targets['file']->enabled = false;
Le code ci-dessus, nécessite que nommiez une cible file
, comme montré ci-dessous en utilisant des clés sous forme de chaînes de caractères dans le tableau targets
:
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'targets' => [
'file' => [
'class' => 'yii\log\FileTarget',
],
'db' => [
'class' => 'yii\log\DbTarget',
],
],
],
],
];
La création d'une classe de cible d'enregistrement est très simple. Vous devez essentiellement implémenter yii\log\Target::export() en envoyant le contenu du tableau des yii\log\Target::$messages vers un média désigné. Vous pouvez appeler la méthode yii\log\Target::formatMessage() pour formater chacun des messages. Pour plus de détails, reportez-vous à n'importe quelle classe de cible de messages incluse dans la version de Yii.
Conseil : au lieu de créer vos propres journaliseurs, vous pouvez essayez n'importe quel journaliseur compatible PSR-3 tel que Monolog en utilisant PSR log target extension.
Le profilage de la performance est un type particulier d'enregistrement de messages qui est utilisé pour mesurer le temps d'exécution de certains blocs de code et pour déterminer les goulots d'étranglement. Par exemple, la classe yii\db\Command utilise le profilage de performance pour connaître le temps d'exécution de chacune des requêtes de base de données.
Pour utiliser le profilage de la performance, commencez par identifier les blocs de code qui ont besoin d'être profilés. Puis, entourez-les de la manière suivante :
\Yii::beginProfile('myBenchmark');
...le bloc de code à::endProfile('myBenchmark');
où myBenchmark
représente un jeton unique identifiant un bloc de code. Plus tard, lorsque vous examinez le résultat du profilage, vous pouvez utiliser ce jeton pour localiser le temps d'exécution du bloc correspondant.
Il est important de vous assurer que les paires beginProfile
et endProfile
sont correctement imbriquées.
Par exemple,
\Yii::beginProfile('block1');
// du code à profiler
\Yii::beginProfile('block2');
// un autre bloc de code à profiler
\Yii::endProfile('block2');
\Yii::endProfile('block1');
Si vous omettez \Yii::endProfile('block1')
ou inversez l'ordre de \Yii::endProfile('block1')
et de \Yii::endProfile('block2')
, le profilage de performance ne fonctionnera pas.
Pour chaque bloc de code profilé, un message est enregistré avec le niveau de sévérité profile
. Vous pouvez configurer une cible d'enregistrement pour collecter de tels messages et les exporter. L'outil Yii debugger comporte un panneau d'affichage pré-construit des résultats de profilage.
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.