EventSource
クラスを使用して ETW イベントを発行するように .NET 4.5 アプリケーションをインストルメント化しています。目標は、エラー ログ用にこれらのイベント (エラー レベル イベント) の一部をキャプチャできるようにすることです。
いくつかの読み取りとテストを行った後、エラーログへのこのアプローチの信頼性、特にイベントのドロップまたは欠落の可能性について懸念しています。エラー ログが機能しない場合は、アプリケーションをシャットダウンする必要があります (私の場合、報告されていないエラーで実行するのは安全ではありません)。ETW と を使用しEventSource
ている場合、エラーが適切に記録されていることを確認するにはどうすればよいですか?
明らかに、答えの一部は、何がイベントをリッスンしているかによって異なります。私の場合、最新の MS Enterprise Library の「Semantic Logging Application Block」を使用する予定です。
以下は、Microsoft が見逃したイベントの考えられる原因について話しているソースの 1 つです。 イベント トレーシングについて
そこには、欠落イベントの考えられる原因がリストされています
イベントの合計サイズが 64K を超えています。これには、ETW ヘッダーとデータまたはペイロードが含まれます。イベントのサイズはアプリケーションによって設定されるため、ユーザーはこれらの欠落したイベントを制御することはできません。
ETW バッファー サイズが合計イベント サイズよりも小さい。イベントのサイズはイベントをログに記録するアプリケーションによって設定されるため、ユーザーはこれらの欠落したイベントを制御することはできません。
リアルタイム ログの場合、リアルタイム コンシューマーがイベントを十分に高速に消費していないか、完全に存在しないため、バッキング ファイルがいっぱいになります。これは、イベントがログに記録されているときにイベント ログ サービスが停止され、開始された場合に発生する可能性があります。ユーザーは、これらの欠落したイベントを制御できません。
ファイルにログを記録するとき、ディスクが遅すぎてログ速度に追いつけません。
これらの懸念が EventSource クラスを使用して何らかの方法で緩和されたかどうか (たとえば、大きなペイロードを何らかの方法で切り捨てるかどうか) を確認するために、いくつかのテストを行いました。長い文字列をログに記録しようとしましたが、30,000 から 35,000 文字の間で失敗しました (64KB の最大イベント ペイロードと一致しています)。大きすぎる文字列について私が知ることができることから、黙って何もしません。セマンティック ログのアプリケーション ブロック ログにイベントはまったくありません。前後の出来事はいつものように書かれています。
ペイロードに文字列があるときはいつでも、トランケータを介して渡す必要がありますか? 「速すぎる」イベントの生成を手動で回避する必要がありますか (また、それはどのように可能でしょうか)。
Microsoft のパターンとプラクティスは、私たちを適切なパターンとプラクティスに導くはずなので、ここで何かが欠けているだけかもしれません。
アップデート:
どうやら、「イベントが速すぎる」状態について、消費アプリケーションに何らかの通知があるようです。今日初めてこれを受け取りました:
レベル: 警告、メッセージ: トレース セッションでのバッファー オーバーランまたはスキーマ同期の遅延により、一部のイベントが失われます: Microsoft-SemanticLogging-Etw-svcRuntime
そして、セッションを閉じるとき:
レベル: 警告、メッセージ: トレース セッション 'Microsoft-SemanticLogging-Etw-svcRuntime' で 1 つのイベントの損失が検出されました。
アップデート2:
Enterprise Library Developers Guideでは、先ほど説明した動作について説明しています。
セマンティック ログ アプリケーション ブロックによって生成されたログ メッセージを監視して、バッファがオーバーフローしたことやメッセージが失われたことを示す兆候がないかどうかを確認する必要があります。たとえば、イベント ID 900 および 901 のログ メッセージは、シンクの内部バッファがオーバーフローしたことを示します。アウト プロセス シナリオでは、イベント ID 806 および 807 は、ETW バッファーがオーバーフローしたことを示します。シンクのバッファリング構成オプションを変更して、通常のワークロードでバッファがオーバーフローする可能性を減らすことができます。
エラーがドロップされた場合にアプリケーションが実行されないようにしながら、セマンティック ロギングを使用できますか? 通常のトレース イベントがドロップされる可能性があります ...
私の現在の考えでは、昔ながらのロギング手法を使用して別のクラスで「重大な」エラーをログに記録し、重大度の低いエラー (およびデバッグ タイプのイベント) は ETW パイプラインを通過するようにします。それはそれほど悪くはありません...より良い提案が見つからない場合は、解決策として投稿するかもしれません.
更新 3:
string
私が受け取った「missing events」という警告は、バッファ オーバーランとは何の関係もありませんでした。これは、ペイロード値としてnull を渡した場合に表示されるメッセージであることがわかりました。