2017-04-07 18 views
3

デバッグログにいくつかのログを書きますが、これは情報ログレベルのプロダクションログでは利用できません。では、この特別なデバッグログはどのようにパフォーマンスに影響しますか?つまり、ログレベルをINFOに設定すると、ログレベルは何であるかを確認し、log.debugを無視する必要があります。この余分なログレベルのチェックはパフォーマンスに影響しますか?配備中にlog.debug()ステートメントを自動的に削除する方法はありますか?私は開発時にlog.debugがそこにあり、デバッグできることを意味します。しかし、プロダクションデプロイ時には、自動メカニズムによりすべてのlog.debug()メッセージが削除されます。これらが可能かどうかはわかりません。そうでなければ、罰金 - C'estラビ!log.debugはパフォーマンスを低下させますか

+1

もちろんパフォーマンスに影響します。問題はパフォーマンスにどれだけ影響が及ぶかということです。その答えは、ログ出力がない場合でも 'log'へのparamsが評価されるため、あなたが何を記録しているかによって異なります。これを回避する方法の1つは、ロギングステートメントを静的変数と照合してラップし、最適化するか、ロギングブロックに入る前にログレベルをチェックすることです。問題は、それがその価値があるかどうかです。 –

答えて

2

このような追加のデバッグログはどのようにパフォーマンスに影響しますか?

ロガーは、ディスクI/Oは、(あなたがシステムをファイルに書いていると仮定)を呼び出し、DEBUGログレベルが厳密に本番環境に推奨されていないされているように、それはアプリケーションのパフォーマンスに影響を与えます。

展開中にlog.debug()ステートメント を削除する方法はありますか?

ません、そして限り、あなたはそれが、debug()メソッドにパラメータを渡すながら重い計算をする必要があり行っていないとして、そこにlog.debug()文を除去する魔法の方法はありませんが、あなたはINFOにログレベルを設定するとき大丈夫です。あなたはINFOに設定されたロガーのレベルを持っているし、あなたのコードに2つのロガーの下に持っていると仮定した場合たとえば、は:

logger.debug(" Entry:: "); //this logger is fine, no calculations 
//Below logger, you are doing computations to print i.e., calling to String methods 
logger.debug(" Entry : product:"+product+" dept:"+dept);//overhead toString() calls 

あなたがすることにより、第2ロガー計算のオーバーヘッドを避けることができるように、私は使用slf4jにお勧め以下に示すように(それはMessageFormatterだ使用して実際の値に置き換えられます){}を使用して:

//Below logger product and dept toString() NOT invoked 
logger.debug(" Entry : product:{} dept{}", product, dept); 

のもう一つの重要な点は、SLF4Jとちょうどabstracであるということです任意のログフレームワークの間で切り替えることができます。hereから取ったテキストを見ることができます。

のJava(SLF4J)のための簡単なロギングファサードは、エンドユーザが所望のロギングをプラグインすることを可能にする様々なロギング・フレームワークのための単純なファサード またはアブストラクション(例えばのjava.util.logging、 logback、log4jの)として機能します展開時にフレームワーク 。

+0

sl4jと同じ機能を持つlog4j2を使用できませんか? – user1539343

+0

はい、それはlog4j2またはslf4jのどちらかがlog4j1.xと比較して明らかに優れています(上記のような 'DEBUG'オーバーヘッドを避けるためです) – developer

1

あなたは同様に、これをやって後ろisInfoEnabled()など

への呼び出しにアイデアをあなたの「情報」の文をラップisDebugEnabled()

if (log.isDebugEnabled()) { 
    log.debug("my debug statement"); 
} 

の呼び出しであなたの「デバッグ」ステートメントをラップすることができますロギングレベルが有効になっているかどうかを確認することは、安価な(固定コスト)操作であるかどうかをチェックすることです。ログに記録されているステートメントを生成するコストは、実行している処理によって異なります。

1

ロギングレベルを確認するオーバーヘッドは非常に少なく、ごくわずかです。デバッグログを有効にすると、パフォーマンスに大きな影響があります。影響は、ログに書き込むデータ量、ストレージ(ストレージがSSDの場合、パフォーマンスヒットが通常のディスクを使用した場合のパフォーマンスヒットと比較して小さい)、ログに書き込むスレッドの数(Since一度に1つのスレッドだけがファイルに書き込むことができ、他のすべてのスレッドは待機しなければならず、それは順次プロセスです)。私は3つについて言及しましたが、ロギングの影響がアプリケーションのパフォーマンスに与える影響を決定する要素が増えています。

2番目の質問に答えるために、コードからデバッグステートメントを自動的に削除する方法はありません。

2

これは、ロギングステートメントの作成方法によって最小化できます。あなたは関係なく、あなたが引数を使用しているロギングフレームワークの後、

Object a = .... 
log.debug("I have an a: " + a); 

を記述する場合、デバッグ機能が実行される前に評価を受ける必要があります。つまり、INFOレベルであっても、toStringaに呼び出し、引数文字列を作成するというパフォーマンスコストを支払っていることになります。代わりに、たとえば(あなたのロギングフレームワークは、これはlog4jをし、SLF4Jで動作し、使用してフォーマットするものに応じて)

log.debug("I have an a: {}", a); 

あなたはこの費用を払っていないが、ロガーのコストだけがデバッグモードにいるかどうかを確認する - しない限り、あなたが議論の評価を支払わないことが必要です。

もう1つは、書き込みを最小限に抑える出力をバッファリングしていることです(もう一度、slf4jにバッファリングアペンダがあります)。

1

私が指摘したいと思う別のテクニックは、Android開発でよく使用される、デバッグなどの呼び出しを取り除くためにjarを後処理できることです。使用されるツールは、通常、プロガードです。呼び出しを副作用なしと定義した場合、オプティマイザによって削除され、パフォーマンスのペナルティはほとんどゼロになります。ログメッセージに対して行っていた文字列の構築を最適化するほどスマートにすべきです。

https://www.guardsquare.com/en/proguard/manual/usage#assumenosideeffects

関連する問題