2015-08-24 3 views
0

Y at-il un moyen (NDC, Propriétés, ...?) D'avoir un nom/id par formulaire qui est inclus dans tous les messages log4net, de sorte que je peux distinguer les formulaires dans tous les messages de journal?log4net: Comment faire la distinction entre différents formulaires sur le même thread d'interface utilisateur?

J'ai beaucoup de méthodes de service etc. qui sont utilisées dans toutes mes formes, et j'aimerais voir par exemple. qu'un service a été appelé suite à une entrée de l'utilisateur sous quelle forme (pensez à plusieurs formes similaires non modales (même classe), exécutées dans le même thread UI, contenant un bouton, et dans Click-Event du bouton, une méthode de service est appelée. Dans la méthode de service, il y a des appels de consignation, dans les messages de consignation, j'aimerais avoir une propriété contenant l'information de dans quelle instance de formulaire le bouton a été cliqué.

Je ne veux pas modifier TOUS les appels de journalisation. Les exemples sur le web pour les contextes de journalisation/NDC ne parlent que de plusieurs clients/requêtes asp.net/etc, pas de multiples formulaires dans un thread.

Merci, Tim

+0

pensée latérale: Une solution possible serait de mettre chaque formulaire dans son propre appartement-fil, et de distinguer les événements du journal via thread-nom. Mais alors je devrais synchroniser/"thread-safify" tous les inter-forme-événements, non? Cela pourrait être un entretien PITA ... quelqu'un a une meilleure idée? –

Répondre

0

Pour ce faire, définissez ce que vous voulez enregistrer les propriétés dans l'événement Activé du formulaire:

private void Form1_Activated(object sender, System.EventArgs e) 
{ 
    // for example 
    log4net.GlobalContext.Properties["Name"] = this.GetType().Name; 
    log4net.GlobalContext.Properties["Id"] = this.Id; 
} 

La dans votre configuration de journalisation, vous pouvez référencer les propriétés en le PatternLayout pour chaque appender:

<layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%property{Name} : %property{Id} : [%level]- %message%newline" /> 
</layout> 

Edit: pour conserver des valeurs multiples, en utilisant une pile, comme dans le test de l'unité qui fournit en sortie:

Maintenant en TestClass1 maintenant dans TestClass2

using log4net.Appender; 
using log4net.Config; 
using log4net.Core; 
using log4net.Layout; 
using NUnit.Framework; 

namespace log4net.Tests 
{ 
    [TestFixture] // A NUnit test 
    public class log4net_Stacks 
    { 
     [SetUp] 
     public void Setup() 
     { 
      ConsoleAppender ca = new ConsoleAppender 
      { 
       Layout = new PatternLayout("%property{demo}"), 
       Threshold = Level.All 
      }; 

      ca.ActivateOptions(); 
      BasicConfigurator.Configure(ca); 
     } 

     [Test] 
     public void Stacks_Demo() 
     { 
      new TestClass1().Method1(); 
      LogManager.GetLogger("logger").Debug(""); 
      ThreadContext.Stacks["demo"].Clear(); 
     } 

     private abstract class BaseTestClass 
     { 
      protected static void AddToStack(string message) 
      { 
       ThreadContext.Stacks["demo"].Push(message); 
      } 
     } 

     private class TestClass1 : BaseTestClass 
     { 
      public void Method1() 
      { 
       AddToStack("Now in " + GetType().Name); 
       var tc2 = new TestClass2(); 
       tc2.Method2(); 
      } 
     } 

     private class TestClass2 : BaseTestClass 
     { 
      public void Method2() 
      { 
       AddToStack("Now in " + GetType().Name); 
      } 
     }  
    } 
} 
+0

thx, oui, cela résout le problème direct, mais j'ai aussi des cas où un événement GUI sous une forme est géré (indirectement) dans plusieurs de ces formes (par exemple, dans le formulaire d'origine d'événement et une autre forme). Dans un tel cas, je ne peux toujours pas voir ce qui se passe sous quelle forme. Est-il possible de distinguer dans ces cas plus complexes? –

+0

@ Dr.TimdosSantos dans ce cas, vous utiliserez probablement la propriété [Stacks de la classe ThreadContext] (https://logging.apache.org/log4net/release/sdk/log4net.ThreadContext.html) – stuartd

+0

pourriez-vous s'il vous plaît expliquer comment tirer parti de l'accessoire ThreadContext.Stacks pour cela, sans avoir à mettre un 'en utilisant (ThreadContext.Stacks [" Foo "]. Push (" Blah ")) {...}' appeler dans chaque gestionnaire d'événement de l'interface utilisateur ? –