2

アプリケーションで使用する Log4j ロガーに簡単なメソッドをいくつか追加したいと考えていました。

このようにしてみました:

public class Logger extends org.apache.log4j.Logger
{
    public Logger(Class type)
    {
        super(type.getName());
    }

    public void info(String format, Object... o)
    {
        info(String.format(format, o));
    }

    public void debug(String format, Object... o)
    {
        debug(String.format(format, o));
    }

    public void warn(String format, Object... o)
    {
        warn(String.format(format, o));
    }

    public void error(String format, Object... o)
    {
        error(String.format(format, o));
    }
}

私はこれを次のように使用できるはずだと考えました:

public class TmpTest
{
    public static void main(String[] args) throws Exception
    {
        // Note I'm not even using the special methods here
        new Logger(TmpTest.class).warn("Test");
    }
}

しかし、私はNullPointerException.

Exception in thread "main" java.lang.NullPointerException
    at org.apache.log4j.Category.warn(Category.java:1004)
    at no.nwn.productconfigurator.TmpTest.main(TmpTest.java:16)

このままじゃいけないの?クラスのgetLoggerファクトリ メソッドを使用した場合にのみ行われる初期化の欠落はありますか?Logger

Logger クラスを拡張できない場合、どうすればよいですか?


log4j.xml に関するものでしょうか? これを自分で使用したことはなく、自分で書いたこともありません。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration debug="true">
    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n"/>
        </layout>
    </appender>
    <appender name="ProductConfigurator" class="org.apache.log4j.DailyRollingFileAppender">
      <!-- 
      <param name="File" value="logs/ProductConfigurator.log" />   
      -->
      <param name="File" value="/var/tomcat/logs/ProductConfigurator.log" />
      <param name="Append" value="true" />
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d{yyyy-MMM-dd HH:mm:ss,SSS}. %5p %c{1}:%L - %m%n"/>
        </layout>
    </appender>
    <logger name="org.hibernate" additivity="false">
    <level value="warn" />
        <appender-ref ref="ProductConfigurator"/>
    </logger>
    <logger name="org.hibernate.type" additivity="false">
    <level value="warn" />
        <appender-ref ref="ProductConfigurator"/>
    </logger>
    <logger name="org.hibernate.SQL" additivity="false">
    <level value="warn" />
        <appender-ref ref="ProductConfigurator"/>
    </logger>
    <root>
        <!-- all|trace|debug|info|warn|error|fatal|no -->
        <priority value="info" />
        <appender-ref ref="ProductConfigurator"/>
    </root>
</log4j:configuration>
4

2 に答える 2

3

category.repositoryフィールドはnull. ソースコードを見てください:

public void warn(Object message) {
    if(repository.isDisabled( Level.WARN_INT))
       return;

    if(Level.WARN.isGreaterOrEqual(this.getEffectiveLevel()))
        forcedLog(FQCN, Level.WARN, message, null);
}

を適切に初期化するには、以下Loggerを使用する必要がありますLogManager

public static void main(String[] args) throws Exception
{              
    LogManager.getLogger(TmpTest.class.getName(), new LoggerFactory() {

        @Override
        public Logger makeNewLoggerInstance(String name) {
            return new Logger(name);
        }
    }).warn("Test");
}

カスタム ファクトリ実装を使用してロガーをインスタンス化します。ロガーを作成する古典的な方法 ( Logger.getLogger(Class clazz)) が以下を使用するわけではありませんLogManager

static public Logger getLogger(Class clazz) {
    return LogManager.getLogger(clazz.getName());
}

プロジェクトに特定の制約がない場合は、slf4jを使用することをお勧めします。それはあなたが期待している方法を提供します:

logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
于 2013-03-18T15:33:09.477 に答える
-1

super.info、warn などのすべての呼び出しの前に追加するだけです。

次のコードで:

public void info(String format, Object... o) {
    info(String.format(format, o));
}

を呼び出すときはinfo(String.format(format, o))、まったく同じメソッドを再帰的に呼び出します。最初のパラメーターは書式設定された文字列で、2 番目の (var-args) パラメーターは null であるため、String.formatを再度呼び出すと、NullPointerException が発生します。

したがって、代わりに次のように書く必要があります。

public void info(String format, Object... o) {
    super.info(String.format(format, o));
}
于 2013-03-18T15:33:30.503 に答える