私は常に次のパターンを使用して(SLF4J)ロガーを作成しました。
private static final Logger log = LoggerFactory.getLogger(MyClass.class);
これはこれまでのところ機能していますが、ある時点でstatic
コンテキストと、次のような非静的ロガーを使用するのではなく、常に具象クラスリテラルを渡す必要があるのではないかと考えていました。
private final Logger log = LoggerFactory.getLogger(getClass());
これは基本的に、ここまでにLOG4Jについて質問(および回答)されています。
そしてここ
final
は基本的に必須であることに気付いたので、非静的コンテキストでSLF4Jを使用するオーバーヘッドが実際にどれほど高いのか疑問に思います。
Q:
使用することによる重要な実用的オーバーヘッドはありますか?
private final Logger log = LoggerFactory.getLogger(getClass());
以上
private static final Logger log = LoggerFactory.getLogger(MyClass.class);
average(web)アプリで? (ここでハイエンドで高負荷のWebアプリについて「議論」する必要はありません)
私は最終的に、CDIを使用してさらに優れたアプローチを使用して次のようなSLF4Jロガーを取得することを計画しています。
@Inject private final Logger log;
ここで説明されているように http://www.seamframework.org/Weld/PortableExtensionsPackage#H-TtLoggerttInjection ですが、最初にロガーのキャッシュについて知る必要があります。
サブ質問:使用することも可能ですか?:
@Inject private static final Logger log;
(正直に言うと、CDIから始めたばかりです)
非静的(インスタンス)ロガー変数のオーバーヘッドは、多くの、たとえば10000以上のインスタンス化が発生しない限り、無視できる必要があります。ここでのキーワードはごくわずかです。多く(> 10000)のオブジェクトがインスタンス化される場合、影響はおそらく測定可能ですが、それでも低いです。
より具体的には、インスタンスロガーは、オブジェクトインスタンスごとに1参照(64ビット)だけメモリフットプリントを増やします。 CPU側では、コストはインスタンスごとに1つのハッシュルックアップです。つまり、ハッシュテーブル(小さい)で適切なロガーをルックアップするコストです。繰り返しますが、多くのオブジェクトが作成されない限り、両方のコストは無視できるはずです。
この質問は SLF4J FAQ でも説明されています。
LoggerFactoryを使用するときの正確なオーバーヘッドについてはわかりませんが、アプリケーションのパフォーマンスに影響を与えるとは思えません。したがって、必要に応じて静的または非静的を使用してください。
@Injectを使用する利点は何ですか。 LoggerFactoryは、具体的なimplからの抽象化をすでに提供しています。いずれにせよ、LoggerFactoryよりもはるかに遅くなります。
真の@Injectを使用すると、構文がより簡潔になります。しかし、テストでクラスを使用するとします。次に、ロギングを取得するためにインジェクションを設定する必要があります。通常のLoggerFactoryを使用すると、テストでもうまく機能します。 Javaに@Injectの一般的なメカニズムがある場合、それはうまく機能しますが、それがそうであるため、セットアップはより困難です。