2

環境: 任意の .Net Framework を歓迎します。24 時間 365 日書き込まれるログ ファイルがあります。

ログ ファイルを読み取ってデータを処理するアプリケーションを作成しようとしています。

ログ ファイルを効率的に読み取るための最良の方法は何ですか? FileSystemWatcher のようなものでファイルを監視することを想像します。しかし、アプリケーションによって処理された後、同じデータを読み取らないようにするにはどうすればよいでしょうか? または、アプリケーションがなんらかの理由で中断した場合、最後に中断したところからどのように再開するのでしょうか?

通常、ログ ファイル内のペイロードの周りにヘッダーとフッターがあります。おそらく、コンテンツの id フィールドも同様です。そこにある id フィールドについてはまだわかりません。

また、ブックマークとして使用するために、行の読み取りカウントをどこかに保存することも想像しました。

4

4 に答える 4

1

ファイルにログを記録する理由はありますか? ファイルが優れているのは、使いやすいことと、最も一般的な分母であるため、問題が発生する可能性が比較的少ないことです。ただし、ファイルには制限があります。あなたが言うように、ファイルを読み取ったときにファイルへの書き込みが完了するという保証はありません。複数のアプリケーションがログに書き込みを行うと、互いに干渉する可能性があります。簡単な並べ替えやフィルタリングのメカニズムはありません。ログ ファイルは非常に急速に大きくなる可能性があり、古いイベント (たとえば、24 時間以上前のもの) をバックアップと保持のために別のファイルに移動する簡単な方法はありません。

代わりに、ログをデータベースに書き込むことを検討します。テーブル構造は非常に単純ですが、トランザクションの利点を活用して (抽出やバックアップを簡単に行うことができます)、ほぼ普遍的に理解されている構文を使用して検索、並べ替え、フィルター処理を行うことができます。負荷の急増が心配な場合は、SQL Serverのhttp://msdn.microsoft.com/en-us/library/ms190495.aspxなどのメッセージ キューを使用してください。

移行を容易にするために、log4netなどのロギング フレームワークの使用を検討してください。この多くをコードから抽象化します。

もう 1 つの方法は、syslogなどのシステムを使用するか、複数のサーバーと大量のログがある場合はFlumeを使用することです。ログ ファイルをソース コンピューターから移動することで、ログ ファイルを別のコンピューターに保存したり、より効果的に検査したりできます。ただし、これらはおそらく現在の問題に対してはやり過ぎです。

于 2012-09-06T04:37:17.693 に答える
1

まあ、あなたはあなたの特定のケースのためのあなたの魔法を自分で理解しなければならないでしょう. よく知られているテキスト エンコーディングを使用する場合、それは非常に単純なことです。System.IO.StreamReader に目を向けると、それは ReadLine()、DiscardBufferedData() メソッド、および BaseStream プロパティです。ファイルが追加されているだけであることが確実であれば、ファイル内の最後の位置を覚えておいて、後でその位置に巻き戻し、もう一度読み始めることができるはずです。他にも考慮すべき点があり、これに対する唯一の普遍的な答えはありません。

単純な例として (動作させるにはまだ多くの調整が必要な場合があります):

    static void Main(string[] args)
    {
        string filePath = @"c:\log.txt";
        using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (var streamReader = new StreamReader(stream,Encoding.Unicode))
            {
                long pos = 0;
                if (File.Exists(@"c:\log.txt.lastposition"))
                {
                    string strPos = File.ReadAllText(@"c:\log.txt.lastposition");
                    pos = Convert.ToInt64(strPos);
                }
                streamReader.BaseStream.Seek(pos, SeekOrigin.Begin); // rewind to last set position.
                streamReader.DiscardBufferedData(); // clearing buffer
                for(;;)
                {
                    string line = streamReader.ReadLine();
                    if( line==null) break;

                    ProcessLine(line);
                }
                // pretty sure when everything is read position is at the end of file.
                File.WriteAllText(@"c:\log.txt.lastposition",streamReader.BaseStream.Position.ToString());
            }
        }
    }
于 2012-09-06T03:43:00.840 に答える