ファイル同時実行(ログ処理)--キュー--Redis+Log 4 Net


マルチスレッドが同じファイルを操作すると、同時発生する問題が発生します.解決策の1つはファイルにロックをかけることですが、そうすると1つのスレッドがファイルを操作するとき、他のものは待たなければなりません.そうすると性能が非常に悪いです.もう1つの解決策は、まずデータをキューに配置し、スレッドを開き、キューからデータを取り出し、ファイルに書き込むことです.
次に、実際のプロジェクトで適用された例を説明します.ログの処理について説明します.ここではASP.NETを使用します. MVCプロジェクトはデモとして.
方法1:キューの使用
考え方:発生したすべてのログ情報を1つのキューに保存し、新しいスレッドを作成することで、このキューから異常情報を読み取り続け、ログに書きます.いわゆる生産者、消費者モデルである.
1、クラスを新規作成します.
using System.Web.Mvc;
    public class MyErrorAttribute : HandleErrorAttribute
    {
        public static Queue ExceptionQueue = new Queue();
        public override void OnException(ExceptionContext filterContext)
        {
            ExceptionQueue.Enqueue(filterContext.Exception);
            filterContext.HttpContext.Response.Redirect("~/Error.html");
            base.OnException(filterContext);
        }
}

2、FilterConfigクラスで以下の修正を行います.
  public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            //filters.Add(new HandleErrorAttribute());

            filters.Add(new MyErrorAttribute());
        }
 }
3

Gobal.asax.cs
タブで行います.
Application_Start
イベントには次のコードが追加されます.
 string filePath = Server.MapPath("~/Logs/");
            ThreadPool.QueueUserWorkItem(o => { 
            while(true)
            {
                if (MyErrorAttribute.ExceptionQueue.Count > 0)
                {
                    Exception ex = MyErrorAttribute.ExceptionQueue.Dequeue();
                    if (ex != null)
                    {
                        string fileName = filePath + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                        File.AppendAllText(fileName, ex.Message);
                    }
                    else
                    {
                        Thread.Sleep(50);
                    }
                }
                else
                {
                    Thread.Sleep(50);
                }
            }
            });

方式2:RedisとLog 4 Netを使用して分散ログ記録を完成する
Log 4 Netはログを記録するためのもので、プログラムの実行中の情報をいくつかの場所(ファイル、データベース、EventLogなど)に出力することができます.ログはプログラムのブラックボックスで、
ログはシステムの実行プロセスを表示し、システムの問題を発見します.ログの役割:実行プロセスのステップ、成功失敗を記録し、重要なデータを記録してシステムの問題点を分析します.
サイトにとって、異常情報をユーザーに表示することはできません.異常情報はログに記録するしかありません.問題が発生したら、ログファイルを開発者に送ると、問題の所在がわかります.
Log 4 Net環境の構成
(1)WebApplicationの新規作成
(2)log 4 net.dllへの参照を追加(binet2.0release Debugバージョンは参照できません(対応するdllファイルをプロジェクトのlibフォルダにコピーします).
(3)Web.configで (またはApp.Config)構成の追加
(4)初期化:プログラムの最初にlog 4 net.Config.XmlConfigurator.configure()を加える
 
ログを印刷する場所LogManager.GetLogger(typeof(Program).Debug("情報"); .ログ管理者GetLoggerからログ・クラス名を渡してこのクラスのILogを取得し(ログ・ファイルでこのログがどのクラスから出力されたかを見ることができます)、Debugメソッドを呼び出してメッセージを出力します.クラス内でログを印刷する場所が1つ以上あるため、ILogをstaticフィールドとして宣言するのが一般的です.
Private static ILog logger=LogManager.GetLogger(typeof(Test))
エラーメッセージをILog.Errorメソッドで出力し、2番目のパラメータはExceptionオブジェクトを渡すことができます.log.Error("***エラー"+ex)、log.Error("***エラー",ex)
Appender:ログを異なる場所に出力できます.異なる出力先は異なるAppender:RollingFileAppender(スクロールファイル)、AdoNetAppender(データベース)、Smtppenderに対応します. (メール)など.
level(レベル):このログ情報を識別する重要レベルNone>Fatal>ERROR>WARN>DEBUG>INFO>ALL、1つ設定
Level、このLevelより低いログはAppenderに書かれません.
Log 4 Netは複数のAppenderを設定することができ、同時にログをファイル、データ、メールなどに記録することができる.異なるAppenderの異なるレベルを設定することができ、通常レベルでファイルに記録し、Error以上のレベルでメールを送信することができます.異なるクラスに対して異なるAppenderを設定することができる.Appenderをカスタマイズすることで、自分でErrorメッセージをメールなどに送ることができる.
例:
1、Log 4 Netを構成し、Web.configに以下の構成を追加する.

    
    

2、添加ServiceStack.dllServiceStack.Interfaces.dllServiceStack.ServiceInterface.dlllog4net.dll的引用,然后新建一个类MyErrorAttribute,

using System.Web.Mvc;
using ServiceStack.Redis;
 public static IRedisClientsManager clientsManager = new PooledRedisClientManager(new string[] { "127.0.0.1:6379"});
        public static IRedisClient redisClient = clientsManager.GetClient();

        public override void OnException(ExceptionContext filterContext)
        {
            redisClient.EnqueueItemOnList("errorMsg", filterContext.Exception.ToString());
            filterContext.HttpContext.Response.Redirect("~/Error.html");
            base.OnException(filterContext);
        }

3、FilterConfigクラスで以下の修正を行います.
 public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            //filters.Add(new HandleErrorAttribute());

            //filters.Add(new MyErrorAttribute());
            filters.Add(new MyExceptionAttribute());
        }
}

4、Gobal.asax.csでのApplication_Startイベントには次のコードが追加されます.
log4net.Config.XmlConfigurator.Configure(); //  Log4Net    
            ThreadPool.QueueUserWorkItem(o =>
            {
                while (true)
                {
                    if (MyExceptionAttribute.redisClient.GetListCount("errorMsg") > 0)
                    {
                        string msg = MyExceptionAttribute.redisClient.DequeueItemFromList("errorMsg");
                        if (!string.IsNullOrEmpty(msg))
                        {
                            ILog logger=LogManager.GetLogger("testError");
                            logger.Error(msg); //       Log4Net 
                        }
                        else
                        {
                            Thread.Sleep(50);
                        }
                    }
                    else
                    {
                        Thread.Sleep(50);
                    }
                }
            });