Java günlük API'sini kullanırken varsayılan konsol işleyicisini nasıl devre dışı bırakabilirim?


93

Merhaba, uygulamamda java günlüğünü uygulamaya çalışıyorum. İki işleyici kullanmak istiyorum. Bir dosya işleyicisi ve kendi konsol işleyicim. Her iki işleyicim de iyi çalışıyor. Günlüğüm bir dosyaya ve konsola gönderilir. Günlüğüm de istemediğim varsayılan konsol işleyicisine gönderiliyor. Kodumu çalıştırırsanız, konsola fazladan iki satırın gönderildiğini göreceksiniz. Varsayılan konsol işleyicisini kullanmak istemiyorum. Varsayılan konsol işleyicisinin nasıl devre dışı bırakılacağını bilen var mı? Yalnızca oluşturduğum iki işleyiciyi kullanmak istiyorum.

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))Bunun yerine kullanmayı nazikçe önerebilir miyim b.append(arg0.getMessage())? İle formatMessageyöntemle size kullanım ile biçimlendirici uyumlu yapıyoruz public void log(Level level, String msg, Object param1)ve benzeri yöntemlerle.
Victor

Yanıtlar:


103

Varsayılan konsol işleyicisi, sizinki de dahil olmak üzere diğer tüm kaydedicilerin ebeveyni olan kök kaydediciye eklenir. Bu yüzden probleminizi çözmenin iki yolunu görüyorum:

Bu yalnızca sizin bu sınıfınızı etkiliyorsa, en basit çözüm, günlükleri ana günlükçüye aktarmayı devre dışı bırakmak olacaktır:

logger.setUseParentHandlers(false);

Bu davranışı uygulamanızın tamamı için değiştirmek istiyorsanız, kendi işleyicilerinizi eklemeden önce varsayılan konsol işleyicisini kök kaydediciden tamamen kaldırabilirsiniz:

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

Not: Aynı günlük işleyicilerini başka sınıflarda da kullanmak istiyorsanız, en iyi yol, günlük yapılandırmasını uzun vadede bir yapılandırma dosyasına taşımaktır.


2
setUseParentHandlers yöntemi çalışıyor, teşekkürler. varsayılan konsol işleyicisini kök kaydediciden nasıl kaldırabilirim?
loudiyimo

10
Ayrıca Logger.getLogger ("") 'ı da kullanabilirsiniz - bu benim için "global" ifadesinin olmadığı yerlerde çalışır (karışımdaki SLF4J'nin sonucu olabilir mi?)
sehugg

2
Eğer SLF4J istiyorsanız Bunu kullanmak önermek LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();
somatik

8
"", kök kaydedicinin tanımlayıcısıdır. "global", varsayılan olarak oluşturulan ve basit günlük senaryolarında kullanılacak adlandırılmış bir günlükçüdür (kökün alt öğesi)
Paolo Fulgoni

1
Bu cevap benim için işe yaramıyor ama Dominique'in
cevabı

110

Sadece yap

LogManager.getLogManager().reset();

1
Teşekkür ederim, bu doğru cevap. Doğru olarak işaretlenen cevap çalışmıyor.
Andreas L.

1
Bu, adlandırılmış her işleyicinin her işleyiciyi etkileyeceğine işaret etmelidir, bu Loggernedenle bu daha karmaşık bir Günlük sistemi için bir sorun olabilir. Bu, gelecekteki kaydedicinin etkilenmeyeceğinden emin olmak için sürecin başında bir kez çağrılmalıdır. Ve tabii ki, konsola ihtiyaç duyacak olanın ConsoleHandlerbeklendiği gibi bir to by alması gerekecek .
AxelH

20

Bu tuhaf ama Logger.getLogger("global") benim kurulumumda çalışmıyor (yanı sıra Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)).

Ancak Logger.getLogger("")iş iyi.

Umarım bu bilgi birilerine de yardımcı olur ...


3
birisi bize getLogger'ın (Logger.GLOBAL_LOGGER_NAME) neden çalışmadığını ama getLogger ("") çalıştığını söyleyebilir mi?
deinocheirus 01

2
@deinocheirus bu cevapla ilgili
Paolo Fulgoni

9

Yapılandırmayı sıfırlayın ve kök düzeyini KAPALI olarak ayarlayın

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

5

Kaydedicinize mesajlarını ana günlükçüye göndermemesi için talimat vermelisiniz:

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

Ancak, bu, günlükçüye daha fazla işleyici eklemeden önce yapılmalıdır.


Bu, benim durumumda işe yaradı, ancak bu günlükleyici için elle işleyici eklemem gerekti.
Sachin Gorade
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.