Log4j Kaydedicilerini Programlı Olarak Yapılandırma


191

log4jİlk kez ( bağlama ile) SLF4J kullanmaya çalışıyorum .

Farklı düzeylerde oturum ve farklı appenders iletiler bir LoggerFactory tarafından döndürülebilir 3 farklı adlı günlükleri yapılandırmak istiyorum:

  • Logger 1 "FileLogger" DEBUG günlüğünü kaydeder ve DailyRollingFileAppender
  • Logger 2 "TracingLogger", TRACE + 'ı günlüğe kaydeder ve bir JmsAppender
  • Logger 3 "ErrorLogger" ERROR + 'yı günlüğe kaydeder ve farklı bir JmsAppender

Ayrıca programlı olarak yapılandırılmasını istiyorum (Java'da, XML veya bir log4j.propertiesdosyanın aksine ).

Normalde, bu Loggers'yi bir init()yöntem gibi bazı önyükleme kodunda bir yerde tanımlayacağımı hayal ediyorum . Ancak, kullanmak istediğim için slf4j-log4j, günlükçüleri nerede tanımlayabileceğim ve onları sınıfyoluna sunabileceğim konusunda kafam karıştı.

Ben yok inanmak SLF4J API kullanarak benim kod Hiç bu kaydediciler var olduğunu bilmez, çünkü bu (bir cephenin gibi) SLF4J altında yatan amaç ihlalidir. Kodum, SLF4J API'sine normal çağrılar yapar, bu da onları sınıf yolunda bulduğu log4j Kaydedicilerine iletir.

Ancak bu log4j Kaydedicilerini sınıf yolunda nasıl yapılandırabilirim?



3
Log4j 2.x bkz aşağıda kabul cevabı kullanmak 1.x için logging.apache.org/log4j/2.x/manual/customconfig.html
earcam

Yanıtlar:


279

Appender'ı Log4j'ye programlı olarak ekleyebilir / kaldırabilirsiniz:

  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

Bunu bir yerden init () 'e koymanızı öneririm, bunun başka bir şeyden önce uygulanacağından emin olabilirsiniz. Daha sonra kök kaydedicideki mevcut tüm ekleyicileri

 Logger.getRootLogger().getLoggerRepository().resetConfiguration();

ve kendinizinkini ekleyerek başlayın. Bunun çalışması için tabii ki sınıf yolunda log4j gerekir.

Not: Eklemek istediğiniz
her Logger.getLogger(...)şeyi alabilirsiniz . Kök kaydediciyi aldım çünkü her şeyin altında ve diğer kategorilerdeki diğer uygulayıcılardan geçen her şeyi işleyecek (aksi takdirde eklenti bayrağı ayarlanarak yapılandırılmadığı sürece).

Günlüğe kaydetmenin nasıl çalıştığını ve günlüklerin nerede yazıldığına nasıl karar verildiğini bilmeniz gerekiyorsa, bununla ilgili daha fazla bilgi için bu kılavuzu okuyun .
Kısacası:

  Logger fizz = LoggerFactory.getLogger("com.fizz")

"com.fizz" kategorisi için bir logger verecektir.
Yukarıdaki örnek için bu, onunla günlüğe kaydedilen her şeyin kök kaydedicideki konsola ve dosya ekleyicisine yönlendirileceği anlamına gelir.
Logger.getLogger ("com.fizz"). AddAppender (newAppender) 'a bir appender eklerseniz, oturum açma işlemi fizzroot logger ve newAppender.
Yapılandırma ile Kaydediciler oluşturmazsınız, sadece sisteminizdeki tüm olası kategoriler için işleyiciler sağlarsınız.


2
Teşekkürler oers! Hızlı soru - Ekleyicileri kök Kaydedici'ye eklediğinizi fark ettim. Bunun bir sebebi var mı?
IAMYourFaja

Ve daha da önemlisi, SLF4J'nin LoggerFactory'sinden hangi Logger'ı alacağımı belirtmem gerekecek. SLF4J'den log4j kök kaydedicisini istemek mümkün mü?
IAMYourFaja

3
@AdamTannon İstediğiniz Logger.getLogger'ı (...) alabilirsiniz. Kök kaydediciyi aldım çünkü her şeyin altında ve diğer kategorilerdeki diğer uygulayıcılardan geçen her şeyi işleyecek (aksi belirtilmedikçe). Logger hiyerarşisine bakın
oers

@AdamTannon log4j kök kaydedicisini almak için sl4j fabrikasını kullanamazsınız. SL4j bir tomruk cephesidir. Bundan belirli bir şey log4j alamazsınız.
Oers

2
oers - Harika geri bildiriminizi takdir ediyorum, ancak sadece buradaki tüm noktaları birleştirmiyorum. Örneğinizi, sisteme eklendikten sonra isteyen herhangi bir sınıf için kullanılabilecek yeni bir Logger (kök kaydedici değil) eklenmesini gösterecek şekilde değiştirebilir misiniz? Örneğin, normalde erişilebilen bir Logger, diyelim ki, Logger fizz = LoggerFactory.getLogger("com.fizz");Teşekkürler!
IAMYourFaja

47

Log4j'yi "her iki uçtan" ​​(tüketici tarafı ve yapılandırma sonu) kullanmaya çalıştığınız anlaşılıyor.

Slf4j api'ye karşı kodlama yapmak, ancak sınıf yolunun geri döneceği log4j Kaydedicilerinin yapılandırmasını önceden (ve programlı olarak) belirlemek istiyorsanız, kesinlikle tembel yapıyı kullanan bir tür günlük adaptasyonuna sahip olmanız gerekir.

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);
    }

Bu yaklaşımla, log4j kaydedicilerinizin nerede / ne zaman yapılandırılacağı konusunda endişelenmenize gerek yoktur. Sınıf yolu ilk kez istediğinde, tembel bir şekilde inşa edilir, geri alınır ve slf4j aracılığıyla kullanılabilir hale gelirler. Umarım bu yardımcı oldu!


2
Başarmak! Yararlı bir örnek için çok teşekkür ederim! @Oers - beni doğru yöne yönlendirmeye çalıştığınız için teşekkür ederim - Size özveriniz için yeşil çek vereceğim ama zharvey'e lütuf vermeliyim çünkü tam olarak aradığım şey buydu. Herkese tekrar teşekkürler!
IAmYourFaja

4

Log4j özelliklerinde bir ek tanımladıysanız ve bunu program aracılığıyla güncellemek istiyorsanız, log4j özelliklerinde adı ayarlayın ve ada göre alın.

Örnek bir log4j.properties girişi:

log4j.appender.stdout.Name=console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.Threshold=INFO

Güncellemek için aşağıdakileri yapın:

((ConsoleAppender) Logger.getRootLogger().getAppender("console")).setThreshold(Level.DEBUG);

1

Birisi log4j2'yi Java'da programlı olarak yapılandırmak istiyorsa, bu bağlantı yardımcı olabilir: ( https://www.studytonight.com/post/log4j2-programmatic-configuration-in-java-class )

Konsol Eklentisini yapılandırmanın temel kodu şöyledir:

ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();

builder.setStatusLevel(Level.DEBUG);
// naming the logger configuration
builder.setConfigurationName("DefaultLogger");

// create a console appender
AppenderComponentBuilder appenderBuilder = builder.newAppender("Console", "CONSOLE")
                .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
// add a layout like pattern, json etc
appenderBuilder.add(builder.newLayout("PatternLayout")
                .addAttribute("pattern", "%d %p %c [%t] %m%n"));
RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.DEBUG);
rootLogger.add(builder.newAppenderRef("Console"));

builder.add(appenderBuilder);
builder.add(rootLogger);
Configurator.reconfigure(builder.build());

Bu, varsayılan rootLogger'ı yeniden yapılandırır ve ayrıca yeni bir ekleyici oluşturur .

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.