私は次の問題があります:java.util.logging.Logger
を使用します。いいえ、異なるリソースが見つかりました1、2、3、どのようにロガーの動作を変更することができます。ロガーを正しく初期化する方法は?
特に、2(私の意見では)クラスター名に従ってロガーを初期化するための良い構造が与えられています。これにより、必要に応じてデバッグ用のパッケージベースのレベルで冗長性を変更することもできます。
問題を掘り起こした後、グローバルロガーと「空の」ロガー(名前は""
)が同じではないことが分かりました。以下の例も参照してください。 ロガーfoo.Bar
を作成しましたが、これはfoo
というロガーの代わりに空のロガーに固定されています。 初めてロガーbar
を作成した場合、ロガーbar.Baz
が正しくアンカーされます。
これは、以前に作成される親ロガーを想定することができないので、this questionのアプローチを主に役に立たない。私が見る限り、クラス名を解析し、必要に応じてロガーを作成する必要があります。
static {...}
コードを追加して、独自のロガーを初期化する前に再帰的にロガーを初期化する必要があります。 複数のクラスがパッケージロガーのLogger.getLogger(String)
メソッドを呼び出した場合(つまり、bar.Baz
とbar.FooBaz
の両方ともロガーbar
)、複数の呼び出しが全体的に発生する場合、これは悪影響を及ぼしますか?
import java.util.Enumeration;
import java.util.logging.LogManager;
import java.util.logging.Logger;
public class TestLogger
{
public static void main(String[] args)
{
// Create the logger directly
Logger.getLogger("foo.Bar");
// Create the logger objects step-by-step
Logger.getLogger("bar");
Logger.getLogger("bar.Baz");
// Put the available loggers to output
Enumeration<String> e = LogManager.getLogManager().getLoggerNames();
while(e.hasMoreElements())
{
String s = e.nextElement();
Logger l = Logger.getLogger(s);
String p = (l.getParent() == null ? "none" : "'" + l.getParent().getName() + "'");
System.out.println("'" + s + "': " + p);
}
}
}
プログラムの出力は、すべてのクラスでLogger.getLogger(String)
を持つ
'bar': ''
'global': ''
'foo.bar': ''
'bar.baz': 'bar'
'': none
'java.utils.Logger'sは扱いにくいことがあります。実際の質問が何であるか完全に理解していませんが、(おそらく)重要な副作用があります。ロガーはガベージコレクションされる可能性があります。あなたの 'main'メソッドで' Logger.getLogger( "foo")。setLevel(x) 'を書いた後に' Logger.getLogger( "foo") 'でロガーを取得すると、** ** may **別のインスタンスになる! 'main'で取得したロガーはすでにガベージコレクトされている可能性があり、2回目の' getLogger( "foo")コールは新しいインスタンスを作成します。 – Marco13