JavaロギングAPIを使用しているときに、デフォルトのコンソールハンドラーを無効にするにはどうすればよいですか?


92

こんにちは、アプリケーションにJavaロギングを実装しようとしています。2つのハンドラを使用したい。ファイルハンドラーと自分のコンソールハンドラー。私のハンドラーはどちらも正常に動作します。私のログはファイルとコンソールに送信されます。ロギングはデフォルトのコンソールハンドラーにも送信されますが、これは不要です。私のコードを実行すると、コンソールに送信される追加の2行が表示されます。デフォルトのコンソールハンドラーを使用したくありません。デフォルトのコンソールハンドラーを無効にする方法を知っている人はいますか?作成した2つのハンドラーのみを使用します。

Handler fh = new FileHandler("test.txt");
fh.setFormatter(formatter);
logger.addHandler(fh);

Handler ch = new ConsoleHandler();
ch.setFormatter(formatter);
logger.addHandler(ch);

import java.util.Date;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class LoggingExample {
    private static Logger logger = Logger.getLogger("test");

    static {
        try {
            logger.setLevel(Level.INFO);

            Formatter formatter = new Formatter() {

                @Override
                public String format(LogRecord arg0) {
                    StringBuilder b = new StringBuilder();
                    b.append(new Date());
                    b.append(" ");
                    b.append(arg0.getSourceClassName());
                    b.append(" ");
                    b.append(arg0.getSourceMethodName());
                    b.append(" ");
                    b.append(arg0.getLevel());
                    b.append(" ");
                    b.append(arg0.getMessage());
                    b.append(System.getProperty("line.separator"));
                    return b.toString();
                }

            };

            Handler fh = new FileHandler("test.txt");
            fh.setFormatter(formatter);
            logger.addHandler(fh);

            Handler ch = new ConsoleHandler();
            ch.setFormatter(formatter);
            logger.addHandler(ch);

            LogManager lm = LogManager.getLogManager();
            lm.addLogger(logger);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        logger.info("why does my test application use the standard console logger ?\n" + " I want only my console handler (Handler ch)\n " + "how can i turn the standard logger to the console off. ??");
    }
}

1
私は優しく使用することをお勧めすることができますb.append(formatMessage(arg0))代わりにb.append(arg0.getMessage())。このformatMessage方法を使用するpublic void log(Level level, String msg, Object param1)と、フォーマッタを使用方法および類似の方法と互換性があります。
ビクター

回答:


102

デフォルトのコンソールハンドラーはルートロガーにアタッチされます。ルートロガーは、あなたを含む他のすべてのロガーの親です。だから私はあなたの問題を解決する2つの方法を見ます:

これがこの特定のクラスにのみ影響する場合、最も簡単な解決策は、親ロガーへのログの受け渡しを無効にすることです。

logger.setUseParentHandlers(false);

アプリ全体でこの動作を変更する場合は、独自のハンドラーを追加する前に、デフォルトのコンソールハンドラーをルートロガーから完全に削除できます。

Logger globalLogger = Logger.getLogger("global");
Handler[] handlers = globalLogger.getHandlers();
for(Handler handler : handlers) {
    globalLogger.removeHandler(handler);
}

注:他のクラスでも同じログハンドラーを使用する場合、最善の方法は、長期的にはログ構成を構成ファイルに移動することです。


2
setUseParentHandlersメソッドが機能します。ルートロガーからデフォルトのコンソールハンドラーを削除するにはどうすればよいですか?
loudiyimo 2010年

10
Logger.getLogger( "")を使用することもできます。これは、「グローバル」が機能しない場合に機能します(ミックス内のSLF4Jの結果である可能性があります)
sehugg

2
slf4jが必要な場合は、これを使用することをお勧めします LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();
Somatik

8
「」はルートロガーの識別子です。「グローバル」は名前付きロガー(ルートの子)であり、デフォルトで作成され、単純なロギングシナリオで使用されます
Paolo Fulgoni

1
この答えは私には
うまくいき

108

するだけ

LogManager.getLogManager().reset();

1
ありがとう、これが正しい答えです。正解としてマークされた答えは機能しません。
Andreas L.

1
これは、これがすべての名前付きのすべてのハンドラーに影響Loggerするため、より複雑なログシステムでは問題になる可能性があることを示しているはずです。これは、将来のロガーが影響を受けないようにするために、プロセスの最初に一度呼び出す必要があります。そしてもちろん、コンソールを必要とする人は、ConsoleHandler期待どおりにto を受け取る必要があります。
AxelH 2017

20

これは奇妙ですが Logger.getLogger("global") 、私のセットアップ(およびLogger.getLogger(Logger.GLOBAL_LOGGER_NAME))では機能しません。

しかしLogger.getLogger("")、仕事はうまくいきます。

この情報が誰かにも役立つことを願っています...


3
getLogger(Logger.GLOBAL_LOGGER_NAME)が機能しないのにgetLogger( "")が機能する理由を誰かに教えてもらえますか?
deinocheirus 2013年

2
@deinocheirusこの回答
Paolo Fulgoni 14

9

構成をリセットし、ルートレベルをオフに設定します

LogManager.getLogManager().reset();
Logger globalLogger = Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME);
globalLogger.setLevel(java.util.logging.Level.OFF);

5

親ロガーにメッセージを送信しないようにロガーに指示する必要があります。

...
import java.util.logging.*;
...
Logger logger = Logger.getLogger(this.getClass().getName());
logger.setUseParentHandlers(false);
...

ただし、これはロガーにハンドラーを追加する前に行う必要があります。


私の場合はこれでうまくいきましたが、このロガーに手動でハンドラーを追加する必要がありました。
Sachin Gorade
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.