私は初めてSLF4J(log4j
バインディング)を使用しようとしています。
LoggerFactoryが返すことができる3つの異なるLoggerを設定して、異なるレベルを記録し、メッセージを異なるappenderにプッシュします。
DailyRollingFileAppender
に追加しますJmsAppender
に追加します。JmsAppender
に追加しますさらに、それらをプログラム的に(XMLやlog4j.properties
ファイルとは対照的に)構成したいと思います。
init()
メソッドのように、通常はブートストラップコードのどこかにこれらのLogger
を定義することを想像しています。しかし、私はslf4j-log4j
を使いたいので、ロガーを定義してそれらをクラスパスで利用できるようにする場所について混乱しています。
believeこれは(ファサードとしての)SLF4Jの根本的な目的に対する違反です。SLF4JAPIを使用する私のコードでは、これらのロガーが存在することを認識していないためです。私のコードはSLF4J APIへの通常の呼び出しをするだけです、そしてそれはそれからそれがクラスパスで見つけたlog4jロガーにそれを転送します。
しかし、どうやってこれらのlog4jロガーをクラスパスで設定するのですか... Javaで!
Log4jにAppenderをプログラム的に追加/削除することができます。
ConsoleAppender console = new ConsoleAppender(); //create appender
//configure the appender
String PATTERN = "%d [%p|%c|%C{1}] %m%n";
console.setLayout(new PatternLayout(PATTERN));
console.setThreshold(Level.FATAL);
console.activateOptions();
//add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(console);
FileAppender fa = new FileAppender();
fa.setName("FileLogger");
fa.setFile("mylog.log");
fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
fa.setThreshold(Level.DEBUG);
fa.setAppend(true);
fa.activateOptions();
//add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(fa);
//repeat with all other desired appenders
Init()のどこかに入れることをお勧めします。確かに、これは他の何よりも先に実行されます。これで、ルートロガーの既存のアペンダをすべて削除できます。
Logger.getRootLogger().getLoggerRepository().resetConfiguration();
そしてあなた自身の追加から始めましょう。これを機能させるには、もちろんクラスパスにlog4jが必要です。
リマーク:
アペンダを追加したい任意のLogger.getLogger(...)
を取ることができます。ルートロガーはすべてのものの一番下にあり、他のカテゴリの他のアペンダを通過するすべてのものを処理するため、ルートロガーを使用しました(追加フラグを設定して構成しない限り)。
ロギングがどのように機能し、どのようにログが書き込まれるのかを知る必要がある場合 このマニュアルを読む それについての詳細は==を参照してください。
要するに:
Logger fizz = LoggerFactory.getLogger("com.fizz")
カテゴリ "com.fizz"のロガーを提供します。
上記の例では、これは、一緒にログに記録されたものすべてが、ルートロガーのコンソールおよびファイルアペンダを参照することを意味します。
Logger.getLogger( "com.fizz")。addAppender(newAppender)にアペンダを追加すると、fizz
からのログ記録は、ルートロガーのアペンダとnewAppender
によって処理されます。
設定を使ってLoggerを作成するのではなく、システム内のすべての可能なカテゴリに対してハンドラを提供するだけです。
Log4jを「両端」(コンシューマ側と設定側)から使用しようとしているようです。
Slf4j apiに対してコーディングしたいが、クラスパスが返すlog4jロガーの設定を前もって(そしてプログラム的に)決定したいのであれば、あなたは絶対に持っている何らかのロギング適応を利用するのに役立ちます怠惰な建設.
public class YourLoggingWrapper {
private static boolean loggingIsInitialized = false;
public YourLoggingWrapper() {
// ...blah
}
public static void debug(String debugMsg) {
log(LogLevel.Debug, debugMsg);
}
// Same for all other log levels your want to handle.
// You mentioned TRACE and ERROR.
private static void log(LogLevel level, String logMsg) {
if(!loggingIsInitialized)
initLogging();
org.slf4j.Logger slf4jLogger = org.slf4j.LoggerFactory.getLogger("DebugLogger");
switch(level) {
case: Debug:
logger.debug(logMsg);
break;
default:
// whatever
}
}
// log4j logging is lazily constructed; it gets initialized
// the first time the invoking app calls a log method
private static void initLogging() {
loggingIsInitialized = true;
org.Apache.log4j.Logger debugLogger = org.Apache.log4j.LoggerFactory.getLogger("DebugLogger");
// Now all the same configuration code that @oers suggested applies...
// configure the logger, configure and add its appenders, etc.
debugLogger.addAppender(someConfiguredFileAppender);
}
この方法では、log4jロガーがいつどこで設定されるのかを心配する必要はありません。初めてクラスパスがそれらを要求するとき、それらは遅延的に構築され、戻され、slf4jを介して利用可能にされます。これが役に立ったことを願っています!
Log4jプロパティでアペンダを定義していて、それをプログラムで更新したい場合は、log4jプロパティで名前を設定し、それを名前で取得します。
これはlog4j.propertiesエントリの例です。
log4j.appender.stdout.Name=console
log4j.appender.stdout=org.Apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.Threshold=INFO
更新するには、次の手順に従います。
((ConsoleAppender) Logger.getRootLogger().getAppender("console")).setThreshold(Level.DEBUG);