2010-09-30 21 views
11

, ancak sağlıklı bir argüman olarak seviyesini belirtemeyeceğinizi oldu bulduğu şey, yani buSLF4J Kayıt Düzeyi bağımsız değişken olarak biz SLF4J kullanmak isteyen

yapmak zorunda

Logger.log(Level.INFO, "messsage"); 

logger.info("message"); 

Bu, her şeyi bir yöntemle geçirebilmenizi önler, böylece diğer özellikleri bir sınıftaki tüm günlük iletilerine yapıştırabilirsiniz.

public class Test 
{ 
    public Test(SomeObj obj) 
    { 
     log(Level.INFO, "message"); 
    } 

    public void anotherMethod() 
    { 
     log(Level.DEBUG, "another message"); 
    } 
    private void log(Level level, String message) 
    { 
     logger.log(level, message + obj.someString()); 
    } 
} 

SLF4j'yi kullanarak bunu başarmanın bir yolu var mı?

+1

"INFO" ve "DEBUG" dizesini iletin ve doğru yöntemi çağırmak için yansımayı kullanın - sadece şaka! – irreputable

+0

Gerçekten de, çoğu (muhtemelen hepsi) çağdaş kaydedicilerin hala bu arkaik paradigmayı izledikleri için çok az endişeli ve pişmanlık duyuyorlar. – matanster

cevap

6

Yanıt Hayır. Bkz. this discussion.

+0

Bunu yapmanın bir yolu var, ancak bu, slf4j'nin bulduğu yerel günlükçüye bir tanıtımı içerir. - cevabımı aşağıya bakın. – PaulG

8

Slf4j çağrısının etrafına bir sarıcı yazın ve altı günlük düzeyleri için kendi numaranızı oluşturun. Daha sonra, sargınızda, doğru slf4j çağrısını çağırmak için bir anahtar kullanın.

void myLog(Level level, String message) 
{ 
    switch (level) 
    { 
    case FATAL: 
    log.fatal(message); 
    break; 
    case ERROR: 
    log.error(message); 
    break; 
    .... 
    } 
} 
1

Teknik olarak SLF4J size bir logger.log (Düzey, ileti) yöntemi sunmuyor. Ama bunun etrafında bir yol buldum. [edit: introspection kullanır]

Aşağıdaki kod parçacığını kullanarak, çalışma zamanında slf4j öğesinin bulunduğunuz ve size sarıldığı yerel günlüğünü alabilirsiniz. Eğer hatırlayacaksanız, slf4j başka bir sağlayıcıdan (yani, jdkLogging, Log4J, JCL, vb.) Bir slf4j uygulaması etrafında bir sarıcıdır. Yani burada:

public Object getNativeLogger(org.slf4j.Logger logger) { 
    Object result = null; 
    if (logger.getClass().getName().equals("org.slf4j.impl.Log4jLoggerAdapter")) { 
     try { 
     Field f = Log4jLoggerAdapter.class.getDeclaredField("logger"); 
     f.setAccessible(true); 
     result = (org.apache.log4j.Logger)f.get(logger); 
     } 
     catch(Exception e) { 
     System.out.println("Unable to access native log4j logger"); 
     } 
    } 
    else if (logger.getClass().getName().equals("org.slf4j.impl.JDK14LoggerAdapter")) { 
     try { 
     Field f = Jdk14Logger.class.getDeclaredField("logger"); 
     f.setAccessible(true); 
     result = (Jdk14Logger)f.get(logger); 
     } 
     catch(Exception e) { 
     System.out.println("Unable to access native log4j logger"); 
     } 
    } 
    else if (..... other native loggers slf4j supports).... 
    } 
    return result; 
} 

Sonra bu gibi kullanabilirsiniz:

Object l = getNativeLogger(mySlf4jLogger); 
    if (l instanceof org.apache.log4j.Logger) { 
     org.apache.log4j.Logger logger = (org.apache.log4j.Logger) l; 
     logger.log(CUSTOMLog4JLevel, message); 
    } 
    else if(.... other implementations that you care about ...)... 

Yani teknik olarak slf4j içinde değil iken, birincil günlüğü arayüz olarak SLF4J kullanarak bunu yapmak mümkündür.

2

Usecase, temsilci deseni için çığlık atıyor.

public class Test 
{ 
    Logger log; 

    public Test(SomeObj obj) 
    { 
     log = new MyLogger(Test.class, obj); 
     log.logInfo("message"); 
    } 

    public void anotherMethod() 
    { 
     logDebug("another message"); 
    } 
} 

optimal yeniden kullanılabilirliği için:

class MyLogger implements Logger { 

    Logger realLogger; 
    Object userData; 


    MyLogger(Class clazz, Object userData){ 
     this.realLogger = LoggerFactory.getLogger(clazz); 
    } 

    public void debug(String msg) { 
     realLogger.debug(msg + userData.someString()); 
    } 

    // many more methods, perhaps per java.lang.reflect.Proxy 
} 

Bu böyle iş kodunda kullanılmasıdır: Temelde alakalı yöntemler "genişletmek" için kodu ve SLF4J arasında Logger kendi uygulaması takoz MyLogger sınıfı SomeObj, Object.toString() numaralı telefonu kullanmalıdır veya ileti eki almak için MyLogger'un kullanabileceği bir arabirim uygulamalıdır.

İlgili konular