2010-09-30 37 views
11

Chúng tôi đang tìm kiếm để sử dụng SLF4J, nhưng có một điều chúng ta thấy được rằng bạn không thể xác định mức độ như một cuộc tranh cãi, tức làSLF4J cấp độ nhật ký như một cuộc tranh cãi

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

Bạn phải làm điều này

logger.info("message"); 

điều này ngăn không cho có thể truyền mọi thứ thông qua một phương pháp, vì vậy bạn có thể tack các thuộc tính khác cho tất cả các thông điệp tường trình trong một lớp.

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

Có cách nào để đạt được điều này bằng SLF4j không?

+1

chuỗi ký tự "INFO" và "DEBUG" và sử dụng phản chiếu để gọi đúng phương pháp - chỉ cần đùa! – irreputable

+0

Thật vậy nó rất thiển cận và hối hận rằng hầu hết (có lẽ tất cả) logger đương đại vẫn theo mô hình cổ xưa – matanster

Trả lời

6

Câu trả lời là Không. Hãy tham khảo this discussion.

+0

Có một cách để làm điều đó, nhưng nó liên quan đến việc xử lý bản ghi nhật ký mà slf4j tìm thấy. - xem câu trả lời của tôi dưới đây. – PaulG

8

Viết trình bao bọc xung quanh cuộc gọi slf4j và tạo enum của riêng bạn cho sáu cấp độ nhật ký. Sau đó, trong trình bao bọc của bạn, hãy sử dụng nút chuyển để gọi đúng cuộc gọi slf4j.

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

Vâng, về mặt kỹ thuật, SLF4J không cung cấp cho bạn phương thức logger.log (Cấp độ thư). Nhưng tôi tìm thấy một cách xung quanh đó. [sửa: sử dụng nội tâm]

Sử dụng đoạn mã bên dưới, bạn có thể lấy trình ghi nhật ký gốc mà slf4j tìm thấy và gói cho bạn khi chạy. Nếu bạn sẽ nhớ lại, slf4j chỉ đơn giản là một trình bao bọc xung quanh việc triển khai slf4j từ một nhà cung cấp khác (hoặc là, jdkLogging, Log4J, JCL, etc ...). Vì vậy, ở đây:

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

Sau đó, bạn có thể sử dụng nó như thế này:

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 ...)... 

Vì vậy, trong khi nó không phải là về mặt kỹ thuật trong vòng slf4j, nó có thể làm điều đó bằng slf4j như giao diện đăng nhập chính của bạn.

2

Hoán đổi của chúng tôi kêu la cho mẫu ủy quyền. Về cơ bản bạn nêm thực hiện của riêng bạn Logger giữa mã và SLF4J của bạn và "mở rộng" các phương pháp có liên quan:

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 
} 

Đây là sử dụng trong mã số kinh doanh như thế này:

public class Test 
{ 
    Logger log; 

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

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

Đối với việc tái sử dụng tối ưu của MyLogger lớp SomeObj phải sử dụng Object.toString() hoặc phải triển khai giao diện MyLogger có thể sử dụng để nhận phụ lục thư.

Các vấn đề liên quan