Section courante

A propos

Section administrative du site

Utilisation des journaux de bord

Il arrive que les développeurs aient besoin de consigner quelque chose pour garder une trace des choses, par exemple ce qui s'est mal passé (c'est-à-dire les journaux d'erreurs), à des fins d'audit,...

Le Fano Framework fournit un mécanisme de journalisation via l'interface ILogger. Cette interface expose plusieurs méthodes :

Méthode Description
log() Pour enregistrer des messages à tous les niveaux.
emergency() Pour enregistrer les messages d'urgence.
critical() Pour enregistrer les messages critiques.
error() Pour enregistrer les messages d'erreur.
alert() Pour enregistrer les messages d'alerte.
warning() Pour enregistrer les messages d'avertissement.
debug() Pour enregistrer les messages de débogage.
notice() Pour enregistrer les messages d'avis.
info() Pour enregistrer des messages d'information.

À l'exception de la méthode log(), toutes les méthodes attendent deux paramètres. Le premier paramètre est un message à enregistrer et le second paramètre est des données liées au message de journal. Ce paramètre est facultatif. Si ce deuxième paramètre est donné, il doit implémenter l'interface ISerializeable.

Par exemple, pour enregistrer un message critique :

  1. Var logger:ILogger;
  2. ...
  3. logger.critical('C''est un message crucial');

Journal de bord intégré

Le Fano Framework possède plusieurs journaux de bord intégrés que les développeurs peuvent utiliser ou étendre. Tous les journaux de bord intégrés héritent de TAbstractLogger fournissant la plupart des implémentations de méthodes, à l'exception de la méthode log() étant une méthode abstraite que le descendant doit implémenter. Cette classe est principalement ce que les développeurs doivent étendre pour créer un nouveau type de logger.

Journal dans le journal système

TSysLogLogger est une implémentation de logger écrivant le journal dans le journal système. Voir syslog.

  1. Var logger:ILogger;
  2. ...
  3. logger:=TSysLogLogger.create();

Son constructeur attend trois paramètres optionnels.

  1. Constructor TSysLogLogger.Create(
  2.     Const Prefix:String = '';
  3.     Const Opt:Integer = -1;
  4.     Const Facility:Integer = -1
  5. );

Paramètre Description
prefix Chaîne de caractères étant préfixée à tous les messages du journal.
opt Valeur entière pour l'option. Si elle n'est pas définie, elle utilise par défaut LOG_NOWAIT ou LOG_PID.
facility Valeur entière pour l'installation. Si elle n'est pas définie, elle utilise par défaut LOG_USER.

Voir openlog.

Journal dans un fichier

TFileLogger est une implémentation de journal écrivant le journal dans un fichier. Son constructeur attend le nom de fichier où écrire le journal. L'exception EInOutError sera déclenchée lorsque le nom de fichier ne peut pas être créé ou ouvert pour l'écriture. Dans ce cas, assurez-vous que l'autorisation de répertoire/fichier correcte est donnée.

  1. Var logger:ILogger;
  2. ...
  3. logger:=TFileLogger.create('storages/logs/app.log');

Supprimer la journalisation

TNullLogger est une implémentation de journalisation ne faisant rien. Il est fourni pour que le développeur puisse désactiver la journalisation.

Journalisation sur STDOUT

TStdOutLogger est une implémentation de journal générant un message de journalisation sur STDOUT. Ce journal ne peut pas être utilisé dans une application CGI.

Journalisation sur STDERR

TStdErrLogger est une implémentation de journal générer un message de journal sur STDERR.

Journalisation par courriel

TMailLogger est une implémentation de journal générant les messages de journal sous forme de courriel. Elle nécessite une instance de l'interface IMailer étant responsable de l'envoi des courriels.

  1. Var logger:ILogger;
  2. ...
  3. logger:=TMailLogger.create(
  4.     TSendmailMailer.create(),  (* envoyer en utilisant sendmail *)
  5.     'to@exemple.com',  (* destinataire *)
  6.     'from@monapp.fano' (* expéditeur *)
  7. );

Le constructeur TMailLogger accepte un quatrième paramètre facultatif étant une chaîne de préfixe ajoutée au sujet du courriel. Pour modifier la composition de l'objet et du corps du courriel, vous pouvez étendre la classe TMailLogger et remplacer ses méthodes protégées buildSubject() et buildMessage().

Fano Mail Logger est un exemple d'application Web montrant comment enregistrer des messages sous forme de courriel.

Journalisation dans la base de données

TDbLogger est une implémentation de journal de bord générant un message de journal dans la base de données. Il nécessite une instance d'IRdbms responsable de l'opération de base de données.

Pour pouvoir utiliser ce journal de bord, vous devez créer une table avec au moins quatre colonnes pour entreposer le niveau, le message, la date et l'heure du journal et les données associées liées à l'entrée du journal. Par exemple :

  1. CREATE TABLE logs
  2. (
  3.     id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
  4.     level VARCHAR(20) NOT NULL,
  5.     msg VARCHAR(400) NOT NULL,
  6.     created_at DATETIME NOT NULL,
  7.     context TEXT NOT NULL
  8. )

Lors de la création d'une instance TDbLogger, vous devez indiquer le nom de la table et les champs obligatoires :

  1. logger:=TDbLogger.create(
  2.     rdbms,
  3.     'logs', (* nom de la table *)
  4.     'level', (* nom de la colonne de niveau *)
  5.     'msg', (* nom de la colonne de message *)
  6.     'created_at', (* journal datetime *)
  7.     'context' (* nom de la colonne de contexte *)
  8. );

Fano Db Logger est un exemple d'application Web qui montre comment se connecter à une base de données MySQL.

Connectez-vous à plusieurs supports

TCompositeLogger est une implémentation de journal de bord composée d'instances ILogger externes. Elle peut être utilisée pour combiner deux ou plusieurs journaux de bord en un seul, créant ainsi une fonctionnalité de journalisation plus complexe. Par exemple, pour enregistrer simultanément dans un fichier et dans un SGBDR.

  1. Var logger:ILogger;
  2. ...
  3. logger := TCompositeLogger.create([
  4.     TFileLogger.create('storages/logs/app.log'),
  5.     TDbLogger.create(
  6.         rdbms,
  7.         'logs', (* nom de la table *)
  8.         'level', (* nom de la colonne de niveau *)
  9.         'msg', (* nom de la colonne de message *)
  10.         'created_at', (* journal datetime *)
  11.         'context' (* nom de la colonne de contexte *)
  12.     )
  13. ]);

Journal séparé en fonction du type de niveau

Parfois, vous souhaiterez peut-être séparer le journal en fonction du niveau. Par exemple, vous souhaiterez peut-être enregistrer les messages de journal non critiques dans un fichier distinct de celui des messages critiques pour faciliter l'audit. Ou vous devez désactiver la journalisation pour les messages de journal non critiques mais conserver le journal critique.

TSegregatedLogger est une implémentation de journal convenant à ce type de scénario de journalisation. Ce journal attend de l'appelant qu'il fournisse quatre instances ILogger qui géreront respectivement les niveaux de journal INFO, DEBUG, Warning et CRITICAL.

  1. Var logger:ILogger;
  2. ...
  3. logger:=TSegregatedLogger.create(
  4.     TFileLogger.create('storages/logs/app.emergency.log'),
  5.     TFileLogger.create('storages/logs/app.alert.log'),
  6.     TFileLogger.create('storages/logs/app.critical.log'),
  7.     TFileLogger.create('storages/logs/app.error.log'),
  8.     TFileLogger.create('storages/logs/app.warning.log'),
  9.     TFileLogger.create('storages/logs/app.notice.log'),
  10.     TFileLogger.create('storages/logs/app.info.log'),
  11.     TFileLogger.create('storages/logs/app.debug.log')
  12. );

De cette façon, chaque type de journal est écrit dans un fichier séparé, ce qui facilite la recherche, par exemple, des messages de journal critiques.

Si vous devez désactiver la journalisation des messages de niveau INFO, vous pouvez le remplacer par quelque chose comme suit :

  1. Var logger:ILogger;
  2. ...
  3. logger := TSegregatedLogger.create(
  4.     TFileLogger.create('storages/logs/app.emergency.log'),
  5.     TFileLogger.create('storages/logs/app.alert.log'),
  6.     TFileLogger.create('storages/logs/app.critical.log'),
  7.     TFileLogger.create('storages/logs/app.error.log'),
  8.     TFileLogger.create('storages/logs/app.warning.log'),
  9.     TFileLogger.create('storages/logs/app.notice.log'),
  10.     TNullLogger.create(),
  11.     TFileLogger.create('storages/logs/app.debug.log')
  12. );

Ou vous souhaiterez peut-être combiner INFO, DEBUG dans un fichier et le message de journal Warning, CRITICAL dans un autre fichier.

  1. Var logger,infoDebug,warningCritical:ILogger;
  2. ...
  3. infoDebug := TFileLogger.create('storages/logs/app.infodebug.log'),
  4. warningCritical:=TFileLogger.create('storages/logs/app.warningcritical.log'),
  5. logger := TSegregatedLogger.create(
  6.     TFileLogger.create('storages/logs/app.emergency.log'),
  7.     TFileLogger.create('storages/logs/app.alert.log'),
  8.     warningCritical,
  9.     TFileLogger.create('storages/logs/app.error.log'),
  10.     warningCritical,
  11.     TFileLogger.create('storages/logs/app.notice.log'),
  12.     infoDebug,
  13.     infoDebug
  14. );

Journalisation dans le processus léger d'arrière-plan

Certaines implémentations de journal de bord prennent du temps à se terminer, comme TMailLogger. Pour éviter de bloquer le processus léger principal, vous pouvez écrire le journal dans le processus léger d'arrière-plan à l'aide de TBackgroundThreadLogger. L'exemple suivant fait que l'écriture du journal dans le courrier électronique se fait dans le processus léger d'arrière-plan.

  1. Var logger:ILogger;
  2. ...
  3. logger:=TBackgroundThreadLogger.create(
  4.     TMailLogger.create(
  5.         TSendmailMailer.create(), (* envoyer en utilisant sendmail *)
  6.         'to@exemple.com', (* destinataire *)
  7.         'from@monapp.fano' (* expéditeur *)
  8.     )
  9. );

Classe d'usine pour les enregistreurs intégrés

Le Fano Framework fournit une classe d'usine pour les enregistreurs intégrés afin qu'ils puissent être enregistrés facilement dans le conteneur de dépendances. Les usines suivantes sont disponibles :

Enregistrer TFileLogger

Par exemple, pour enregistrer TFileLogger dans un conteneur de dépendances :

  1. Var container:IDependencyContainer;
  2. ...
  3. container.add('logger', TFileLoggerFactory.create('storages/logs/app.log'));

Enregistrer TNullLogger

Pour enregistrer TNullLogger :

  1. container.add('logger',TNullLoggerFactory.create());

Enregistrer TStdOutLogger

Pour enregistrer TStdOutLogger :

  1. container.add('logger', TStdOutLoggerFactory.create());

Enregistrer TStdErrLogger

Pour enregistrer TStdErrLogger :

  1. container.add('logger', TStdErrLoggerFactory.create());

Enregistrer TCompositeLogger

Pour enregistrer TCompositeLogger :

  1. container.add(
  2.     'logger',
  3.     TCompositeLoggerFactory.create(
  4.         TFileLoggerFactory.create('storages/logs/app.log'),
  5.         TNullLoggerFactory.create()
  6.     )
  7. );

Enregistrer TSysLogLogger

Pour enregistrer TSysLogLogger :

  1. container.add(
  2.     'logger',
  3.     (TSysLogLoggerFactory.create()).prefix('fano-app')
  4. );

Enregistrer TDbLogger

Pour enregistrer TDbLogger :

  1. container.add('db',TMySqlDbFactory.create(
  2.     'mysql 5.7',
  3.     '127.0.0.1',
  4.     '[remplacer par le nom de la base de données]',
  5.     '[remplacer par le nom d''utilisateur]',
  6.     '[remplacer par un mot de passe]',
  7.     3306
  8. ));
  9. container.add('logger', TDbLoggerFactory.create().rdbmsSvcName('db'));

rdbmsSvcName() est utilisé pour indiquer à l'usine où rechercher l'instance IRdbms.

Le code ci-dessus suppose l'utilisation de journaux de noms de table, avec le niveau de colonne, msg, created_at et context.

Pour utiliser des noms de table ou de colonne différents :

  1. container.add(
  2.     'logger',
  3.     TDbLoggerFactory.create()
  4.         .rdbmsSvcName('db')
  5.         .tableName('mylogs')
  6.         .levelField('mylevel')
  7.         .msgField('mymsg')
  8.         .createdAtField('my_created_at')
  9.         .contextField('my_coaintext')
  10. );

Enregistrer TMailLogger

Pour enregistrer TMailLogger :

  1. container.add('mailer', TSendmailMailerFactory.create());
  2. container.add(
  3.     'logger',
  4.     TMailLoggerFactory.create()
  5.         .mailer('mailer')
  6.         .recipient('to@exemple.com')
  7.         .sender('no-reply@monapp.fano')
  8. );

mailer() est utilisé pour indiquer à l'usine où rechercher l'instance IMailer. Pour définir le préfixe sur l'objet du courriel, utilisez la méthode prefix() comme suit :

  1. container.add(
  2.     'logger',
  3.     TMailLoggerFactory.create()
  4.         .mailer('mailer')
  5.         .recipient('to@exemple.com')
  6.         .sender('no-reply@monapp.fano')
  7.         .prefix('Mon App')
  8. );

Enregistrer TBackgroundThreadLogger

Pour enregistrer TBackgroundThreadLogger :

  1. container.add(
  2.     'logger',
  3.     TBackgroundThreadLoggerFactory.create(
  4.         TMailLoggerFactory.create()
  5.             .mailer('mailer')
  6.             .recipient('to@exemple.com')
  7.             .sender('no-reply@monapp.fano')
  8.     )
  9. );

Enregistrer les dépendances du logger

Vous pouvez automatiser l'enregistrement des dépendances du journal de bord lors de l'échafaudage du projet avec Fano CLI.

Récupérer l'instance ILogger du conteneur

Une fois la fabrique de journaux de bord enregistrée, vous pouvez accéder au journaux de bord n'importe où à partir de l'application, comme indiqué dans le code suivant.

  1. Var logger:ILogger;
  2. ...
  3. logger:=container.get('logger') as ILogger;

ou avec une syntaxe de type tableau :

  1. logger:=container['logger'] as ILogger;


Dernière mise à jour : Vendredi, le 18 octobre 2024