リモートマシンからイベントログ (アプリケーション) を読み取るアプリケーションに取り組んでいます。.net で EventLog クラスを使用してから、ログ エントリを繰り返し処理していますが、これは非常に遅いです。場合によっては、一部のマシンに 40000 以上のログ エントリがあり、エントリを反復処理するのに何時間もかかります。このタスクを達成するための最良の方法は何ですか? .net に、より高速な、または他のテクノロジの他のクラスはありますか?
9 に答える
男、私はあなたの痛みを感じます。アプリでもまったく同じ問題が発生しました。
ソリューションには、実行しているサーバーのバージョンと、「ターゲット」マシンが実行しているサーバーのバージョンに応じて分岐があります。
両方とも Vista または Windows Server 2008 を使用している場合は、幸運です。System.Diagnostics.Eventing.Reader.EventLogQuery
およびを参照してくださいSystem.Diagnostics.Eventing.Reader.EventLogReader
。これらは .net 3.5 の新機能です。
基本的に、XML でクエリを作成し、送信してリモート コンピューターで実行することができます。特定のタイプのイベントを検索しているだけかもしれませんし、特定の時点からの新しいイベントを検索しているだけかもしれません。検索はリモート マシンで実行され、一致するイベントが返されます。新しいクラスは、古い .net 2.0 の方法よりもはるかに高速ですが、Vista または Windows Server 2008 でのみサポートされています。
ターゲットが Vista/Win2008 でない場合のアプリでは、リモート システムから生の .evt ファイルをダウンロードし、そのバイナリ形式を使用してファイルを解析しました。.evt ファイル (Vista 以前) のイベント ログ形式に関するデータ ソースはいくつかあります。たとえば、リンク テキストや、codeproject.com でいくつかの C# コードを含む記事を思い出しました。
Vista および Windows Server 2008 マシンは、新しい形式である新しい .evtx 形式を使用するため、すべてのバージョンで同じバイナリ解析アプローチを使用することはできません。しかし、新しい EventLogQuery および EventLogReader クラスは非常に高速であるため、その必要はありません。組み込みクラスを使用するだけで、完全に高速になりました。
イベント ログ リーダーは恐ろしく遅いです...遅すぎます。マイクロソフト?
LogParser 2.2 を使用する - インターネットで C# と LogParser を検索します (または、コマンド ラインからログ パーサー コマンドを使用できます)。他の人がすでに寄稿した作品を複製したくありません。
ログを EVTX ファイルとしてエクスポートすることで、リモート システムからログをプルします。次に、リモート システムからファイルをコピーします。このプロセスは非常に迅速です。ネットワークが地球全体にまたがっていても (ログをネットワーク リソースにエクスポートする際に問題がありました)。ローカルに配置したら、検索と処理を行うことができます。
EVTX を使用する理由は複数ありますが、その理由については説明しません。
以下は、ログのコピーを EVTX として保存するコードの実例です。 Security」、または「Application」。outputPathOnRemoteSystem は、「c:\temp\%hostname%.%LogName%.%YYYYMMDD_HH.MM%.evtx」などのリモート コンピューター上のパスです。)
static public bool DumpLog(string device, string LogName, string outputPathOnRemoteSystem, out string errMessage)
{
bool wasExported = false;
string errorMessage = "";
try
{
System.Diagnostics.Eventing.Reader.EventLogSession els = new System.Diagnostics.Eventing.Reader.EventLogSession(device);
els.ExportLogAndMessages(LogName, PathType.LogName, "*", outputPathOnRemoteSystem);
wasExported = true;
}
catch (UnauthorizedAccessException e)
{
errorMessage = "Unauthorized - Access Denied: " + e.Message;
}
catch (EventLogNotFoundException e)
{
errorMessage = "Event Log Not Found: " + e.Message;
}
catch (EventLogException e)
{
errorMessage = "Export Failed: " + e.Message + ", Log: " + LogName + ", Device: " + device;
}
errMessage = errorMessage;
return wasExported;
}
たぶんWMIはあなたを助けることができます:
ログをファイルに保存してWebアプリケーションに送信するプログラムをマシンに配置できます。ループローカルを実行できるため、はるかに高速になると思いますが、その方法がわからないため、コードを取得できません。 (
PowerShell 2.0 のリモート機能を試してみましたか? リモート マシンでコマンドレット (イベント ログを読み取るコマンドレットなど) を実行し、呼び出し元のセッションに結果を (もちろんオブジェクトとして) 返すことができます。