ECRITURE DE LOG C# MULTI-THREAD ET MULTI-PROCESS

cs_jmhC Messages postés 108 Date d'inscription vendredi 24 janvier 2003 Statut Membre Dernière intervention 10 août 2007 - 21 juin 2007 à 18:47
_shun_ Messages postés 2 Date d'inscription jeudi 26 juillet 2007 Statut Membre Dernière intervention 19 août 2015 - 19 août 2015 à 14:47
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/43210-ecriture-de-log-c-multi-thread-et-multi-process

_shun_ Messages postés 2 Date d'inscription jeudi 26 juillet 2007 Statut Membre Dernière intervention 19 août 2015
19 août 2015 à 14:47
Très utile, m'a fait gagner un temps précieux. Merci!
cs_gogomanu Messages postés 29 Date d'inscription mardi 7 janvier 2003 Statut Membre Dernière intervention 26 mars 2009
13 janv. 2010 à 17:13
Je trouve l'idée très bonne.

Simplement un commentaire:
Au lieu de définir une variable statique globale, tu peux créer un Singleton qui n'oblige pas l'instanciation à se faire dans le Main et n'oblige pas la déclaration Static.
La méthode getInstance() du Singleton peut renvoyer une interface ILog qui propose la méthode Write() principalement.

Donc, si tu fais Log.GetInstance().Write("mon info"); , cela écrira disons par défaut dans la sortie standard d'erreur, sans rien paramétrer avant.
La classe se suffit à elle même : déclaration, initialisation par défaut.

Un avantage est que le Singleton pourrait très bien dans le futur lire ses paramètres dans un fichier de configuration externe, qui pourrait contenir le nom du fichier par défaut, la chaîne de connexion BDD, etc. Ce qui n'oblige pas l'application en cours à paramétrer le type de Log désiré.
Rien n'empêche d'exposer des méthodes qui permettent de paramétrer depuis le Main() en plus, comme tu le fais actuellement.

Un autre avantage est que tu peux faire ta cuisine interne dans le Singleton : tu peux instancier une classe qui implémente ILog, et donc déporter la méthode Write() dans d'autres classes : "class LogWriterToFile : ILog", ou LogWriterToDefaultOutput, LogWriterToDB, etc... et dans la méthode Write() de la classe Log, tu peux appeler :

// --- Singleton (constructeur privé...)
class Log : ILog
{

// -- Par défaut sortie standard
private _writer = new LogWriterToDefaultOutput();

(...)

public ILog GetInstance()
{

}

public void Write(...)
{
_writer.Write(...);
}

}

A mon sens cette approche permet également beaucoup de souplesse : possibilité de chaîner les appels, d'utiliser le Design Pattern Proxy, le Design Pattern "chaîne de responsabilité" (si l'on admet qu'une info de succès doit être à l'écran, une erreur dans un fichier, et une info critique à la fois dans un fichier et envoyée par mail)...

Le Singleton peut aussi stocker une liste de ILog à appeler dans la méthode Write...

Le message c'est juste que travailler avec Singleton + interface autorise toutes les modifications de structure dans la façon dont le Log est géré derrière.
- Le Singleton sert de façade et d'accesseur global
- L'interface sert à pouvoir implémenter librement le code où l'on veut.

Enfin c'est un avis personnel.
arsenikstiger Messages postés 1 Date d'inscription samedi 6 octobre 2007 Statut Membre Dernière intervention 22 avril 2009
22 avril 2009 à 11:44
C'est sympa comme code.
Une remarque quand même.
Quand il y a des chaines multiples à concaténer, il est préférable d'utiliser la méthode string.concat
Exemple :
string messageErr = " Type : " + eventType.ToString() + " - message : "+ message + "\r\n";
devient
string messageErr = string.Concat(" Type : {0} - message : {1}\r\n",eventType.ToString(),message).

C'est plus propre et plus lisible ;)
Openflyer7 Messages postés 2 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 11 mars 2009
11 mars 2009 à 17:35
Je débute cela m'aide énormément, merci pour ton travail
gderenne Messages postés 3 Date d'inscription dimanche 10 novembre 2002 Statut Membre Dernière intervention 5 mars 2008
5 mars 2008 à 04:43
Super génial ton code : BRAVO.

Par contre, étant ultra débutant en C#, je ne comprend pas cette partie du code (void RaiseExceptionDetectedEvent) :
EventHandler eventHandler = ErrorDetectedEvent;
if (eventHandler != null)
eventHandler(this, new EventArgs());

Si tu pouvais m'expliquer, ca serait super sympa (surtout la première ligne) ;)
tyrann01 Messages postés 4 Date d'inscription mardi 26 juillet 2005 Statut Membre Dernière intervention 12 décembre 2008
17 juil. 2007 à 11:56
pour ricklekebekoi : tu as tout à fait raison, en fait j'utilise ce bout de code pour informer l'utilisateur d'une erreur via un bulle dans la tray icon de l'appli et en cas d'avalanche d'erreur ou exception, l'utilisateur ne voit que la dernière et m'envoit un mail avec les logs par exemple. Pour la classe MyClassEventArgs retourné par l'évenement pourquoi pas tout depent de l'usage que tu veux en faire.

Pour eldim :
Quand je parlais de multi-thread, je voulais dire que mon code prend en compte le multi-thread c'est à dire dans le cas ou ton appli a créer une volé de thread qui par le plus grand des hasard générent au meme moment des exceptions normalement le logger doit écrire toutes les erreurs dans le fichiers de log. Idem si tu as plusieurs applications ou instance différentes qui écrivent sur le même fichier de log (par exemple une appli ASP.NET). J'ai tester cela avec le code qui suit le button1_Click() dans Form1.cs (appli de test de ma class).
cs_eldim Messages postés 956 Date d'inscription lundi 30 mai 2005 Statut Membre Dernière intervention 21 août 2014 1
25 juin 2007 à 08:18
Bonjour,

je ne dois pas bien être réveillé mais je n'ai pas vu de multi-thread... peut-on m'indiquer où il se trouve ? (à moins qu'un timer soit considérer comme du multi-thread... mais j'en doute)
ricklekebekoi Messages postés 303 Date d'inscription mardi 11 février 2003 Statut Membre Dernière intervention 24 avril 2009 5
22 juin 2007 à 23:01
Vraiment bien !

Une petite partie m'embête un peu
//recuperation du message de l'erreur
string msgErr = Program.monLogListener.LastErrorMsg;
//recuperation du message de l'exception
Exception ex = Program.monLogListener.LastException;

Et si deux erreurs se succede vraiment rapidement, l'exception sera levée 2 fois, mais a chaque fois tu risque de voir la même erreur comme "derniere erreur". (C'est de la théorie, selon moi ça ferait ça, corrigez moi si je me tompre :P)

Hors, te faire une classe MyClassEventArgs qui contiendrait le message et l'exception, serait, selon moi, plus solide ... non ?
philcad Messages postés 1 Date d'inscription samedi 19 juin 2004 Statut Membre Dernière intervention 22 juin 2007
22 juin 2007 à 19:21
Pour une première publication je trouve ca vraiment bien.
Toutes mes félictations.
tyrann01 Messages postés 4 Date d'inscription mardi 26 juillet 2005 Statut Membre Dernière intervention 12 décembre 2008
22 juin 2007 à 10:17
Je me sert actuellement de ce code dans une appli client pour jeter un oeil aux dernières erreurs loggées quand un utilisateur m'informe d'un bug. Mais sur une appli serveur, il est clair que j'implementerai la fonctionnalité que tu as décrite.
cs_jmhC Messages postés 108 Date d'inscription vendredi 24 janvier 2003 Statut Membre Dernière intervention 10 août 2007
21 juin 2007 à 18:47
Super ton appli.

Je n'ai pas encore eu le temps de visualiser le code, mais celà peut-être pratique.

Une idée peut-être, tu pourrais mettre une date dans le nom du fichier et changer de fichier selon un quota ou une heure fixe de la journée, donc un fichier de X longueurs ou un fichier par jour.

Bonne continuation.
Rejoignez-nous