2016-06-23 12 views
2

私はlog4netでログクラスの実装のようなメッセージキューを見た。log4netでASP.NET MVCの非同期ロギングを実装する必要はありますか?

これは、ASP.NET MVC Webアプリケーションに使用するので、私はスレッドがすでに隔離されていると感じています。この実装のメリットは何ですか?

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

これはアイソレーションとは何の関係もありません。誰でもこれを書いた人は、log4netがメッセージを処理するのを待つことを望んでいませんでした。ただし、バッファリングは遅延を低減します。このコードは、log4netの抽象構文を使用する代わりに、ハードコードされたロガー(およびシングルトン以下)を使用する必要があるため、このコードは優れていません。それはまた、.NET 4.5は非常に良い同時コレクションを持ってい –

+0

すべてのスレッド間で共有する必要があるとして、実際にこのシングルトンは孤立を破ります。 ConcurrentQueueを使用できるときは、キューとロックを使用する必要はありません。そのコードには深刻な問題がいくつかあります –

答えて

1

あなたはlog4netのために任意の非同期ロガーを実装する必要はありません、ベンチマークを含有し、必要に応じて詳細を説明するブログエントリを伴う非常に良い実装があります。要約すると

は、非同期あなたもそうでない場合、別の原因がスレッドメインスレッドまたはそれ以外にボトルネックの後に、すべてのログメッセージ1を洗い流すスループットを向上させるバッチ・ロギングを提供する必要があり、問題の半分だけです。

ライブラリはGitHub,NuGet、ブログエントリHEREにあります。

+0

シングルトンを忘れないでください!そして手動で作成されたスレッド –

+0

それを意味しませんでした。問題のシングルトン、手動のスレッド、ConcurrentQueueの代わりにロックを持つQueueを見ました。この実装はむしろ恐ろしいものです。 –

+0

は、はい、私は同意するものの簡単Logger'が正しく非同期アペンダを作成しているようだ '、OPによって掲示クラスは、多くの問題があり、ハックではなく、アペンダまたはフォワーダの適切な実装のように思えます。 – MaYaN

関連する問題