ログが必要な理由
明らかに、ログは開発者が(私たち)がより簡単に生きられるようにするために作成されます。 ログがある主な目標:
- デバッガの助けに頼ることなく、システムが今何をしているかを言う 正当化されない場合があります。
- システムの特定の状態(クラッシュやバグなど)につながった状況の「調査」を実施します。
- より多くの時間/リソースが費やされていることを分析します。 プロファイリング。
プリミティブアプローチ
すべてがシンプルに思えます:
public static void Log( string message) {
File .AppendAllText( "log.txt" , message);
}
なぜ他のことを考え、外部ライブラリを接続し、構成を構成するのですか?
実際には、これはそうではないことが判明しています。1つのログファイルでは不十分であり、マルチスレッド、ログ形式、時間記録、パフォーマンスなどに問題があります。
優れたロガーはどの機能をサポートする必要がありますか?
立派なロガーの機能
ログレベルとメッセージフィルタリング
典型的なレベル:デバッグ、情報、警告、エラー、致命的
レベルは、メッセージの重要度とそれに対する許容可能な応答時間の決定に役立ちます。これについては、以下で詳しく説明します。
ログファイルのローテーション
ログは時間とともに成長し、古いログは不要になります。 優れたロガーは、特定の条件が発生したときにアクティブなファイルを置き換えることができるはずです。 日付とファイルサイズの2つのモードがあります。
ファイルだけでなくメッセージを書き込む機能
必ずしもファイルがメッセージを保存する最良の方法であるとは限りません。優れたロガーは、UDPを介したメッセージの送信、データベースへの書き込み、MSMQやJMSなどのメッセージキューとの対話をサポートする必要があります。 さらに、ロガーが独自のメッセージコンシューマー(通常、メッセージコンシューマーまたはメッセージアペンダーと呼ばれる)を実装する機能を提供すると優れています。
スレッドセーフ
ロガーにとってスレッドセーフは非常に重要な要件です。 悪いロガーは次のことができます。
- 一部のメッセージをスキップします。
- 例外を投げる
- パフォーマンスに悪影響を与える
非同期ロギング
一般的なログ記録方法は非同期記録です。 バッファサイズを柔軟にカスタマイズできることが重要です。たとえば、デバッグメッセージは100個で記述でき、エラーは発生直後に書き込むことができます。
ログの形式と構成
形式は、何を書き込むか、どこに書き込むかを指定できる機能を備えてカスタマイズ可能である必要があります。 たとえば、環境変数からパスに沿って保存されているファイルに書き込むことができます。 さらに、便利な機能は、構成ファイルを追跡するロガーの動的構成です。 デバッグモードを有効にする必要があります-設定を変更し、アプリケーションを再起動せずにおいしいログをお楽しみください。
ログに書き込む内容と方法
ロガーの機能を考慮しました。 ただし、適切で読みやすいログを取得するには、正しくログを記録する必要があります。
そもそも、サービスまたは部門の「法律」は通常、サービスレベル契約であるSLAです。 障害後の回復の許容レベル、メッセージの許容応答時間などを示します。 SLAを維持し、時間内にイベントに対応するために、ログレベルがあります。
ロギングレベル
メッセージには特定の重要度の情報が含まれており、メッセージへの応答時間は異なることを理解することが非常に重要です。 例を挙げます。
Debug.
Debug.
Debug. 0.02 , 1000
Info. 40000000000 (John Doe), $2000.
Warn. 0.
Error. 123: …..
Fatal. MSMQ, - (…). .
各レベルの意味は何ですか?
デバッグ :デバッグメッセージ、プロファイリング。 実動システムでは、このレベルのメッセージは通常、システムの最初の起動時に含まれるか、ボトルネック(ボトルネック)を検索します。
情報 :システムアクションについて通知する定期的なメッセージ。 そのようなメッセージに応答する必要はまったくありませんが、たとえば、バグの検索時、興味深い状況の調査時などに役立ちます。
警告 :このようなメッセージを記録すると、システムは保守スタッフの注意を引き付けようとします。 奇妙なことが起こりました。 おそらくこれは、システムにまだ知られていない新しいタイプの状況です。 何が起こったのか、これが何を意味するのかを理解し、状況を情報メッセージまたはエラーのいずれかに起因させる必要があります。 したがって、このような状況を処理するためにコードを変更する必要があります。
エラー :介入が必要なシステムのエラー。 何かが生き残れず、何かが落ちました。 あなたはかなり迅速に行動を起こす必要があります! このレベル以上のエラーは、それらへの応答を高速化するために即座にログを記録する必要があります。 ユーザーエラーはシステムエラーではないことを理解する必要があります。 ユーザーがフィールドに-1を入力した場合(これが想定されていない場合)、エラーログにこれについて書き込むべきではありません。
致命的 :これは特別な種類のエラーです。 このようなエラーは、システム全体の動作不能、またはサブシステムの1つの動作不能につながります。 致命的なエラーは、多くの場合、誤った構成または機器の障害が原因で発生します。 彼らは緊急の、即時の反応を必要とします。 おそらく、SMSを介してこのようなエラーの通知を提供する必要があります。
エラーレベルを正しく判断すると、システムの品質とメンテナンスの単純さに影響します。
レベル選択の実例
開発中のシステムが、パッケージを受け入れる郵便従業員であると想像してみましょう。 彼らは荷物を持ってきました。
Debug: 1. …
Debug: 1: 40x100
Debug: …
Debug: 1: 1
Debug: …
Info ( Error!): 1 40x100, 1, :
…
Info: 2 20x60, 0.5 1
…
Warn: 3: : 2050-01-01
…
Error: : :
…
Fatal: . .
ログと例外
彼らはレーニンと党のように、お互いから切り離せません。 例外またはエラーの処理は、頻繁に正しく記録する必要があります。
悪い例:
Log(ex.ToString());
さらに悪いこと:
Log(ex.Message);
ログにテキストを添付せずに例外を書き込まないでください。 スタックトレースが何も語っていないのを見て、私はパニックに陥ります。 それは何ですか-エラー、通知? プログラムはこの例外にどのように対応しましたか? 管理者の反応を待って、通常モードで動作し続け、クラッシュしましたか? 残念ながら、私はこれをコードでよく見ますが、これは非常に悲しいことです。 正しい方法:
Log( " {0} , : {1}" , account, ex);
ログ例外ルール
- 例外を記録するレベル(サブシステム)を選択します。
- 例外を処理した場合、考えられる3つのケースがあります。
- 例外は処理されたと見なされ、スタックを押し上げません。 この場合、詳細なスタックとともに例外をログに書き込みます。
- 同じサブシステム内のスタックに例外がスローされます。 そのような例外をログに記録しないでください。 ただし、スタックの上位に書き込まれるようにしてください。
- 例外がスタックから別のサブシステムにスローされます。 たとえば、別のマシンまたは別のプロセスに。 そのような例外を記録するか、例外に関する診断メッセージを記録します。
- 例外が処理されない場合は、ログに記録しないでください。 ただし、上記の例外が必ず約束されていることを確認してください。 私が説明します:
try { … } catch (Exception ex) { Log(ex); throw ; }
ロガーの1回の呼び出しが誤ったオプションであるcatchブランチ。 そのようなキャッチを取り除きます。
これらの単純なルールは、エラーが発生したときにログをスタックトレースからダンプに変換しないようにするのに役立ちます。
はい、ex.ToString()がテキストと完全なトレースで例外をスローすることを忘れないでください。 時々何らかの理由で、彼らはこの便利な方法を忘れています。
ロガーの比較
NLog、Log4net、Enterprise Libraryで提供されているものと比較しましょう。
Nlog | Log4net | エンタープライズライブラリ | |
---|---|---|---|
免許 | BSD | アパッチ | MS-PL |
レベル | デバッグする
トレース 情報 警告する エラー 致命的 | デバッグする
情報 警告する エラー 致命的 | 冗長
情報 警告 エラー クリティカル |
ログローテーション | はい | はい | はい |
構成追跡 | はい | はい | いいえ(?) |
配列ロギング | いや | はい | いや |
スレッドセーフ | はい | はい | はい |
プロトコル | ネットワーク
記憶 Msmq ベース ...拡張機能 | Wmi
ネットワーク 記憶 ベース ...拡張機能 | Wmi
Msmq ベース ...拡張機能 |
バッファリング、非同期ロギング | はい | はい | はい |
状態 | アクティブ | おそらく放棄された。 バグトラック(http://issues.apache.org/jira/)の最後のバグは2009年3月に記録されました | アクティブ |
以前はlog4netを使用していましたが、NLogに切り替えました。 放棄されたlog4net(残念)。
結論
- ロガーを自分で作成しないでください。
- 使用するロガーの構成と機能を調べます。
- ログ内のメッセージのレベルを正しく選択します。
- 例外ログに注意してください。