slf4j: cách ghi nhật ký định dạng tin nhắn, mảng đối tượng, ngoại lệ


274

Cách tiếp cận đúng để ghi nhật ký cả tin nhắn dân cư và dấu vết ngăn xếp của ngoại lệ là gì?

logger.error(
    "\ncontext info one two three: {} {} {}\n",
    new Object[] {"1", "2", "3"},
    new Exception("something went wrong"));

Tôi muốn tạo ra một đầu ra tương tự như thế này:

context info one two three: 1 2 3
java.lang.Exception: something went wrong
stacktrace 0
stacktrace 1
stacktrace ...

phiên bản slf4j 1.6.1


3
Tôi không hiểu tại sao slf4j sử dụng cú pháp chuỗi định dạng của riêng nó thay vì kiểu% s tiêu chuẩn. Làm phiền.
Keith Tyler

@KeithTyler Tôi thích {}hơn, vấn đề về hương vị ...
Betlista

@KeithTyler toString()Phương pháp của các đối số có thể tốn kém. Với cú pháp này, chỉ một tham chiếu đến từng đối tượng được truyền và toString()phương thức chỉ được gọi nếu thông điệp cụ thể thực sự được ghi lại. Các đối tượng được tham chiếu trong một info()cuộc gọi nhật ký sẽ không có toString()phương thức được gọi nếu mức nhật ký WARNcao hơn hoặc cao hơn. Các {}cú pháp là một lời nhắc nhở cho người dùng rằng đây không phải là một String.format()hoạt động -like, tức là họ phải vượt qua đối tượng chứ không phải là cơ quan đại diện chuỗi đó.
user149408

Câu trả lời:


426

Kể từ SLF4J 1.6.0, với sự có mặt của nhiều tham số và nếu đối số cuối cùng trong câu lệnh ghi nhật ký là ngoại lệ, thì SLF4J sẽ cho rằng người dùng muốn đối số cuối cùng được coi là ngoại lệ và không phải là tham số đơn giản. Xem thêm mục FAQ có liên quan .

Vì vậy, viết (trong phiên bản SLF4J 1.7.x trở lên)

 logger.error("one two three: {} {} {}", "a", "b", 
              "c", new Exception("something went wrong"));

hoặc viết (trong phiên bản SLF4J 1.6.x)

 logger.error("one two three: {} {} {}", new Object[] {"a", "b", 
              "c", new Exception("something went wrong")});

sẽ mang lại

one two three: a b c
java.lang.Exception: something went wrong
    at Example.main(Example.java:13)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at ...

Đầu ra chính xác sẽ phụ thuộc vào khung cơ bản (ví dụ: logback, log4j, v.v.) cũng như cách cấu hình khung cơ bản. Tuy nhiên, nếu tham số cuối cùng là một ngoại lệ, nó sẽ được hiểu như vậy bất kể khung cơ bản.


4
Bạn đang sử dụng khung đăng nhập cơ bản nào? Như đã đề cập trong câu trả lời của tôi ở trên, nếu tham số cuối cùng là một ngoại lệ, nó sẽ được hiểu như vậy bất kể khung cơ bản. (Đã thử nghiệm với logback, slf4j-log4j12, slf4j-jdk14 và slf4j-đơn giản.)
Ceki

3
Xin lỗi, tôi không nhận ra rằng trong ví dụ của bạn, bạn đã sử dụng n = 3 giữ chỗ trong chuỗi định dạng và n + 1 = 4 phần tử trong mảng đối tượng. Tôi có n giữ chỗ trong chuỗi định dạng và n phần tử trong mảng đối tượng cộng với một ngoại lệ là tham số thứ ba. Kỳ vọng của tôi là ngoại lệ sẽ được in bằng stacktrace nhưng điều này không bao giờ xảy ra. Cái này có hoạt động như thiết kế không? Ngoài ra, nếu tôi có n phần giữ chỗ và n phần tử trong mảng đối tượng với một ngoại lệ là phần tử cuối cùng thì tôi không thấy bất kỳ stacktrace nào. Có lẽ n giữ chỗ với các đối tượng n + 1 trong một mảng nên được nhấn mạnh hơn một chút.
chèo

7
Tôi sẽ cho @Ceki một khoảng thời gian khó khăn về việc nó không ở trong Javadocs mà là ở đầu Loggerlớp javadoc: slf4j.org/apidocs/org/slf4j/Logger.html
Adam Gent

1
Tôi đã tạo yêu cầu cải tiến , bạn có thể bỏ phiếu cho nó nếu bạn thích nó.
Betlista

8

Ngoài câu trả lời của @Ceki, Nếu bạn đang sử dụng logback và thiết lập tệp cấu hình trong dự án của bạn (thường là logback.xml), bạn có thể xác định nhật ký để vẽ dấu vết ngăn xếp bằng cách sử dụng

<encoder>
    <pattern>%date |%-5level| [%thread] [%file:%line] - %msg%n%ex{full}</pattern> 
</encoder>

% ex trong mẫu là điều làm nên sự khác biệt

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.