web-dev-qa-db-ja.com

Log4jロガーをプログラムで設定する

私は初めてSLF4J(log4jバインディング)を使用しようとしています。

LoggerFactoryが返すことができる3つの異なるLoggerを設定して、異なるレベルを記録し、メッセージを異なるappenderにプッシュします。

  • ロガー1 "FileLogger"はDEBUGをログに記録してDailyRollingFileAppenderに追加します
  • ロガー2 "TracingLogger"はTRACE +をログに記録し、JmsAppenderに追加します。
  • ロガー3 "ErrorLogger"はERROR +をログに記録し、別のJmsAppenderに追加します

さらに、それらをプログラム的に(XMLやlog4j.propertiesファイルとは対照的に)構成したいと思います。

init()メソッドのように、通常はブートストラップコードのどこかにこれらのLoggerを定義することを想像しています。しかし、私はslf4j-log4jを使いたいので、ロガーを定義してそれらをクラスパスで利用できるようにする場所について混乱しています。

believeこれは(ファサードとしての)SLF4Jの根本的な目的に対する違反です。SLF4JAPIを使用する私のコードでは、これらのロガーが存在することを認識していないためです。私のコードはSLF4J APIへの通常の呼び出しをするだけです、そしてそれはそれからそれがクラスパスで見つけたlog4jロガーにそれを転送します。

しかし、どうやってこれらのlog4jロガーをクラスパスで設定するのですか... Javaで!

177
IAmYourFaja

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を作成するのではなく、システム内のすべての可能なカテゴリに対してハンドラを提供するだけです。

265
oers

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を介して利用可能にされます。これが役に立ったことを願っています!

43
IAmYourFaja

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);
3
Kyle Shrader