Si seulement j'avais reçu un mail lorsque l'erreur s'est produite, j'aurai pu intervenir plus rapidement...
C'est le genre de phrase que l'on pourrait se dire lorsque notre application plante et provoque une catastrophe chez un client. Souvent, intervenir dès que l'erreur est détectée aurait permis de diminuer l'impact du problème.
Aujourd'hui, c'est ce que nous allons essayer de voir avec yLogger, le composant qui permet de gérer les logs de votre application.
Vous avez bien protégé votre application, les erreurs sont correctement loguées, mais il y en a une qui vous fait peur et vous avez le code suivant :
QUAND EXCEPTION DANS
executer_traitement_très_risqué()
FAIRE
logger.ecrire_critique("Le traitement très risqué a explosé." + RC + ExceptionInfo(errMessage))
FIN
Mais voilà, les logs sont enregistrés sur la machine qui fait tourner le code. Lorsque l'erreur se produit, vous n'êtes pas derrière à vérifier ce qu'il se passe. Si seulement vous aviez reçu un mail !
Ça ne s'est pas encore produit ? Tant mieux ! Je vous propose de résoudre ce problème en mettant en place un enregistreur qui permet d'envoyer un mail lorsqu'une erreur critique est rencontrée.
La première chose à faire est de créer l'enregistreur. Pour cela, vous devez créer une nouvelle classe. Pour ma part, je l'appelle ici cEnregistreurVersMail.
cEnregistreurVersMail est une Classe
hérite de cEnregistreur
PRIVÉE
__adresses_destinataires est un tableau de chaînes
__serveur_adresse est une chaîne
__serveur_port est une chaîne
__serveur_nom_expéditeur est une chaîne
__serveur_mdp_expéditeur est une chaîne
__chemin_fichier_log est une chaîne
__logger est un cLogger dynamique
FIN
On paramètre ensuite le constructeur. Dedans, on indique que l'on n'envoie un mail que dans le cas d'un message critique avec la constante _LOG_CRITIQUE_
. On indique aussi le formateur par défaut, je prends le fichier texte.
Notez qu'en paramètre, je récupère un objet logger. Et oui, si je n'arrive pas à envoyer mon mail, j'ai envie d'enregistrer la raison. En le récupérant comme un paramètre, cela m'évite de mettre en place une dépendance avec le projet. Je peux déplacer ma classe dans chacun de mes projets.
PROCEDURE Constructeur(logger est un cLogger dynamique)
Constructeur cEnregistreur(_LOG_CRITIQUE_, mLogger.créer_formateur_texte())
:__logger = logger
:__adresses_destinataires = ["adresse1@exemple.com", "adresse2@exemple.com"]
:__serveur_adresse = "smtp.fai.com"
:__serveur_port = 25
:__serveur_nom = "utilisateur"
:__serveur_mdp = "mon mot de passe"
:__chemin_fichier_log = "x:\répertoire\fichier.log" // Changer le chemin du fichier log
FIN
Je dérive ensuite la méthode _enregistrer. C'est la base de la classe cEnregistreur. Chaque message de log passe par cette méthode. Afin d'éviter que le programme bloque les messages, j'utilise un thread pour envoyer le mail. J'aurais aussi pu utiliser une tâche parallèle. J'utilise DonneGUID pour être sûr d'avoir un nom de thread unique.
PROCEDURE _enregistrer(message_log est un stMessage)
ThreadExécute(DonneGUID(), threadNormal, :__envoyer_log_par_mail, message_log)
Et voilà la procédure qui permet d'envoyer le log par mail. J'initialise mes paramètres d'envoi et surtout, je n'oublie pas d'attacher le fichier de log. C'est lui qui me permettra de savoir ce qu'il s'est passé. Je protège l'envoi par un QUAND EXCEPTION.
PROCEDURE PRIVÉE __envoyer_log_par_mail(message_log est un stMessage)
QUAND EXCEPTION DANS
// Ouverture d'une session SMTP sécurisée TLS
session_mail est un EmailSessionSMTP
session_mail..AdresseServeur = :__serveur_adresse
session_mail..Option = emailOptionDéfaut
// Le port TLS dépend du fournisseur, à bien vérifier !
session_mail..Port = :__serveur_port
session_mail..Nom = :__serveur_nom_expéditeur
session_mail..MotDePasse = :__serveur_mdp_expéditeur
// 10 secondes pour le time out
EmailChangeTimeOut(10)
SI EmailOuvreSession(session_mail) ALORS
// Envoi d'un message
email_log est un Email
email_log.Expediteur = "noreply@exemple.com"
email_log.Sujet = "Problème dans le projet Truc"
email_log.Destinataire = :__adresses_destinataires
email_log.Message = message_log.texte
EmailChargeFichierAttaché(email_log, :__chemin_fichier_log)
EmailEnvoieMessage(session_mail, email_log)
EmailFermeSession(session_mail)
SINON
:__logger.ecrire_erreur("Impossible d'envoyer un mail." + RC + ErreurInfo())
FIN
FAIRE
:__logger.ecrire_erreur("Impossible d'envoyer un mail." + RC + ExceptionInfo())
FIN
Enfin, il ne me reste plus qu'à ajouter mon enregistreur à mon objet cLogger.
logger = créer_logger(_LOG_INFO_)
logger.ajouter_enregistreur(creer_enregistreur_vers_fichier_texte(_LOG_INFO_, mLogger.créer_formateur_texte(), "x:\répertoire\fichier.log"))
logger.ajouter_enregistreur(allouer un cEnregistreurVersMail(vl.logger))
Dès lors que j'appelle la méthode logger.ecrire_critique(), je recevrais un mail avec le fichier de log.
Et voilà ! Vous avez mis en place un système qui vous permet de recevoir un mail à chaque fois qu'une erreur critique survient. Bien entendu, vous pouvez conditionner l'envoi sur la présence d'un mot clé dans le message de log ou sur tout autre critère (en fonction de l'heure par exemple).
Si vous n'utilisez pas encore yLogger, sachez que je le vends à prix libre.
Sachez aussi que je peux vous proposer des séances d'accompagnement pour vous aider à mettre en place ce composant.
Si vous souhaitez le faire évoluer, n'hésitez pas à m'indiquer vos suggestions.
J'espère que cet article vous a plu et vous permettra d'utiliser tout le potentiel d' yLogger.
Je vous remercie.