2016-02-01 12 views
6

Tôi có vấn đề sau: Tôi muốn sử dụng số java.util.logging.Logger. Không, tôi tìm thấy các tài nguyên khác nhau 1, 2, 3, cách người ta có thể sửa đổi hành vi của trình ghi nhật ký.Làm thế nào để khởi tạo Logger một cách chính xác?

Đặc biệt trong câu hỏi 2 a (theo ý kiến ​​của tôi) cấu trúc tốt được đưa ra để khởi tạo nhật ký theo tên lớp. Điều này cũng cho phép sửa đổi độ dài trên mức gói dựa trên để gỡ lỗi nếu cần.

Sau một chút đào sâu vào vấn đề tôi phát hiện ra, trình ghi nhật ký toàn cục và bộ ghi "trống" (có tên "") không giống nhau. Xem thêm ví dụ bên dưới. Tôi vừa tạo một logger foo.Bar, được neo tại logger trống thay vì logger được gọi là foo. Chỉ khi tôi lần đầu tiên tạo trình ghi nhật ký bar, trình ghi nhật ký bar.Baz được neo vào đúng.

Điều này làm cho cách tiếp cận trong this question chủ yếu là vô ích vì không thể giả định nhật ký cha mẹ được tạo trước đó. Người ta phải phân tích tên lớp và tạo logger nếu cần, theo như tôi thấy.

Tôi có chính xác rằng tôi phải thêm một số mã static {...} để khởi tạo nhật ký theo cách đệ quy trước khi trình ghi nhật ký của riêng bạn có thể được khởi tạo không? Điều này có bất kỳ tác động tiêu cực nào nếu nhiều lớp học gọi phương thức Logger.getLogger(String) cho trình ghi nhật ký gói (dẫn đến nhiều cuộc gọi tổng thể, ví dụ: bar.Bazbar.FooBaz nhận nhật ký bar)?

import java.util.Enumeration; 
import java.util.logging.LogManager; 
import java.util.logging.Logger; 
public class TestLogger 
{ 
    public static void main(String[] args) 
    { 
     // Create the logger directly 
     Logger.getLogger("foo.Bar"); 
     // Create the logger objects step-by-step 
     Logger.getLogger("bar"); 
     Logger.getLogger("bar.Baz"); 
     // Put the available loggers to output 
     Enumeration<String> e = LogManager.getLogManager().getLoggerNames(); 
     while(e.hasMoreElements()) 
     { 
      String s = e.nextElement(); 
      Logger l = Logger.getLogger(s); 
      String p = (l.getParent() == null ? "none" : "'" + l.getParent().getName() + "'"); 
      System.out.println("'" + s + "': " + p); 
     } 
    } 
} 

Đầu ra của chương trình là

'bar': '' 
'global': '' 
'foo.bar': '' 
'bar.baz': 'bar' 
'': none 
+0

'java.utils.Logger's có thể phức tạp. Mặc dù tôi không hiểu rõ câu hỏi thực sự ở đây là gì, một lưu ý quan trọng (có thể): Logger có thể là rác được thu thập. Khi bạn viết 'Logger.getLogger (" foo "). SetLevel (x)' trong phương thức 'main' của bạn, và sau đó lấy logger với' Logger.getLogger ("foo") 'ở một nơi khác, nó ** có thể ** là một ví dụ khác! Logger mà bạn thu được trong 'main' có thể đã được thu thập rác và lệnh' getLogger ("foo") 'thứ hai sẽ tạo một cá thể mới. – Marco13

Trả lời

1

Một tác động tiêu cực của việc có Logger.getLogger(String) trong mỗi lớp là bạn sẽ không thể để thử nó (hoặc vượt qua một logger đặc biệt) để kiểm tra.

Ví dụ: Hãy nói rằng bạn cần phải kiểm tra các lớp C sau:

package a.b; 
class C { 
    private Logger logger; 
    private int capacity; 
    private int size; 
    C(int capacity) { 
    this.logger = Logger.getLogger("a.b.C"); 
    this.capacity = capacity; 
    size = 0; 
    } 
    void add(int item) { 
    if (size >= capacity) { 
     logger.log("You already reached the capacity: " + capacity); 
    } 
    //... 
    } 
} 

Đó là một yêu cầu mà thêm các bản ghi nếu khả năng đạt được. Bây giờ bạn cần phải kiểm tra nó. Nó là rất khó khăn và hacky để thực hiện một bài kiểm tra đó kiểm tra này:

public void testCapacityReachedLogs() { 
    C c = new C(2); 
    c.add(1); 
    c.add(2); 
    // verify that c logged the exact string: "You already reached the capacity: 2" 
} 

Tuy nhiên nếu bạn có:

package a.b; 
class D { 
    private Logger logger; 
    private int capacity; 
    private int size; 
    D(Logger logger, int capacity) { 
    this.logger = logger; 
    this.capacity = capacity; 
    size = 0; 
    } 
    void add(int item) { 
    if (size >= capacity) { 
     logger.log("You already reached the capacity: " + capacity); 
    } 
    //... 
    } 
} 

Bây giờ bạn có thể thử Logger:

public void testCapacityReachedLogs() { 
    Logger logger = getMock(Logger.class); 
    D d = new D(logger, 2); 
    d.add(1); 
    d.add(2); 
    verify(logger).log("You already reached the capacity: 2"); 
} 

Lưu ý "giả "mã liên quan không nhất thiết phải tuân theo cú pháp của một khung công tác, nó chỉ là ví dụ.

+0

Bạn có ý gì khi "chế nhạo"? Bạn có thể giải thích một chút được không? –

+0

@ChristianWolf Tôi đã thêm một ví dụ với "mô phỏng" – Gavriel

+0

Ahh, tôi hiểu. Cảm ơn vì đã giải thích. –

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