jeudi 23 avril 2015

Technique de log .NET C#: TraceSource et FileLogTraceListener

.NET possède un système pas trop mal pour logger différents types d'infos dans des fichiers de façon relativement simple. En fait, plusieurs façons de le faire existent mais je ne détaille que la méthode retenue qui correspond à ce que je cherche en ce moment: TraceSource et FileLogTraceListener.

La classe TraceSource nous donne accès à quelques méthodes et constantes pour enregistrer plusieurs types d'informations de côté. Ces informations peuvent être filtrées et récupérées par des Listener qui peuvent les afficher dans des consoles ou les enregistrer dans des fichiers.

FileLogTraceListener range les infos qu'on lui dis de récupérer dans un ou plusieurs fichiers en fonction de la date ou divers autres paramètres.

Dans mon code source .cs:

using System.Diagnostics;
using Microsoft.VisualBasic.Logging;
...
class Program{
    // défini un TraceSource avec un nom spécifique   
    static TraceSource tracer = new TraceSource( "mesTraces" );
   
static void Main( string[] args )    {       
    int idTrace = Process.GetCurrentProcess().Id;
    // change le nom de base du fichier de log utilisé pour les traces       
    var ecouteurs = tracer.Listeners;   // récupère la liste des listeners liés à mon TraceSource          
    for( int i=0; i<ecouteurs.Count; i++ ) {
        try{
            var ecout = (FileLogTraceListener)ecouteurs[i];
            ecout.BaseFileName = "TestTraces-"+ args[1];   // le nom du fichier log généré sera du type TestTraces-<nom donné en argument d'entrée>-<date du jour>
            break;
        }catch( Exception e ){}       
    }
    ...

    tracer.TraceEvent( TraceEventType.Information, idTrace, "infos blabla" );
    ...
    tracer.TraceEvent( TraceEventType.Warning, idTrace, "Attention!" );
    ...
    tracer.TraceEvent( TraceEventType.Error, idTrace, "Gros Problème!" );
    ...
    tracer.Close();
}
}


Bref, pas trop de trucs compliqués à gérer dans le code!
- on ajoute les using qui correspondent
- on définit et initialise un TraceSource
- optionnellement, on peut modifier le nom de base du fichier crée par les listeners lié au TraceSource
- on logge les infomations que l'on veut avec la fonction TraceEvent qui nous permet d'indiquer le type d'informations (voir les Trace Event Type), un entier que l'on peut utiliser comme on veut, et notre message
- on ferme le Tracer quand on en a plus besoin

La gestion des infos loggées peut se faire dans le code source directement, mais j'ai préféré mettre tout ca dans le fichier de configuration de façon à pouvoir modifier le comportement sans avoir à tout recompiler.

Dans mon app.config:

<system.diagnostics>
    <!-- switchValue= Off, Error, Warning, Info, Verbose -->
    <sources>
      <source name="mesTraces" switchType="System.Diagnostics.SourceSwitch" switchValue="Verbose">
        <listeners>
          <add name="ecouteurFileLog"                type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
               Location="ExecutableDirectory"
               logFileCreationSchedule="Daily"
               baseFileName="ListingPrint"
               traceOutputOptions="Timestamp" />
          <remove name="Default" />
        </listeners>
      </source>
    </sources>
</system.diagnostics>


La, c'est un peu plus verbeux..
- dans la définition de la source, on indique le nom du TraceSource à regarder = le nom donné à ton TraceSource dans le code source.
- switchValue permet de dire quelles informations vont être sauvegardées dans le fichier. Off: on ne met rien, Verbose: on met tout, ...
- on peut ajouter plusieurs listeners par source pour avoir plusieurs fichiers de log différents ou pour afficher aussi les logs à l'écran...
- mon FileLogTraceListener a un type qui est long à définir.. mais il faut tout ca sinon on a des problèmes à l'exécution!
- quelques paramètres à donner au listener (voir la page MSDN pour plus de détails). A noter que les dates et heures récupérées avec les options traceOutputOptions DateTime et Timestamp sont UTC, pas locales! ...et ca ne se configure pas..
- de base, FileLogTraceListener ajoute la date du jour au nom de fichier de log généré!

Bon, ca n'est pas parfait:
- les infos rajoutées à chaque ligne du fichier log sont dans un ordre défini:
    nom du traceSource, id, type de message, message, traceOutputOptions
si tu veux mettre la date au début ou virer le nom du traceSource, tant pis!

- les dates/heures du traceOutputOptions sont en UTC! Donc vive le calcul mental, ou alors tu laisses tomber le traceOutputOptions et tu intègres la date locale dans chacun de tes messages (surcharges des fonctions traceEvent, ...)

Après, rien ne nous empêche de créer notre propre listener selon nos envies.

Aucun commentaire:

Enregistrer un commentaire