2010-10-18 7 views
6

Est-il possible de créer un CustomLayoutConverter personnalisé log4net qui permet de configurer une valeur "index"? Je sais au sujet de la chaîne de conversion « propriété » qui vous permet d'écrire du code comme ceci:Propriété log4net personnalisée PatternLayoutConverter (avec index)

ThreadContext.Properties["ID"] = yourID; 

Et préciser comme ceci:

%property{ID} 

Que la valeur doit être incluse dans la sortie. Et si les valeurs que je veux enregistrer sont dans un autre "dictionnaire"? Je suppose que je pourrais écrire une logique pour copier ces valeurs du dictionnaire dans l'un des contextes log4net et ensuite utiliser le jeton %property intégré. Que dois-je faire si je veux que log4net enregistre les valeurs directement à partir de mon propre "dictionnaire" en fonction d'une valeur d'index spécifiée dans le fichier de configuration?

Puis-je écrire mon propre PatternLayoutConverter qui me permettent de configurer quelque chose comme ceci:

%myproperty{ID} 

Et puis tirez sur le « ID » valeur de mon propre « dictionnaire » correspondant?

Pour toute personne qui se intéresse, il est assez facile de faire la même chose avec NLog:

[LayoutRenderer("MyGDC")] 
    class GdcLayoutRenderer : LayoutRenderer 
    { 
    [RequiredParameter] 
    [DefaultParameter] 
    public string Item { get; set; } 

    protected override void Append(StringBuilder builder, LogEventInfo logEvent) 
    { 
     string msg = GDC.Get(this.Item); 
     builder.Append(msg); 
    } 

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent) 
    { 
     return 10; 
    } 
    } 

et configuré comme ceci:

Parlez NLog au sujet des assemblages avec des extensions:

<extensions> 
    <add assembly="NLog.Extensions"/> 
    </extensions> 

Utilisez la propriété "indexée" dans un modèle:

<layout="${longdate} | ${MyGDC:item=name} | ${message}"/> 

Dans cet exemple, j'utilise réellement l'objet GDC de NLog comme "dictionnaire", mais je montre comment j'ai pu écrire mon propre LayoutRenderer "indexable" (plus ou moins équivalent au PatternLayoutConverter de log4net) pour accéder à une valeur indexée par une valeur dans le fichier de configuration.

[EDIT] J'ai obtenu la réponse que je voulais. J'ai inclus le code pour mon exemple PatternLayoutRenderer ici. Dans mon test, j'ai un dictionnaire statique dans ma classe de formulaire principal où je pourrais stocker des "paramètres d'application". J'ai créé un PatternLayoutConverter qui peut accepter une clé en tant que paramètre afin que le convertisseur puisse rechercher la valeur correcte dans le dictionnaire. Je pourrais être capable d'atteindre la même fonctionnalité en utilisant les objets de contexte log4net (ou NLog), mais dans notre application nous pourrions avoir quelques paramètres ou informations de session que l'application contiendra à d'autres fins et nous voulons être en mesure d'ajouter cela à sortie de journalisation. Comme il sera déjà dans une structure de recherche, il serait bon de pouvoir référencer directement les données plutôt que d'avoir à les copier explicitement dans le contexte log4net (ou NLog).

Quoi qu'il en soit, voici le code:

namespace Log4NetTest 
{ 
    class KeyLookupPatternConverter : PatternLayoutConverter 
    { 
    protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent) 
    { 
     //Use the value in Option as a key into the "application settings" stored on the main form. 
     string setting; 
     if (Form1.AppSettings.TryGetValue(Option, out setting)) 
     { 
     writer.Write(setting); 
     } 
    } 
    } 
} 

configuration de mise en page:

//Log the "sessionid" and "userid" values from our "application settings" object 
    <layout type="log4net.Layout.PatternLayout"> 
    <param name="ConversionPattern" value="%d [%t] %-5p [session = %KLPC{sessionid}] [user = %KLPC{userid}] %m%n"/> 
    <converter> 
     <name value="KLPC" /> 
     <type value="Log4NetTest.KeyLookupPatternConverter" /> 
    </converter> 
    </layout> 

Répondre

4

Je n'ai pas essayé, mais cela devrait fonctionner.En log4net vous pouvez passer une chaîne d'option à un convertisseur de modèle comme celui-ci:

%converterName{converterOptions} 

Le convertisseur de modèle de date, par exemple, peut être utilisé comme ceci:

%date{HH:mm:ss,fff} 

Cela signifie que vous pouvez écrire votre convertisseur de modèle le comme tu l'as suggéré. Un exemple simple pour un tel convertisseur peut être trouvé here.

Dans la méthode Convert, vous pouvez accéder à la chaîne de propriété avec la propriété 'Option' (définie dans la classe PatternConverter) et utiliser le contexte de thread pour obtenir l'entrée souhaitée du dictionnaire. Vous pouvez également implémenter l'interface IOptionHandler si vos options comprennent plus que la clé de dictionnaire: De cette façon, vous pouvez analyser les options lors de l'activation de la configuration de log4net.

+0

Merci! Cela a fait exactement ce que je voulais faire. Je vais ajouter mon test LayoutPatternConverter à ma question de référence au cas où quelqu'un d'autre serait intéressé. – wageoghe

Questions connexes