更新: System.Diagnosticsの拡張については、必要ないくつかの欠落しているリスナーを提供しています。CodePlexのEssential.Diagnostics(http://essentialdiagnostics.codeplex.com/)を参照してください。
フレームワーク
Q:どのフレームワークを使用していますか?
A:System.Diagnostics.TraceSource、.NET 2.0に組み込まれています。
これは、アプリケーションに強力で柔軟な高性能のロギングを提供しますが、多くの開発者はその機能を認識しておらず、それらを十分に活用していません。
追加機能が役立つ、または機能が存在するが十分に文書化されていない領域がいくつかありますが、これは、(拡張可能に設計された)ロギングフレームワーク全体を破棄し、一般的な代替手段のように完全に置き換える必要があることを意味しません(NLog、log4net、Common.Logging、さらにはEntLib Logging)。
ロギングステートメントをアプリケーションに追加する方法を変更してホイールを再発明するのではなく、必要ないくつかの場所でSystem.Diagnosticsフレームワークを拡張しただけです。
EntLibでさえ、他のフレームワークは単にNot Invented Here Syndromeに悩まされているように思えますが、System.Diagnosticsで正常に機能する基本(ログステートメントの記述方法など)を再発明するために時間を浪費していると思います。存在するいくつかのギャップを埋めるのではなく。つまり、それらを使用しないでください。それらは必要ありません。
あなたが知らなかったかもしれない機能:
- Filter.ShouldTrace()が成功するまでパラメーターが個別の参照として保持されるため、フォーマット文字列と引数を受け取るTraceEventオーバーロードを使用すると、パフォーマンスが向上します。これは、システムがメッセージが実際にログに記録されることを確認した後まで、パラメーター値でのToString()への負荷の高い呼び出しがないことを意味します。
- Trace.CorrelationManagerを使用すると、同じ論理演算に関するログステートメントを相互に関連付けることができます(以下を参照)。
- VisualBasic.Logging.FileLogTraceListenerは、ログファイルへの書き込みに適しており、ファイルローテーションをサポートしています。VisualBasic名前空間でも、DLLを含めるだけで、C#(または他の言語)プロジェクトで簡単に使用できます。
- EventLogTraceListenerを使用して、複数の引数と空またはnull形式の文字列でTraceEventを呼び出す場合、ローカライズされたメッセージリソースを使用している場合、引数は直接EventLog.WriteEntry()に渡されます。
- (WCFからの)Service Trace Viewerツールは、(WCFを使用していない場合でも)アクティビティ相関ログファイルのグラフを表示するのに役立ちます。これは、複数のスレッド/アクティビティが関係する複雑な問題のデバッグに役立ちます。
- すべてのリスナーをクリアして(またはデフォルトを削除して)、オーバーヘッドを回避します。それ以外の場合、Defaultはすべてをトレースシステムに渡します(そしてすべてのToString()オーバーヘッドが発生します)。
拡張したい領域(必要な場合):
- データベーストレースリスナー
- 色付きコンソールトレースリスナー
- MSMQ /電子メール/ WMIトレースリスナー(必要な場合)
- 動的構成変更のためにTrace.Refreshを呼び出すFileSystemWatcherを実装する
その他の推奨事項:
構造化されたイベントIDを使用し、参照リストを保持します(列挙型でそれらをドキュメント化するなど)。
システム内の(重要な)イベントごとに一意のイベントIDを持つことは、特定の問題を関連付けて見つけるのに非常に役立ちます。イベントIDをログに記録/使用する特定のコードに戻るのは簡単で、一般的なエラーのガイダンスを簡単に提供できます。たとえば、エラー5178はデータベース接続文字列が間違っていることを意味します。
イベントIDは、特定のコードを知らなくてもカテゴリー別にそれらを扱うことができる(電子メールおよびHTTPで使用される応答コードの理論に類似した)ある種の構造に従う必要があります。
たとえば、最初の桁は一般クラスの詳細を示すことができます。1xxxは「開始」操作に使用でき、2xxxは通常の動作、3xxxはアクティビティトレース、4xxxは警告、5xxxはエラー、8xxxは「停止」操作、9xxxは致命的なエラー、等
2桁目は領域の詳細を示すことができます。たとえば、データベース情報の21xx(データベース警告の41xx、データベースエラーの51xx)、計算モードの22xx(計算警告の42xxなど)、別のモジュールの23xxなどです。
割り当てられた構造化イベントIDを使用すると、それらをフィルターで使用することもできます。
Q:トレースを使用する場合、Trace.Correlation.StartLogicalOperationを使用しますか?
A:Trace.CorrelationManagerは、あらゆる種類のマルチスレッド環境でログステートメントを相関させるのに非常に役立ちます(最近のほとんどのものです)。
相関させるためには、少なくとも論理操作ごとに1回はActivityIdを設定する必要があります。
Start / StopとLogicalOperationStackは、単純なスタックベースのコンテキストに使用できます。より複雑なコンテキスト(非同期操作など)の場合、TraceTransferを新しいActivityIdに(変更する前に)使用すると、相関が可能になります。
Service Trace Viewerツールは、アクティビティグラフの表示に役立ちます(WCFを使用していない場合でも)。
Q:このコードを手動で記述していますか、それともアスペクト指向プログラミングの何らかの形式を使用して記述していますか?コードスニペットを共有しますか?
A:たとえば、LogicalOperationScopeなどのスコープクラスを作成すると、(a)作成時にコンテキストが設定され、(b)破棄されるときにコンテキストがリセットされます。
これにより、次のようなコードを記述して、操作を自動的にラップできます。
using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
{
// .. do work here
}
作成時に、スコープは必要に応じて最初にActivityIdを設定し、StartLogicalOperationを呼び出してから、TraceEventType.Startメッセージをログに記録できます。Disposeでは、Stopメッセージをログに記録してから、StopLogicalOperationを呼び出すことができます。
Q:トレースソースに対して何らかの形式の粒度を提供していますか?たとえば、WPF TraceSourcesを使用すると、さまざまなレベルでそれらを構成できます。
A:はい。システムが大きくなるにつれて、複数のトレースソースが役立ちます。
おそらくすべての警告以上、またはすべての情報以上のメッセージを一貫してログに記録する必要がある一方で、妥当なサイズのシステムでは、アクティビティトレース(開始、停止など)と冗長ログの量が単純に多すぎます。
すべてをオンまたはオフにするスイッチを1つだけ持つのではなく、システムの1つのセクションでこの情報を一度にオンにできると便利です。
このようにして、通常のロギング(すべての警告、エラーなど)から重大な問題を特定し、必要なセクションを「拡大」して、それらをアクティビティトレースまたはデバッグレベルに設定できます。
必要なトレースソースの数はアプリケーションによって異なります。たとえば、アプリケーションごとに、またはアプリケーションの主要セクションごとに1つのトレースソースが必要になる場合があります。
さらに細かい調整が必要な場合は、個々のブールスイッチを追加して、生のメッセージダンプなど、特定の大量のトレースをオン/オフにします。(または、WCF / WPFと同様に、別のトレースソースを使用できます)。
また、アクティビティトレースと一般的な(その他の)ログのトレースソースを個別に検討することもできます。これにより、フィルターを希望どおりに構成することが少し簡単になります。
異なるソースが使用されている場合でも、ActivityIdを介してメッセージを関連付けることができるため、必要な数だけ使用してください。
リスナー
Q:どのログ出力を使用しますか?
これは、作成しているアプリケーションのタイプ、およびログに記録されているものによって異なります。通常、異なるものは異なる場所に行きます(つまり、複数の出力)。
私は通常、出力を3つのグループに分類します。
(1)イベント-Windowsイベントログ(およびトレースファイル)
たとえば、サーバー/サービスを作成する場合、Windowsでのベストプラクティスは、Windowsイベントログを使用することです(レポートするUIがありません)。
この場合、すべての致命的、エラー、警告、および(サービスレベルの)情報イベントは、Windowsイベントログに記録されます。情報レベルは、これらのタイプの高レベルのイベント、たとえば「Service Started」、「Service Stopped」、「Connected to Xyz」、さらには「Schedule Initiated」など、イベントログに記録するイベント用に予約する必要があります。 、「ユーザーログオン」など
場合によっては、イベントログへの書き込みを、トレースシステムを介さずにアプリケーションの組み込み部分にすることもできます(つまり、イベントログエントリを直接書き込みます)。つまり、誤ってオフにすることはできません。(相関することができるように、トレースシステムの同じイベントにも注目したいことに注意してください)。
対照的に、Windows GUIアプリケーションは通常、これらをユーザーに報告します(ただし、Windowsイベントログに記録される場合もあります)。
イベントには関連するパフォーマンスカウンター(エラー数/秒など)も含まれる場合があり、イベントログ、パフォーマンスカウンターへの直接の書き込み、トレースシステムへの書き込み、およびユーザーへのレポートを調整して、イベントが発生するようにすることが重要です。同時に。
つまり、ユーザーが特定の時間にエラーメッセージを表示した場合、Windowsイベントログで同じエラーメッセージを見つけ、トレースログで同じタイムスタンプを持つ同じイベントを(他のトレースの詳細とともに)見つけることができます。
(2)アクティビティ-アプリケーションログファイルまたはデータベーステーブル(およびトレースファイル)
これは、システムが実行する通常のアクティビティです。たとえば、提供されたWebページ、提出された株式市場の取引、受注、計算の実行などです。
アクティビティトレース(開始、停止など)は、ここで(適切な単位で)役立ちます。
また、特定のアプリケーションログ(監査ログと呼ばれることもあります)を使用することは非常に一般的です。通常、これはデータベーステーブルまたはアプリケーションログファイルであり、構造化データ(つまり、フィールドのセット)が含まれています。
アプリケーションによっては、状況が少し不鮮明になる場合があります。良い例は、各リクエストをWebログに書き込むWebサーバーです。同様の例は、メッセージングシステムや計算システムであり、各操作はアプリケーション固有の詳細とともにログに記録されます。
それほどよくない例は、株式市場の取引や販売注文システムです。これらのシステムでは、重要なビジネス価値があるため、おそらくすでにアクティビティをログに記録していますが、それらを他のアクションに関連付ける原則は依然として重要です。
カスタムアプリケーションログだけでなく、アクティビティには、関連するパフォーマンスカウンター(1秒あたりのトランザクション数など)も含まれていることがよくあります。
一般に、さまざまなシステム間でアクティビティのロギングを調整する必要があります。つまり、パフォーマンスカウンターを増やしてトレースシステムにログを記録すると同時に、アプリケーションログに書き込みます。すべてを同時に(またはコード内で互いに続けて)実行すると、問題のデバッグが容易になります(コード内の異なる時間/場所ですべてが発生する場合よりも)。
(3)デバッグトレース-テキストファイル、またはXMLまたはデータベース。
これは、詳細レベル以下の情報です(たとえば、生データダンプをオン/オフにするカスタムブールスイッチ)。これは、システムがサブアクティビティレベルで何をしているかの根本または詳細を提供します。
これは、アプリケーションの個々のセクション(したがって複数のソース)のオン/オフを切り替えられるようにするレベルです。このようなものがWindowsイベントログを雑然とさせたくありません。データベースが使用されることもありますが、一定の時間が経過するとパージされるローリングログファイルである可能性が高くなります。
この情報とアプリケーションログファイルの大きな違いは、構造化されていないことです。アプリケーションログにはTo、From、Amountなどのフィールドが含まれる場合がありますが、詳細なデバッグトレースは、プログラマーが入力したもの、たとえば「X = {value}、Y = falseのチェック」、または「やり直してください。」
重要なプラクティスの1つは、アプリケーションログファイルまたはWindowsイベントログに記録したものも同じ詳細(タイムスタンプなど)でトレースシステムに記録されるようにすることです。これにより、調査時にさまざまなログを関連付けることができます。
Service Trace Viewerなどの複雑な相関関係があるために特定のログビューアを使用する場合は、適切な形式、つまりXMLを使用する必要があります。それ以外の場合は、通常、単純なテキストファイルで十分です。低レベルでは情報はほとんど構造化されていないため、配列のダンプやスタックダンプなどが見つかる可能性があります。より高いレベルでより構造化されたログに関連付けることができれば、大丈夫です。
Q:ファイルを使用する場合、ローリングログを使用しますか、それとも単一のファイルを使用しますか?人々がログを利用できるようにするにはどうすればよいですか?
A:ファイルの場合、通常、管理性の観点からログファイルをローリングする必要があります(System.Diagnosticsでは、単にVisualBasic.Logging.FileLogTraceListenerを使用します)。
可用性はシステムにも依存します。ファイルについてのみ話している場合は、サーバー/サービスの場合、必要なときにローリングファイルにアクセスできます。(Windowsイベントログまたはデータベースアプリケーションログには独自のアクセスメカニズムがあります)。
ファイルシステムに簡単にアクセスできない場合は、データベースへのデバッグトレースの方が簡単な場合があります。[データベースTraceListenerを実装する]。
Windows GUIアプリケーションで見た興味深い解決策の1つは、実行中に非常に詳細なトレース情報を「フライトレコーダー」に記録し、問題がなければシャットダウンしたときにファイルを削除することでした。
ただし、クラッシュまたは問題が発生した場合、ファイルは削除されませんでした。エラーをキャッチした場合、または次回実行したときにファイルに気づき、圧縮(例:7zip)などのアクションを実行してメールで送信したり、他の方法で利用できるようにします。
最近の多くのシステムには、中央サーバーへの障害の自動報告が組み込まれています(プライバシー上の理由などでユーザーに確認した後)。
見る
Q:ログの表示に使用するツールは何ですか?
A:さまざまな理由で複数のログがある場合は、複数のビューアを使用します。
Notepad / vi / Notepad ++またはその他のテキストエディタは、プレーンテキストログの基本です。
転送を伴うアクティビティなどの複雑な操作がある場合は、Service Trace Viewerなどの専用ツールを使用します。(ただし、必要ない場合は、テキストエディターの方が簡単です)。
私は通常、Windowsイベントログに高レベルの情報を記録するので、構造化された方法で概要をすばやく取得できます(かなりのエラー/警告アイコンを探します)。ログに十分な量がない場合は、少なくともログから開始点がわかりますが、テキストファイルを探し始める必要があります。(この時点で、ログが全体を調整していることを確認することが有用になります)。
通常、Windowsイベントログでは、これらの重要なイベントをMOMやOpenViewなどの監視ツールで利用できるようにします。
その他-
データベースにログインすると、情報のフィルタリングと並べ替えが簡単になります(たとえば、特定のアクティビティIDにズームインします。(テキストファイルでは、Grep / PowerShellなどを使用して、必要な特定のGUIDでフィルタリングできます)
MS Excel(または別のスプレッドシートプログラム)。これは、構造化された情報または半構造化された情報を適切な区切り文字でインポートして、異なる値が異なる列に入るように分析できる場合に役立ちます。
デバッグ/テストでサービスを実行するとき、私は通常、簡単にするためにコンソールアプリケーションでホストします。たとえば、色付きのコンソールロガーが便利です(たとえば、エラーには赤、警告には黄色など)。カスタムトレースリスナーを実装する必要があります。
フレームワークには色の付いたコンソールロガーやデータベースロガーが含まれていないため、現時点では、必要に応じてこれらを記述する必要があります(それほど難しくありません)。
いくつかのフレームワーク(log4net、EntLibなど)がホイールを再発明し、基本的なロギング、フィルタリング、およびテキストファイル、Windowsイベントログ、XMLファイルへのロギングを再実装して時間を無駄にしてしまったことは本当に私を困らせます異なる方法(ログステートメントはそれぞれ異なります); 次に、それぞれが独自のバージョンのデータベースロガーなどを実装しましたが、そのほとんどはすでに存在し、必要なのはSystem.Diagnosticsのトレースリスナーが2、3個だけでした。重複した努力の大きな無駄について話します。
Q:ASP.NETソリューションを構築している場合、ASP.NETヘルスモニタリングも使用しますか?ヘルスモニターイベントにトレース出力を含めますか?Trace.axdはどうですか?
これらは必要に応じてオン/オフを切り替えることができます。Trace.axdは、サーバーが特定の事柄にどのように応答するかをデバッグするのに非常に役立ちますが、頻繁に使用される環境や長期的なトレースには一般的に役立ちません。
Q:カスタムパフォーマンスカウンターはどうですか?
プロフェッショナルアプリケーション、特にサーバー/サービスの場合、パフォーマンスモニターカウンターとWindowsイベントログへのログ記録の両方が完全に装備されているのを期待しています。これらはWindowsの標準ツールであり、使用する必要があります。
使用するパフォーマンスカウンターとイベントログのインストーラーを必ず含める必要があります。これらはインストール時に作成する必要があります(管理者としてインストールする場合)。アプリケーションが正常に実行されている場合は、管理者権限を持っている必要はありません(そのため、不足しているログを作成できません)。
これは、非管理者としての開発を実践するのに適した理由です(サービスをインストールする必要がある場合などのために、個別の管理者アカウントを持っています)。イベントログに書き込む場合、.NETは最初にログに書き込むときに欠落しているログを自動的に作成します。非管理者として開発する場合は、これを早期にキャッチし、顧客がシステムをインストールして管理者として実行していないためにシステムを使用できない場合の厄介な驚きを回避します。