6

デバッグ目的でログ メッセージを使用して計測したい Java コードがいくつかあります。ただし、最終的な (コンパイルされた) 製品コードには、実行時間が遅くなるため、ログを含めないでください。Javaでコンパイル時にロガーを無効にする方法はありますか?

実行時有効/無効ロガーの log メソッド内のチェックが追加するフットプリントを恐れていません。

if (logging==enabled) {// do logging}

ただし、本番コードでは次のようなパラメーターの構築は避けたいと思います。

Logger.log("undefined state" + state + " @ " + new Date());

Sun の Java コンパイラを使用しています。

4

10 に答える 10

6

{} プレースホルダーを使用した slf4j アプローチを検討しましたか。これにより、toString() の構築を遅らせることができます。つまり、デバッグ ログが無効になっている場合、log.debug(...) は安価です。

log.debug("in loop() - a={}, b={}", a, b);
于 2010-06-22T10:02:13.360 に答える
2

Proguardを使用して Java クラス ファイルを後処理し、-assumenosideeffectsオプションを使用してロギング呼び出しを削除することができます。これは、以下を使用して Android で最も一般的に行われます。

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}

などへのすべての呼び出しを削除するにはLog.d(TAG, "message")...

于 2011-10-31T04:05:03.847 に答える
2
if(logger.isDebugEnabled()) {
  logger.debug(expression);
}

私が使用したすべてのロギング フレームワークでは、ロギング式の不要な評価を避けるために、上記のパターンを使用する必要があります。

于 2010-06-22T09:37:02.313 に答える
1

これを可能にする組み込みの方法はありません。Java Preprocessorを使用することもできます。

于 2010-06-22T09:36:47.470 に答える
1

1 つの方法は、log メソッドの外でチェックを行うことです。あなたが述べたのとほぼ同じチェックですが、自分で行います:

if (LOGGER.isLoggable(Level.DEBUG)) {
    LOGGER.log("undefined state" + state + " @ " + new Date());
}

この方法は、任意のログ レベルで使用できます。詳細については、Logger#isLoggable(Level)を参照してください。これは、ログ メソッド パラメータの構築を回避するための推奨される方法であることに注意してください。

于 2010-06-22T09:37:12.997 に答える
1

これはあなたが探しているもののようです:

いくつかのログの場所をオンまたはオフにすると、log4j は実際に何をしているのでしょうか?

于 2010-06-22T09:38:30.360 に答える
0

これに関するコンパイラの機能については知りませんが、ビルドスクリプトを作成することもできます。このスクリプトは、元の (デバッグ) Java ソース ファイルをコピーし、それらを一時的な場所にコピーし、ログ ステートメントを削除してから、デバッグ コードのない新しいソース ファイルをコンパイルします。

于 2010-06-22T09:36:42.650 に答える
0

機能するかもしれない醜いハックは、Logger ライブラリの実装を空の実装で隠すことです。オプティマイザーはそれらをインライン化し、デッドコードの削除はパラメーターの構築を削除する必要があります。パラメータの構築に副作用が含まれている場合、これは機能しません。

これは理論であり、実際にはテストしていません。私はこれについて興味があります。多分これは別の質問を保証しますか?

于 2010-06-22T09:49:36.463 に答える
0

ログ メッセージにレベル インジケータを使用する必要があります。Level.SEVERE -> Level.FINEST です。

これには、Logger に定義済みのメソッドがあります。つまり、次のとおりです。

Logger.info(msg);
Logger.finest(msg); // debug/trace message.

Logger.log(Level.CONFIG, "config message");

これにより、アプリケーション レベルで最小ログ レベルを構成し、コマンド ライン、構成ファイル、または手動で LogManager を使用して、構成されたレベルより下のメッセージをオン/オフに切り替えることができます。

于 2010-06-22T10:00:21.933 に答える
0

Java コンパイラーは、コンパイル時の定数式によって保護されているコードのブロックを除去できることを理解しています。したがって、理論的には、次のような方法でこれを実行できるはずです。

 public class Logging {
     public static final boolean ENABLED = true;  // change to false
 }

 public class Something
     ....

     if (Logging.ENABLED) {
          logger.debug("hello mum");
     }
 }

残念ながら、値を変更するたびに Logging.ENABLED フラグに依存するすべてのクラスを再コンパイルする必要があります。したがって、私は次のことを非常に好みます。

public class Something
     ....

     if (logger.isDebugEnabled()) {
          logger.debug("hello mum");
     }
 }

これには、構成時または実行時にログレベルをきめ細かく調整できるという利点があります。たとえば、デバッガー、JMX などを使用します。また、logger.isDebugEnabled()log4j での呼び出しのオーバーヘッドは十分に低いため、コードベースに非常に多くのログがない限り、気にすることはほとんどありません。

于 2010-06-22T10:37:40.170 に答える