2012-11-15 5 views
9

私は私のプロジェクトの1つで解決する必要があるこの問題があります。 3つの異なるサービス用に1つのログファイルを作成する必要があります(私の上司がこれを要求した理由を聞かないでください)。各サービスは、ファイルに情報を記録しようとする複数のスレッドを持つことができるので、私の質問は、これを行うための最善の方法は何ですか?複数のサービス(複数のスレッドを持つ各サービス)間でログファイルを共有する方法は?

グローバルミューテックスを使用する必要がありますか?このようなもの:

procedure LogToFile(fn, str: string); 
var 
    F: TextFile; 
begin 
    logMutex.Acquire; 
    try 
{$I+} 
    try 
     AssignFile(F, fn); 
     if FileExists(fn) then 
     Append(F) 
     else 
     Rewrite(F); 
     Writeln(F, DateTimeToStr(Now) + ': ' + str); 
     CloseFile(F); 
    except 
    end; 
{$I-} 
    finally 
     logMutex.Release; 
    end; 
end; 

initialization 
    logMutex := SyncObjs.TMutex.Create(nil, False,'some_global_mutex'); 

finalization 
    logMutex.Free; 

もっと良いアイディアですか?

編集:他のサービスからログに記録する必要のあるメッセージを待ってから、ログファイルを処理するサービスが1つだけ必要な別のサービス、ログサービスをビルドしますか?これが良い解決策であれば、サービス間で通信する最良の方法は何ですか?私はインディを使用することができます...

+3

http://www.raize.com/DevTools/CodeSite/Default.aspからCodeSiteを試してください –

+1

私の会社は独自のログサービスを作成しました。フリースレッドのCOMオブジェクトを使用して、アプリケーションがログメッセージをサービスにプッシュできるようにしてから、必要に応じてメッセージをキューに入れてログファイルに書き出します。また、プレーンテキストファイルの代わりにWindowsシステムイベントログを使用することを検討することもできます。その後、アプリケーションは 'ReportEvent()'を使ってそのログにメッセージを送信し、OSに実際のログファイルを処理させることができます。 –

+1

私は別のロガーサービスを書いて、ウィンドウWM_COPYDATAメッセージを使って3つのサービスにメッセージを送るようにします。特に、そのログサービスはファイルを開いたままにしておくことができるためです。常にファイルを開くのが遅くなります。申し訳ありませんが、私は現時点でサンプルコードにアクセスできる場所ではありません。 –

答えて

3

名前付きミューテックスを使ったあなたのソリューションは動作しますし、確かに最も簡単なアプローチです。

2

複数のターミナルサーバーで実行されている約50-80のアプリケーション(同期が難しい)を持つ大きなプロジェクトでは、すべてのログ出力を1つの中央ファイルに集めることができました。

アプリケーションは、オープンソースLog4D frameworkとインターネットダイレクト(Indy)を使用して、ログ出力をUDP経由でアプリケーションサーバーに書き込みます。アプリケーションサーバーには、ログメッセージを受信して​​単一のファイルに書き込むUDPサーバーアプリケーションが実行されています。

ログメッセージにはメタ情報(ロガー名など)が含まれているため、メインファイルに加えてアプリケーションごとに別々のファイルを書き込むようにログサーバーを設定することもできます。たとえば、クライアントから送信されたログメッセージの中には、データベースのパフォーマンスデータが含まれているものがあります。別のログファイルに書き込まれ、フィルタリングのステップを追加することなく解析準備が整います。

関連する問題