2016-06-23 1 views
2

Ich sah eine Nachrichtenwarteschlange wie die Implementierung einer Protokollierungsklasse mit log4net.Ist es erforderlich, async-Protokollierung für ASP.NET MVC mit log4net zu implementieren?

Es ist für ASP.NET MVC Web-Anwendung verwendet wird, so fühle ich mich Threads bereits isoliert sind. Was ist der Vorteil dieser Implementierung?

public class Logger 
{ 
    private ILog _logger; 
    private static Logger _instance; 
    private Queue<Action> _logQueue = new Queue<Action>(); 
    private ManualResetEvent _newItemsExist = new ManualResetEvent(false); 
    private ManualResetEvent _terminate = new ManualResetEvent(false); 
    private ManualResetEvent _waiter = new ManualResetEvent(false); 
    private static object _syncLock = new object(); 

    private Thread _logThread; 

    public enum LoggingType { Debug, Info, Warn, Error, Fatal }; 
    public Logger() 
    { 
     _logger = LogManager.GetLogger(
      System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

     _logThread = new Thread(new ThreadStart(ProcessQueue)); 
     _logThread.IsBackground = true; 
     _logThread.Start(); 
    } 

    public static Logger Instance 
    { 
     get 
     { 
      if (_instance == null) 
       lock (_syncLock) 
        if (_instance == null) 
         _instance = new Logger(); 

      return _instance; 
     } 
    } 

    private void ProcessQueue() 
    { 
     while (true) 
     { 
      _waiter.Set(); 

      int i = ManualResetEvent.WaitAny(new WaitHandle[] { _newItemsExist, _terminate }); 
      if (i == 1) return; 

      _newItemsExist.Reset(); 
      _waiter.Reset(); 

      Queue<Action> queueCopy; 
      lock (_logQueue) 
      { 
       queueCopy = new Queue<Action>(_logQueue); 
       _logQueue.Clear(); 
      } 

      foreach (Action logAction in queueCopy) 
       logAction(); 
     } 
    } 
    public void _LogMessage(string msg_, Exception inEx_, LoggingType type_) 
    { 
     lock (_logQueue) 
      _logQueue.Enqueue(() => AsyncLogMessage(msg_, inEx_, type_)); 

     _newItemsExist.Set(); 
    } 
    private void AsyncLogMessage(string msg_, Exception inEx_, LoggingType type_) 
    { 
     switch (type_) 
     { 
      case LoggingType.Debug: 
       _logger.Debug(msg_, inEx_); 
       break; 

      case LoggingType.Info: 
       _logger.Info(msg_, inEx_); 
       break; 

      case LoggingType.Warn: 
       _logger.Warn(msg_, inEx_); 
       break; 

      case LoggingType.Error: 
       _logger.Error(msg_, inEx_); 
       break; 

      case LoggingType.Fatal: 
       _logger.Fatal(msg_, inEx_); 
       break; 
     } 
    } 
} 
+1

Das hat nichts mit Isolation zu tun. Wer dies schrieb, wollte nicht auf log4net warten, um die Nachricht zu verarbeiten. Obwohl die Pufferung jede Verzögerung reduzieren würde. Dieser Code ist jedoch * nicht * gut, weil Sie gezwungen sind, einen fest codierten Logger (und einen Singleton nicht weniger!) Zu verwenden, anstatt die Abstraktionen von log4net zu verwenden. Dieser Singleton bricht die Isolation tatsächlich, da er über alle Threads hinweg geteilt werden muss. –

+0

Außerdem hat .NET 4.5 sehr gute gleichzeitige Sammlungen. Wenn Sie ConcurrentQueue verwenden können, müssen Sie Warteschlangen und Sperren nicht verwenden. Dieser Code hat einige ernste Probleme –

Antwort

1

Sie brauchen nicht für log4net all Asynchron-Logger zu implementieren, ist es eine sehr gute Umsetzung mit einem Eintrag Benchmarks enthält Blog begleitet und erläutert die notwendigen Details.

Zusammenfassend ist async nur die Hälfte des Problems, Sie müssen auch eine Batch-Protokollierung bereitstellen, um den Durchsatz zu erhöhen. Andernfalls führt das Leeren jeder Protokollnachricht nacheinander zu Engpässen im Thread-Hauptthread.

Sie finden die Bibliothek unter GitHub, NuGet und den Blogeintrag HERE.

+0

Vergessen Sie nicht das Singleton! Und der manuell erstellte Thread –

+0

Meinte das nicht. Ich sah den Singleton in der Frage, einen manuellen Thread, eine Warteschlange mit Sperren anstelle von ConcurrentQueue und ich denke, diese Implementierung ist ziemlich beängstigend. 'Easy Logger' scheint einen richtig asynchronen Appender zu erstellen, obwohl –

+0

ja ich stimme zu, die Klasse von OP gepostet hat viele Probleme und scheint eher ein Hack als eine ordnungsgemäße Implementierung eines Appenders oder eines Forwarders. – MaYaN

Verwandte Themen