すでにコンパイルされたjarのパフォーマンスを簡単に変更しますか?
-
05-07-2019 - |
質問
多くのlog4jユーザーのように、デバッグレベルのログは評価に費用がかかることがよくあります。そのため、次のようなコードでこれらのケースを保護します。
if( _logger.isDebugEnabled )
_logger.debug("Interesting, my foojes are goofed up: " + getFullDetails())
ただし、それは単純な_logger.debug呼び出しよりもugく、プログラマーは評価が高価になる可能性があることに気付かない場合があります。
コンパイル済みのjarを取得し、isDebugEnabledチェックを使用してすべての_logger.debug呼び出しをガードするプログラムを作成するのは、かなり簡単なはずです。すべての場合において、isDebugEnabledをチェックする余分なオーバーヘッドを受け入れることになるでしょう。
このアプローチを試した人や、同様のjarの後処理を行った人はいますか?
解決
AspectJ をご覧になりましたか?これは、バイトコードウィービングを使用したアスペクトをサポートし、以前にコンパイルされた.jarファイル。
他のヒント
jarを変更するのではなく、バイトコード計測。問題は、 .isDebugEnabled()
内にラップするコードの部分を識別することです。log4jの呼び出しにのみ使用されるオブジェクトを識別する必要があります。
良い解決策は、コードがそのまま効率的であることだと思います。
log4jは非推奨であると考えてください。作成者自身は互換性を壊さないようにそのままにしておきましたが、新しいSLF4J( http:// wwwを作成しました。 .slf4j.org / )。彼は、commons-logging / log4jの区別に従って、ファサードと実装の両方を提供していますが、それぞれの欠点はありません...
この新しいロギングファシリティでは、オブジェクトパラメータをロギングに送信でき、オブジェクトを(ストリングなどに)変換する前にレベルが評価されると信じています。アイデアは、フォーマット文字列とパラメーターを使用することです。
私たちのコードはslf4jを使用していませんが、まさにそれを行うユーティリティメソッドがあります。 おおよそ次のようにコーディングされます(メモリから):
public enum LogLevel {
FATAL, ERROR, WARNING, INFO, DEBUG;
public void log(Logger logger, String format, Object... parameters) {
if (isEnabled(logger)) {
logImpl(logger, String.format(format, parameters));
}
}
public boolean isEnabled(Logger logger) {
switch(this) {
case WARNING : return logger.isWarningEnabled();
case INFO : return logger.isInfoEnabled();
case DEBUG : return logger.isDebugEnabled();
default: return true;
}
}
private void logImpl(Logger logger, String message) {
switch(this) {
case WARNING : logger.warn(message);
// other cases
}
}
}
次のように使用されます:
public void myMethod(Object param) {
LogLevel.WARNING.log(LOGGER, "What is my message ....", "myMethod", param);
}
更新:ログ内のメソッドを呼び出す必要がある場合...
-
1つの可能性は、
toString
メソッドを使用することです。これは、ロギングが「テクニカル」である場合に適切であり、デバッグ時にも使用されます。 -
ロギングがより機能的である場合(開発者向けではない場合)、インターフェイスを定義することをお勧めします(その場合は機能的に適切であるため、意味を提供すると便利です) :
public interface Detailable { // the name could also suggest logging? String getFullDetails(); }
ログを作成するための複雑な計算を使用して、ロギングオブジェクトとして渡す必要があるオブジェクトにそのインターフェイスを実装します。