2012-01-23 5 views
163

Tôi đang cố gắng sử dụng SLF4J (với log4j ràng buộc) lần đầu tiên.Đặt cấu hình Log4j Loggers Programmatically

Tôi muốn cấu hình 3 Loggers tên khác nhau mà có thể được trả về bởi một LoggerFactory đó sẽ đăng nhập cấp độ khác nhau và đẩy các thông điệp để appenders khác nhau:

  • Logger 1 "FileLogger" nhật ký DEBUG và gắn thêm để DailyRollingFileAppender
  • Logger 2 "TracingLogger" nhật ký TRACE + và gắn thêm vào một Logger JmsAppender
  • 3 "ErrorLogger" nhật ký LỖI + và gắn thêm vào một khác nhau JmsAppender

Hơn nữa, tôi muốn chúng được lập cấu hình theo lập trình (trong Java, trái ngược với XML hoặc một tệp log4j.properties).

Tôi tưởng tượng rằng, thông thường, tôi sẽ xác định các Logger s ở đâu đó trong một số mã khởi động, như phương thức init(). Tuy nhiên, bởi vì tôi muốn sử dụng slf4j-log4j, tôi đang bối rối về nơi tôi có thể xác định logger và làm cho chúng có sẵn cho classpath.

Tôi không tin điều này là vi phạm mục đích cơ bản của SLF4J (như mặt tiền), vì mã của tôi sử dụng API SLF4J sẽ không bao giờ biết rằng những trình ghi nhật ký này tồn tại. Mã của tôi chỉ thực hiện các cuộc gọi bình thường tới API SLF4J, sau đó chuyển tiếp chúng đến Loggerj Logger mà nó tìm thấy trên đường dẫn lớp.

Nhưng làm cách nào để định cấu hình Logger Log4j đó trên đường dẫn lớp ... trong Java ?!

+0

http://stackoverflow.com/questions/1666121/programmatically-creating-different -log-files-using-log4j – skaffman

+2

Đối với log4j 1.x, hãy sử dụng câu trả lời được chấp nhận bên dưới cho 2.x xem https://logging.apache.org/log4j/2.x/manual/customconfig.html – earcam

Trả lời

242

Bạn có thể thêm/xóa appender lập trình để Log4j:

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 

tôi muốn đề nghị bạn đặt nó vào một init() ở đâu đó, bạn đang ở đâu chắc chắn, rằng điều này sẽ được thực hiện trước khi bất cứ điều gì khác. Sau đó, bạn có thể xóa tất cả các ứng dụng hiện có trên trình ghi nhật ký với

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

và bắt đầu thêm của riêng bạn. Bạn cần log4j trong classpath của khóa học để làm việc này.

Ghi chú:
Bạn có thể thực hiện bất kỳ Logger.getLogger(...) nào bạn muốn thêm người phụ trách. Tôi chỉ lấy logger gốc vì nó ở dưới cùng của tất cả mọi thứ và sẽ xử lý tất cả mọi thứ được thông qua các appender khác trong các loại khác (trừ khi cấu hình khác bằng cách thiết lập cờ additivity).

Nếu bạn cần biết cách ghi nhật ký hoạt động và cách quyết định nơi nhật ký được viết read this manual để biết thêm thông tin về điều đó.
Trong ngắn:

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

sẽ cung cấp cho bạn một logger cho thể loại "com.fizz".
Đối với ví dụ trên, điều này có nghĩa là tất cả mọi thứ được đăng nhập với nó sẽ được chuyển đến bàn điều khiển và trình bổ sung tệp trên trình ghi nhật ký gốc.
Nếu bạn thêm một appender vào Logger.getLogger ("com.fizz").addAppender (newAppender) sau đó đăng nhập từ fizz sẽ được xử lý bởi các ứng dụng từ trình ghi nhật ký gốc và newAppender.
Bạn không tạo Logger với cấu hình, bạn chỉ cần cung cấp trình xử lý cho tất cả các danh mục có thể có trong hệ thống của bạn.

+2

Cảm ơn các bạn! Câu hỏi nhanh - Tôi nhận thấy bạn đang thêm các ứng dụng vào Trình ghi nhật ký gốc. Có một lý do cho điều này? – IAmYourFaja

+0

Và, quan trọng hơn, tôi sẽ cần phải xác định Logger nào để lấy từ LoggerFactory của SLF4J. Có thể yêu cầu SLF4J cho logger gốc của log4j không? – IAmYourFaja

+3

@AdamTannon Bạn có thể lấy bất kỳ Logger.getLogger (...) nào bạn thích. Tôi chỉ lấy logger gốc vì nó ở dưới cùng của tất cả mọi thứ và sẽ xử lý tất cả mọi thứ được thông qua các appender khác trong các loại khác (trừ khi được cấu hình khác). [Xem hệ thống phân cấp logger] (https://logging.apache.org/log4j/1.2/manual.html) – oers

39

Có vẻ như bạn đang cố gắng sử dụng log4j từ "cả hai đầu" (đầu người tiêu dùng và kết thúc cấu hình).

Nếu bạn muốn mã chống lại lệnh slf4j api nhưng xác định trước thời hạn (và lập trình) cấu hình của log4j Logger mà đường dẫn lớp sẽ trả về, bạn hoàn toàn có để có một số kiểu ghi nhật ký thích hợp sử dụng xây dựng lười biếng.

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

Với phương pháp này, bạn không cần phải lo lắng về vị trí/khi nhật ký log4j được định cấu hình. Lần đầu tiên classpath yêu cầu họ, họ được xây dựng một cách uể oải, được trả lại và có sẵn thông qua slf4j. Hy vọng điều này đã giúp!

+1

Đóng đinh nó! Cảm ơn bạn rất nhiều vì một ví dụ hữu í[email protected] - cảm ơn bạn đã cố gắng chỉ đạo tôi đi đúng hướng - Tôi sẽ cho bạn kiểm tra màu xanh lá cây cho sự cống hiến của bạn nhưng phải cung cấp cho zharvey tiền thưởng vì đó là chính xác những gì tôi đang tìm kiếm. Cảm ơn một lần nữa tất cả mọi người! – IAmYourFaja

0

Trong trường hợp bạn đã xác định một appender trong thuộc tính log4j và muốn cập nhật nó theo lập trình, hãy đặt tên trong thuộc tính log4j và đặt tên theo.

Dưới đây là một bài viết mẫu log4j.properties:

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

Để cập nhật nó, làm như sau:

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