ロギングに対する理想的なコードの比率はどれくらいですか?私が開発したほとんどのアプリケーションにはログがあまりないため、ログの書き込みには慣れていません。
最近転職しましたが、log4netの呼び出しのアプリケーションコードが表示されないことに気づきました。これは便利ですが、デバッグステートメントが多すぎることは、まったくないことと同じくらい悪いことです。
すべてのメソッドがいつ開始および終了し、何を返すかを示すロギングステートメントがあります。そして、ほとんど何でも行われたとき。
コンパイル時にリフレクションを使用してロギングステートメントを追加し、コードを見ようとして邪魔にならないアドオンを作成するのは簡単ではないでしょうか。
また、強力なIDEとリモートデバッグの最近では、それほど多くのロギングが本当に必要ですか?
あなたが言うように、実際には事後にロギングを追加するための素晴らしいライブラリがあります、 PostSharp 。ロギングだけでなく、他の多くの非常に便利なことの中でも、属性ベースのプログラミングを介してそれを行うことができます。
私はあなたの言うことがロギングにとって少し過剰であることに同意します。
他のいくつかは、いくつかの良い点、特に銀行のシナリオや他のミッションクリティカルなアプリを持ち出します。極端なロギングが必要な場合や、少なくとも必要に応じてオンとオフを切り替えたり、さまざまなレベルを設定したりできる場合があります。
Log4netはリソースを詰まらせないという点で優れた仕事をしているので、デバッグモードに変更する必要がある場合は、情報が多ければ多いほどよいので、ロギングについて少し冗長になる傾向があります。これが私が通常ログに記録するものです:
デバッグレベル
情報レベル
エラーレベル
致命的なレベル
また、ログの詳細がたくさんあると、エラーメッセージが表示されたときにユーザーに何をしていたのかを尋ねることができなくなります。簡単につなぎ合わせることができます。
また、強力なIDEとリモートデバッグの最近では、それほど多くのロギングが本当に必要ですか?
はい、もちろんですが、多くの熟練していない開発者が犯す間違いは、間違った方法を使用してバグを修正しようとすることです。通常、デバッグする必要があるときにログに記録する傾向があります。それぞれに場所がありますが、ほとんどの場合、ロギングが必要になる領域が少なくともいくつかあります。
//データファイルを開きます fp = fopen( "data.bin"、 "rb");
上記のコメントは、ロギング呼び出しに同じように簡単に配置できます。
const char * kDataFile = "data.bin"; log( "データファイル%sを開いています"、kDataFile); fp = fopen(kDataFile、 "rb" );
そうは言っても、あなたはいくつかの点で正しいです。ロギングメカニズムを栄光のスタックトレースロガーとして使用すると、開発者が調査するのに十分な有用な障害点が提供されないため、非常に質の低いログファイルが生成されます。したがって、ここで重要なのは、ロギング呼び出しを正しく慎重に使用することです。これは、開発者の裁量に帰着すると思います。基本的にyourself;のログファイルを作成していることを考慮する必要があります。ユーザーはそれらを気にせず、通常はとにかく内容をひどく誤解しますが、少なくともプログラムが誤動作した理由を判断するためにそれらを使用できます。
また、ログファイルが特定のバグの直接の原因を示すことは非常にまれです。私の経験では、通常、バグを複製する方法についての洞察を提供し、バグを複製するかデバッグするプロセスによって、問題の原因を見つけます。
完全なログファイルは驚くほど便利です。アプリケーションが銀行のような場所にデプロイされている状況を考えてみましょう。そこに行って手動でデバッグすることはできず、彼らはあなたにデータを送信しないでしょう。取得できるのは、問題が発生した場所を示すことができる完全なログです。多数のログレベルがあると非常に役立ちます。通常、アプリケーションは、致命的なエラーまたは重大なエラーのみを報告するようなモードで実行されます。デバッグする必要がある場合、ユーザーはデバッグまたはトレース出力をオンにして、はるかに多くの情報を取得できます。
あなたが見ている種類のロギングは過剰に見えますが、アプリケーションとそれがどこにデプロイされるかについてもっと知らなければ、それが確かであるとは本当に言えません。
それほど多くのロギングは必要ありません。各メソッドがいつ開始および終了するかを知る理由は(本番環境では)ありません。特定の方法でそれが必要になるかもしれませんが、ログファイルにノイズが多いと、効果的に分析することがほぼ不可能になります。
エラー、ユーザーログイン(監査ログ)、トランザクションの開始、重要なデータの更新など、重要なことが発生したときにログに記録する必要があります。ログから理解できない問題がある場合は、必要に応じてさらに追加できます...ただし、必要な場合に限ります。
また、参考までに、コンパイル時にログインを追加することは、いわゆる アスペクト指向プログラミング の例です。ロギングは「横断的関心事」になります。
「ログとコードの比率」は問題の誤解だと思います。
私の仕事では、Javaプログラムのバグを実稼働環境の外で再現できず、顧客がそれを二度と起こしたくないという状況が時々あります。
次に、バグを修正するために利用できるのは、ログファイルに入力した情報だけです。デバッグセッションはありません(とにかく本番環境では禁止されています)-入力データを突く必要はありません-何もありません!
したがって、ログはバグが発生したときまでのタイムマシンであり、バグを修正するために必要な情報を事前に予測することはできないため、まだ不明です。そうでなければ、最初にバグを修正することができます。ログを記録する必要があります。たくさんのもの...
正確に何がシナリオに依存しますが、基本的には、どこで何が起こるかを疑うことがないようにするのに十分です:)
当然、これは大量のロギングが発生することを意味します。次に、2つのログを作成します。1つは、必要がないことを確認するのに十分な時間だけ保持されるすべてのものと、もう1つは、はるかに長く保持できる重要な情報を含むものです。
ロギングを過剰なものとして却下することは、通常、バグを修正する必要がなく、他に何もする必要がない人によって行われます:)
アプリケーションのベータリリース中にバグに遭遇し、それを再現できない場合は、過剰なロギングを行う必要があることがわかります。クライアントがバグを報告したが、それを再現できない場合も同じように、過剰なロギング機能で1日を節約できます。
顧客のシナリオ(つまり、マシンに物理的にアクセスできない人)がある場合、「ロギングが多すぎる」のは、関数の再描画と、それらによって呼び出されるほとんどすべてのもの(ほとんど何もないはずです)だけです。または、操作中に1秒間に数百回呼び出される他の関数(ただし、私の経験では、問題のほとんどが発生する場所であるため、プログラムの起動は、ルーチンを取得/設定するための数百回の呼び出しを記録しても問題ありません)。
そうしないと、ユーザーのマシンに何が問題であるかを明確に示す重要なログポイントが欠落しているときに、自分を蹴ってしまうことになります。
(注:ここでは、ユーザー指向の通常の操作ログではなく、開発者指向のログに対してトレースモードが有効になっている場合に発生するログを参照しています。)
私の仕事では、多くのWindowsサービスを作成しています。私にとって、ロギングは贅沢ではありません。それは実際には私の唯一のUIです。本番環境にデプロイすると、デバッグにアクセスできなくなり、サービスが書き込むデータベースにさえアクセスできなくなります。ログを記録しないと、発生する問題の詳細を知る方法がありません。
そうは言っても、簡潔なロギングスタイルが最善のアプローチであると私は信じています。ログメッセージは、「入力された関数yyy」よりも「アカウントxxxから受信したメッセージ」などのアプリケーションのビジネスロジックに限定される傾向があります。例外のログ記録、スレッドの開始、環境設定とタイミングのエコーを行います。それを超えて、開発フェーズとQAフェーズで論理エラーを特定するためにデバッガーに注目します。
TDDを使い始めてから、ロギングの必要性がはるかに少なくなっていることがわかりました。これにより、バグがどこにあるかを簡単に特定できます。ただし、ロギングステートメントはコードで何が起こっているのかを理解するのに役立つことがわかりました。確かに、デバッガーは何が起こっているのかについての低レベルのアイデアを提供するのに役立ちます。しかし、何が起こっているのかを高レベルで把握したい場合は、出力行をコード行に一致させる方が簡単です。
ただし、追加する必要があることの1つは、ログステートメントにログステートメントが含まれるモジュールが含まれていることを確認することです。戻ってログステートメントが実際にどこにあるかを見つけなければならなかった回数を数えることができません。
私は個人的に、まず第一に、厳格な規則はないと信じています。 LOT、メソッドのログインとログアウト、および途中でのステータス更新をログに記録するアプリケーションがいくつかあります。ただし、これらのアプリケーションはスケジュールされたプロセスであり、ハンドオフで実行され、ログは成功/失敗を格納する別のアプリケーションによって解析されます。
実際には、多くのユーザーアプリケーションは大量のログを必要としないことがわかりました。実際に問題が発生した場合は、そこで値をトレースするためにデバッグすることになります。さらに、通常、ロギングの費用は必要ありません。
しかし、それは本当にプロジェクトに依存します。
それらの行のうち、デフォルトでログに記録されているのはいくつですか?私はあなたが説明しているものと非常によく似たシステムで作業しました-ロギングが大幅に増加した場合、起動するだけで20MBを超えるログが書き込まれますが、デバッグでもすべてのモジュールで完全に起動しませんでした。デフォルトでは、コードのモジュールが入力されたとき、および主要なシステムイベントがログに記録されます。 QAはログをチケットに添付するだけで、再現性がなくても、問題が発生したときに何が起こっていたかを確認できるため、デバッグに最適でした。深刻なマルチスレッドが進行している場合でも、ロギングは、私が使用したどのIDEまたはデバッガーよりも優れています。
私はプログラミングを始めたとき、「Dillie-O」で説明されているように多かれ少なかれすべての詳細を記録したことを告白しなければなりません。
私を信じてください...それは、何百もの問題を解決するためにログファイルに大きく依存していた本番展開の最初の数日間に大いに役立ちました。
システムが安定したら、付加価値が減少し始めたので、ログエントリの削除をゆっくりと開始しました。 (いいえ Log4j その時点で。)
コードとログのエントリの比率はプロジェクトと環境に依存し、一定の比率である必要はないと思います。
現在、Log4jなどのパッケージを使用したロギング、ログレベルの動的な有効化などに多くの柔軟性があります。
しかし、プログラマーがそれを適切に使用しない場合、たとえば、いつ使用するか、いつ使用しないか、INFO、DEBUG、ERRORなど、およびログメッセージの詳細(「HelloX、Hello XX、プログラマーだけが理解できる「こんにちはXXXなど」)比率は高いままで、少ない [〜#〜] roi [〜#〜] 。
もう1つの要因は、使用されているツールセット/プラットフォームとそれに付随する規則だと思います。たとえば、ロギングはJ(2)EEの世界ではかなり普及しているようですが、RubyアプリケーションのRailsでログステートメントを書いたことは覚えていません。