- - PR -
log4jのgetLoggerに指定するクラス名について
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-10-07 18:18
こんばんは。
現在log4jを使用して、ログを出力していますが、 その際以下のようにして、Loggerのオブジェクトを取得すると思います。 public class TestClass { private static final Logger log = Logger.getLogger(TestClass.class); } ここで、getLoggerに渡す引数は、クラス名にログを出力するクラス名に すると思いますが、よく、別クラスから、上記1行をコピーして、 使う場合、クラス名の修正を忘れてしまうことがあります。 そこで、以下のようなクラス名を取得するUtilクラスを作成し、 以下のように使用しています。 // クラス名取得 public class Util { public static String getClassName(Throwable t) { if (t == null) { return ""; } return t.getStackTrace()[0].getClassName(); } } 実際のgetLoggerは、以下のような感じです。 public class TestClass { private static final Logger log = Logger.getLogger(Util.getClassName(new Throwable())); } このようにすれば、コピーしても、動的にクラス名を取得できるので、 問題ないのですが、クラス名を取得するだけで、Throwableをnewするのは、 ちょっと、もったいない気がします。 みなさんは、どのようにされていますでしょうか? また、よい方法があれば、ぜひ、教えてください。 | ||||||||
|
投稿日時: 2007-10-07 18:30
別にもったいなくないと思います。 実行されるのは各クラスのロード時に一回だけですし、 寿命も短いので第一世代GCで回収されるため無害です。 あと、そこまでやるなら、
の方が使い勝手がよいのでは? | ||||||||
|
投稿日時: 2007-10-09 01:02
staticから使えませんが、継承が多いと宣言の必要すらありません。
フレームワークとの間に一枚かます場合によく使います。 public Logger log(){ return Logger.getLogger(getClass()); } コストについて考える場合はそこだけ対応した方が効率的かと。 | ||||||||
|
投稿日時: 2007-10-09 22:12
返信ありがとうございました。
> 実行されるのは各クラスのロード時に一回だけですし、 > 寿命も短いので第一世代GCで回収されるため無害です。 確かにそうですね。 ただ、newしているのがちょっと、もったいない気がしたもので、 質問させていただきました。 また、 return Logger.getLogger(new Throwable().getStackTrace()[1].getClassName()); 確かにそちらの方が、使い勝手がよいですね。 ありがとうございます。 > フレームワークとの間に一枚かます場合によく使います。 なるほど。ただ、やっぱりログを出力している、クラス名を 表示したいです。 今回は、どうもありがとうございました。 | ||||||||
|
投稿日時: 2007-10-09 22:32
そうでもないです。第一世代のアロケーションは ポインタを進める程度のコストで済むらしいですし、 JavaSE6ならエスケープ解析もあります。 この辺りの情報はIBM developerWorksに詳しい記事があります。 http://www-06.ibm.com/jp/developerworks/java/051104/j_j-jtp09275.shtml | ||||||||
|
投稿日時: 2007-10-09 23:18
私は、
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; : : private Log logger = LogFactory.getLog(this.getClass()); と記述して、コピペしてますね。 | ||||||||
|
投稿日時: 2007-10-10 13:40
>flatlineさん
それはあまりオススメしません。 何故かというと継承することによってロガーのファクトリの引数が変わってしまうためです。 「ベースクラスはログ出力いらないけど、継承したクラスのある部分ではログを出したい」 というような要件の時に困りますよ。 他のフレームワークのクラスを継承したときの、 基底クラスのログって結構うるさいですから。 SpringFrameworkも非staticでロガーを保持しているので、 オリジナルのApplicationContextを継承して作成したときに、 何故いらないログが出るんだ?ということで調べると、 そんな感じの現象でした。参考までに。 | ||||||||
|
投稿日時: 2007-10-10 17:29
それはわかっているのですが、そもそもログを出すようなクラスで、継承をあまり使用しないので、記述の簡易性(つまりコピペ可能)を優先してます。 アプリケーションの作り方にもよるでしょうが、個人的には作成するクラスの種類としては、 ・Page(Form)系 ・Action系 ・Logic系 の3種類で、この中で継承する可能性があるのはPage系 だけ、ログを出す可能性があるのは、Logic系だけです。 |