ロギングのベストプラクティス[終了]


323

人々が実際のアプリケーションでトレースとロギングをどのように処理しているかについてのストーリーを入手したいと思います。あなたの答えを説明するのに役立つかもしれないいくつかの質問があります。

フレームワーク

どのフレームワークを使用していますか?

  • log4net
  • System.Diagnostics.Trace
  • System.Diagnostics.TraceSource
  • ロギングアプリケーションブロック
  • その他?

トレースを使用する場合、Trace.Correlation.StartLogicalOperationを使用しますか?

このコードを手動で記述していますか、それともアスペクト形式のプログラミングを何らかの形で使用していますか?コードスニペットを共有しますか?

トレースソースに対して何らかの粒度を提供していますか?たとえば、WPF TraceSourcesを使用すると、さまざまなレベルでそれらを構成できます。

  • System.Windows- すべてのWPFの設定
  • System.Windows.Animation- 特にアニメーションのオーバーライド。

リスナー

どのログ出力を使用しますか?

  • テキストファイル
  • XMLファイル
  • イベントログ
  • その他?

ファイルを使用する場合、ローリングログを使用しますか、それとも単一のファイルを使用しますか?人々がログを利用できるようにするにはどうすればよいですか?

見る

ログの表示にどのツールを使用しますか?

  • メモ帳
  • イベントビューアー
  • Systems Center Operations Manager / Microsoft Operations Manger
  • WCFサービストレースビューアー
  • その他?

ASP.NETソリューションを構築している場合、ASP.NETヘルスモニタリングも使用しますか?ヘルスモニターイベントにトレース出力を含めますか?Trace.axdはどうですか?

カスタムパフォーマンスカウンターについてはどうですか?


3
このような質問を300の賛成票で締めくくる人が、Wiki形式またはprogrammers.stackexchangeへの投稿のいずれか、あるいはこのタイプの質問が歓迎されない場合はQuoraのいずれかを提案できると役立つでしょう。明らかに、質問は実際には非常に建設的であり、StackOverflowが必要とする基準に適合しないだけです。programmers.stackexchange.com/questions/57064/…には24の賛成票があります。おそらくStackOverflowに何か不足していますか?
Niall Connaughton

この質問がQ&A形式に違反している場合、この質問ではなく、Q&A形式に問題があります。質問をクローズするかどうかの決定は、提供された回答の関数である場合があります。自由回答式の質問の中には討論を招くものもありますが、このような貴重なコンテンツを提供するようにユーザーを招待するものもあります。
Matthias Wolf

1
この質問、特にトップの回答は、誰かがそのように使用したい場合、おそらくブログ投稿の優れた基盤になるでしょう...客観的な質問として、それは実際には適合しません-ストロー投票として明示的に構成されています-しかし以下にいくつかの良い情報があるので、ロックです。
Shog9 2013年

回答:


232

更新: 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は最初にログに書き込むときに欠落しているログを自動的に作成します。非管理者として開発する場合は、これを早期にキャッチし、顧客がシステムをインストールして管理者として実行していないためにシステムを使用できない場合の厄介な驚きを回避します。


参考:ファイルへのMicrosoftトレースがクラッシュする問題が発生しました。同じファイルに書き込む複数のプロセス(またはスレッド)があり、それらが衝突すると、ログファイルでファイルシステムの排他的アクセスロックエラーが発生します。
ジェイ

1
System.Diagnosticsインフラストラクチャはスレッドセーフです。デフォルトの動作はフレームワークのロックですが、独自のロックを提供する場合は、TraceListener.IsThreadSafeをオーバーライドできます。msdn.microsoft.com/en-us/library/…を参照してください。複数のプロセスの場合、通常は別々のファイルに書き込みますが、Service Trace Viewerは複数のトレースファイルを(たとえば、複数のマシンから)ロードして、ActivityIdを介してそれらを関連付けることができることに注意してください。
Sly Gryphon

1
TraceEvent()を使用して例外をログに記録する方法を提案できますか?
Dmitriy Sosunov 2012年

1
フラグを使用してコードをコンパイルすることがほとんどない本番環境で使用できなくなる、System.Diagnostics.Traceデコレーションの大きな欠点の1つではありませんか?[Conditional("TRACE")]TRACE
アスビョルンUlsberg

2
@asbjornu Visual Studioのデフォルトのリリースビルド構成にはTRACEが定義されています(リリースビルドでは無効になっているのはDEBUGです)。ただし、コマンドラインからビルドする場合は、オンにする必要があります。
Sly Gryphon 2013

40

私の場合、プラットフォームの柔軟性(デスクトップ.N​​et / Compact Framework、32/64ビット)の観点から来ているlog4netを推奨する合唱団に参加する必要があります。

ただし、プライベートラベルAPIでラップすることは、主要なアンチパターンです。 log4net.ILoggerCommons LoggingラッパーAPIの.Net対応物であり、カップリングはすでに最小化されています。また、これはApacheライブラリでもあるため、制御を放棄していないので、通常は心配する必要もありません。必要があります。

私が見たほとんどのハウスラッパーライブラリは、1つ以上の多くの障害をコミットします。

  1. グローバルシングルトンロガー(または同等の静的エントリポイント)を使用すると、他の選択性の向上のために推奨されるクラスごとのロガーパターンの細かい解像度が失われます。
  2. オプションのException引数を公​​開しないと、複数の問題が発生します。
    • 例外ログポリシーを維持するのがさらに難しくなるため、例外に一貫して対処することはありません。
    • 一貫したポリシーがあっても、例外を文字列にフォーマットすると、データが早期に失われます。ILayoutイベントのチェーンを判別するために例外で詳細なドリルダウンを実行するカスタムデコレーターを作成しました。
  3. プロパティの公開に失敗しましたIsLevelEnabled。これにより、ログの領域またはレベルがオフになっている場合に、フォーマットコードをスキップする機能が破棄されます。

1
私はlog4jの(恐ろしい)社内ラッパーを少し恐ろしいものにリファクタリングするタスクを課されました(それはまだかなり悪いですが、それはlog4jに与えられた要件を厳しくした結果です)。グローバルな静的エントリポイントを排除しようとしましたが、撃墜されました。本当に要点はわかりません。私たちのセットアップでは、log4jは大幅に拡張されており、実際にはイベントディスパッチャーとして使用されているだけです。「log4jをこれに使用するにはどうすればよいのか」と質問されたので、それだけを使用しています。そのままlog4whateverを使用するか、独自のフレームワークを作成します。中道が痛いです。
Adam Jaskiewicz、2009年

25
log4netをラップしないというあなたの提案には同意しません。これをシンプロバイダーモデルのAPIでラップすると、クラスライブラリのユーザーがお気に入りのログフレームワークをプラグインできます。もちろんYMMVですが、「主要なアンチパターン」としてそれを説明することは少し独断的です。また、「ありふれた障害」を伴うラッパーライブラリが存在するという事実は、適切に記述されたラッパーに対する良い議論ではありません。
Joe

1
アンチパターンと呼んでも、それが常に100%悪い考えであることを意味するわけではありません。注意しないと、角を曲がってしまう傾向があるからです。また、ILog / LogManagerは、それ自体が、log4netアセンブリにバンドルされているcommons-loggingのイメージの中で適切に記述されたラッパーミニライブラリですが、抽出してCLRの適切なcommons-loggingに変換できない理由はありません。
ジェフリー・ハンティン

18

私はasp.netで開発することはあまりありませんが、ロガーに関しては、多くのベストプラクティスが普遍的だと思います。ここに、私が長年にわたって学んだロギングに関する私のランダムな考えのいくつかがあります:

フレームワーク

  • ロガー実装をAPIから分離できるように、slf4j(または独自のロールバック)のようなロガー抽象化フレームワークを使用します。多くのロガーフレームワークが行き来するのを見てきましたが、それほど手間をかけずに新しいフレームワークを採用できるほうがよいでしょう。
  • さまざまな出力形式をサポートするフレームワークを見つけてください。
  • プラグイン/カスタムフィルターをサポートするフレームワークを見つけてみてください。
  • 外部ファイルで構成できるフレームワークを使用して、顧客/消費者がログ出力を簡単に調整できるようにして、市販のログ管理アプリケーションで簡単に読み取れるようにします。
  • カスタムロギングレベルを使いすぎないようにしてください。そうしないと、異なるロギングフレームワークに移動できない場合があります。

ロガー出力

  • 致命的なエラーが発生する可能性のあるログのXML / RSSスタイルのログは避けてください。ロガーがクロージングを書かずに電源スイッチが遮断された場合、これは重要です</xxx>タグをと、ログが壊れるです。
  • ログスレッド。そうしないと、プログラムのフローを追跡することが非常に困難になる可能性があります。
  • ログを国際化する必要がある場合は、開発者に英語(または選択した言語)のみでログインしてもらうことをお勧めします。
  • ロギングステートメントをSQLクエリに挿入するオプションがあると、デバッグの状況で命を救うことがあります。といった:
    -呼び出しクラス:com.foocorp.foopackage.FooClass:9021
    SELECT * FROM foo;
  • クラスレベルのロギングが必要です。通常、ロガーの静的インスタンスも必要ありません-マイクロ最適化の価値はありません。
  • すべての例外が同等に作成されるとは限らないため、ログに記録された例外をマークして分類することは、時々役立ちます。したがって、重要な状態について通知を送信する必要があるログモニターがある場合は、重要な例外のサブセットを事前に知っておくと役立ちます。
  • 複製フィルターは視力とハードディスクを節約します。同じロギングステートメントが10 ^ 10000000回繰り返されることを本当に確認しますか?次のようなメッセージを受け取るだけでよいのではないでしょうか。 This is my logging statement - Repeated 100 times

私のこの質問も見てください。


5
複製フィルターは素晴らしいアイデアです
ポール・ストーベル09/02/23

壊れたタグの問題については以前は同意していましたが、ほとんどの優れたXMLライターはとにかく完全なXMLを使用しない(つまり、ルート要素がない)ため、XML DOMをロードせずにログを記録できます。まれなケースですが、部分的に書き込まれたエントリから問題が発生した場合は、手動で修正できます
Paul Stovell

私は何年もの間XMLロギングを行ったり来たりしてきました。今、それは私には過剰に思えます。アプリケーションのステータスのRSSフィードが必要な場合は、ログ監視ユーティリティを使用して実装するほうがよいと思います。
エリヤ

RSSに同意します。エントリをよりよく理解できる視覚化ツールについてもっと考えています。テキストファイルの場合、通常は1行にエントリを保持します。ただし、スタックトレースやシリアル化されたオブジェクトを含めたい場合があります。ここで、XMLログ(WCFで使用される)が
役立ちます

SQLクエリのインストルメンテーションについて言及する場合は+1。これは、データベーストレースとアプリケーショントレースの相関に非常に役立ちます。DALで手動で実行していますが、この手法にはどのようなツールサポートがありますか?
コンスタンティン

17

私のパンとバターはJavaであるため、.Netのロギングについてコメントする資格はありませんが、過去8年間でロギングに移行があり、質問との類似点が見つかる可能性があります。

最初に、JVM内のすべてのスレッドで使用されるシングルトンロガーから始め、プロセス全体のロギングレベルを設定しました。システムの非常に特定の部分をデバッグする必要がある場合、これは巨大なログをもたらしたので、レッスン1はロギングをセグメント化することです。

ロガーの現在の具体化では、デフォルトとして定義されたインスタンスを持つ複数のインスタンスが許可されます。ロギングレベルが異なる子ロガーをいくつでもインスタンス化できますが、このアーキテクチャの最も有用な側面は、ロギングプロパティを変更するだけで個々のパッケージとクラスのロガーを作成できることです。レッスン2は、コードを変更せずに動作をオーバーライドできる柔軟なシステムを作成することです。

Log4JをラップしたApache commons-loggingライブラリを使用しています。

お役に立てれば!

*編集*

以下のJeffrey Hantinの投稿を読んだ後、私は内部のロギングラッパーが実際にどうなっているのかに注意すべきであることに気付きました。これは基本的にはファクトリーであり、正しいプロパティファイルを使用して動作するロガーを取得するために厳密に使用されます(レガシーの理由により、デフォルトの位置に移動されていません)。ロギング構成ファイルをコマンドラインで指定できるようになったので、それがさらにスリムになると思います。新しいアプリケーションを開始する場合は、ロガーをラップする必要さえないという彼の声明に間違いなく同意します。


答えてくれてありがとう。子ロガーをコードで手動で作成しますか(つまり、ハードコードされていますか)、または何らかの自動/暗黙的な方法で作成しますか?
ポールストーベル2009

いいえ...パッケージまたはクラスのlogging.propertiesファイルにロギング構成を追加すると、それらはその構成ごとにログに記録されますが、特に構成されていないパッケージまたはクラスはデフォルトレベルでログに記録されます。
スティーブモイヤー

9

ロギングプロバイダーとして、Log4Netをログプロバイダーとして使用します(シングルトンラッパーはログインスタンス用ですが、シングルトンは検討中ですが、それらが良いアイデアかどうかを疑問視しています)。

次の理由でそれを選択しました:

  • さまざまな環境でのシンプルな構成/再構成
  • 多数の事前構築されたアペンダー
  • 私たちが使用しているCMSの1つには、すでに組み込まれています。
  • ログレベルとその周りの構成の数が多い

私は言及する必要があります、これはASP.NET開発の観点から話している

.NETフレームワークにあるTraceを使用することにはいくつかのメリットがありますが、主に使用するコンポーネントが実際にはTrace呼び出しを行わないため、完全に販売されていません。私が頻繁に使用する唯一のことはSystem.Net.Mail、私が言えることからです。

したがって、log4netをラップするライブラリーがあり、コード内には次のようなものが必要です。

Logger.Instance.Warn("Something to warn about");
Logger.Instance.Fatal("Something went bad!", new Exception());

try {
  var i = int.Parse("Hello World");
} catch(FormatException, ex) {
  Logger.Instance.Error(ex);
}

メソッド内で、ログレベルが有効になっているかどうかを確認するため、log4net APIへの冗長な呼び出しはありません(したがって、Debugが有効になっていない場合、デバッグステートメントは無視されます)。自分でチェックできるように、それらを公開するように更新します。これにより、たとえば次のようにすべきでないときに評価が行われなくなります。

Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

これは次のようになります:

if(Logger.DebugEnabled) Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

(実行時間を少し節約)

デフォルトでは、2つの場所でログを記録します。

  1. Webサイトのファイルシステム(提供されていないファイル拡張子)
  2. エラーと致命的なエラーのメール送信

ファイルは、毎日または10MB(IIRC)のローリングとして実行されます。EventLogを使用することはありません。これは、サイトに提供したいよりも高いセキュリティが必要になる可能性があるためです。

ログの読み取りにはメモ帳が問題なく機能します。


ロギングフレームワークは、シングルトンが誤用されない数少ない例の1つです。
mmcdole 2009

ロガーの周りにコンテキストを提供したい場合があります。しかし、それは並行性に対処するのに役立ちます
アーロン・パウエル

7
私は間違いなくシングルトンを引き抜くでしょう。あなたは確かに(できればIOC / DIコンテナで)渡される単一のインスタンスを持つことができます。また、ロギングをインターセプターに移動しようとします...
yfeldblum

2
シングルインスタンスのファンでもありません。各クラスに一意の名前が付けられたロガーを与えることを好むので、モジュールごとにロギングをオンまたはオフにするのは簡単です。
ジェフリーハンティン、

8

どのフレームワークを使用していますか?

ロギングアプリケーションブロックと、.Netフレームワークビットを回避するカスタムロギングヘルパーを組み合わせて使用​​します。LABは、サービスメソッドの開始/終了用の個別の一般的なトレースファイルと予期しない問題の特定のエラーファイルを含むかなり広範囲のログファイルを出力するように構成されています。構成には、デバッグ支援のための日付/時刻、スレッド、pIdなどのほか、完全な例外の詳細とスタック(予期しない例外の場合)が含まれます。

カスタムログヘルパーはTrace.Correlationを利用し、WFでのログのコンテキストで特に便利です。たとえば、一連の順次ワークフローを呼び出すステートマシンがあります。これらの各呼び出しアクティビティで、開始を記録し(StartLogicalOperationを使用)、最後に、一般的な戻りイベントハンドラーで論理操作を停止します。

これは、アクティビティの実行シーケンスに基づいてIf / Else分岐の決定などをより迅速に判断できるため、複雑なビジネスシーケンスで障害をデバッグしようとするときに数回役立つことが証明されています。

どのログ出力を使用しますか?

テキストファイルとXMLファイルを使用します。テキストファイルはアプリブロックを介して構成されますが、WFサービスからのXML出力もあります。これにより、ランタイムイベント(永続性など)および一般的なビジネスタイプの例外をキャプチャできます。テキストファイルは、日付とサイズでロールされるローリングログです(合計サイズ1MBがロールオーバーポイントだと思います)。

ログの表示にどのツールを使用しますか?

表示している出力グループに応じて、メモ帳とWCFサービストレースビューアーを使用しています。WCFサービストレースビューアーは、出力が正しく設定されていて、出力の読み取りを大幅に簡略化できる場合に非常に便利です。とにかく、エラーがどこにあるのかを大まかに知っている場合-注釈が付けられたテキストファイルを読み取るだけでも同様です。

ログは単一のディレクトリに送信され、ソースサービスに基づいてサブディレクトリに分割されます。ルートディレクトリは、アクセスがサポートユーザーグループによって制御されているWebサイトを介して公開されます。これにより、リクエストを入力せずに本番ログを確認し、本番データの長い赤いテーププロセスを実行できます。


6

このツールの作成者として、私たちはもちろん、.NETアプリケーションのロギングとトレースにSmartInspectを使用しています。通常、ライブロギングには名前付きパイププロトコルを使用し、エンドユーザーログには(暗号化された)バイナリログファイルを使用します。ビューアと監視ツールとしてSmartInspectコンソールを使用します。

実際、.NET用のかなりの数のロギングフレームワークとツールがあります。DotNetLogging.comには、さまざまなツールの概要と比較があります。


5

回答には多くの素晴らしい推奨事項があります。

一般的なベストプラクティスは、誰がログを読み取るかを検討することです。私の場合、クライアントサイトの管理者になります。だから私は彼らに行動できる何かを与えるメッセージをログに記録します。たとえば、「アプリケーションを初期化できません。これは通常......が原因です」


1

ウェブアプリケーションではlog4netを使用しています。

XML構成ファイルを変更して実行時にロギングをカスタマイズする機能は、アプリケーションが実行時に誤動作していて、詳細を確認する必要がある場合に非常に便利です。

また、ログインする特定のクラスまたは属性をターゲットにすることもできます。これは、エラーが発生している場所を把握している場合に非常に便利です。古典的な例は、SQLだけがデータベースに送信されることを確認するNHibernateです。

編集:

すべてのイベントをデータベースとトレースシステムに書き込みます。エラーまたは例外に使用するイベントログ。ほとんどのイベントはデータベースに記録するので、カスタムレポートを作成し、ユーザーがアプリケーションから直接実行したい場合にユーザーがログを表示できるようにすることができます。


使用方法について詳しく教えてください。ファイルまたはイベントログに記録しますか?それはローリングログファイルですか?それを保護またはバックアップするために何をしますか?実生活での使用に興味があります。
ポールストーベル2009

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.