2011-07-02 38 views
8

Hiện tại tôi đang phát triển để trở thành dịch vụ web còn lại lớn (chức năng khôn ngoan) và tôi muốn ghi nhật ký thực sự tốt, vì vậy tôi có thể hiểu rõ những gì đang xảy ra ở đâu. Để bây giờ tôi sử dụng log4j cho khai thác gỗ, sử dụng thiết lập nối này:Cách tốt nhất để sửa đổi log4j được thêm vào để ghi nhật ký

<!-- Appenders --> 
<appender name="console" class="org.apache.log4j.ConsoleAppender"> 
    <param name="Target" value="System.out" /> 
    <layout class="org.apache.log4j.PatternLayout"> 
     <param name="ConversionPattern" value="%-5p: %c - %m%n" /> 
    </layout> 
</appender> 

trong đó sản xuất các loại bản ghi:

10:44:55,893 INFO [STDOUT] INFO : my.package.MyClass - I'm class message 
  1. Làm thế nào tôi có thể làm cho cái nhìn thông điệp này như tức

    10:44:55,893 INFO : my.package.MyClass - I'm class message 
    
  2. Tôi có thể tạo một ứng dụng đặc biệt hay bất cứ thứ gì, và sử dụng nó trong một số lớp không có trong tất cả, nghĩa là tôi muốn ave trong vài trong số các bản ghi của tôi này:

    • Payload: some request parameters
    • Response: some response that my service returns
    • extra data : some extra data

Nếu không có những INFO [STDOUT] INFO my.package.MyClass in front of it

CẬP NHẬT

Tôi quên đề cập đến trong câu hỏi rằng tôi đang sử dụng Jboss 5. Tôi nghĩ rằng jboss có thể thêm 10:44:55,893 INFO [STDOUT] vào bất kỳ định dạng nào mà tôi đặt trong cấu hình log4j của mình.

BOUNTY CẬP NHẬT

tôi đã thay đổi này:

<!-- ============================== --> 
    <!-- Append messages to the console --> 
    <!-- ============================== --> 

    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> 
     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/> 
     <param name="Target" value="System.out"/> 
     <param name="Threshold" value="INFO"/> 

     <layout class="org.apache.log4j.PatternLayout"> 
     <!-- The default pattern: Date Priority [Category] Message\n --> 
     <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/> 
     </layout> 
    </appender> 

này:

<!-- ============================== --> 
    <!-- Append messages to the console --> 
    <!-- ============================== --> 

     <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> 
      <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/> 
      <param name="Target" value="System.out"/> 
      <param name="Threshold" value="INFO"/> 

      <layout class="org.apache.log4j.PatternLayout"> 
      <!-- The default pattern: Date Priority [Category] Message\n --> 
      <param name="ConversionPattern" value="%m%n"/> 
      </layout> 
     </appender> 

Và nó làm việc, nhưng có vẻ như loại xấu xí để làm điều đó như thế này. Còn cách nào khác không? Tôi đang sử dụng kết hợp Spring MVC/JBoss.

Tôi bây giờ nhận được thông điệp sạch đẹp:

10:44:55,893 INFO : my.package.MyClass - I'm class message 

mà không gây phiền nhiễu

10:44:55,893 INFO [STDOUT] 

tiền tố

+0

Không JBoss nhưng% d {ABSOLUTE} đã cho bạn 10: 44: 55,893 thư – Dima

+0

Bạn có thể làm rõ - điều gì xấu về việc đặt mẫu chuyển đổi tùy chỉnh? – GargantuChet

Trả lời

7

Câu hỏi 1:

Sử dụng cách bố trí mô hình sau đây cho bạn appender:

<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p: %c - %m%n" /> 

Mẫu chuyển đổi trong tệp cấu hình bạn đã nêu không dẫn đến loại nhật ký bạn đã nêu. Ví dụ: ngày/giờ không được bao gồm trong mẫu chuyển đổi của bạn.


Câu hỏi 2:

Bạn có thể sử dụng một logger đặc biệt trong đó sử dụng một appender mà chỉ được đăng nhập thông điệp tinh khiết.

cấu hình của bạn sẽ ví dụ trông giống như sau:

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> 

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> 

    <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender"> 
     <param name="Target" value="System.out" /> 
     <layout class="org.apache.log4j.PatternLayout"> 
      <param name="ConversionPattern" value="%m%n" /> 
     </layout> 
    </appender> 

    <appender name="consoleAppender2" class="org.apache.log4j.ConsoleAppender"> 
     <param name="Target" value="System.out" /> 
     <layout class="org.apache.log4j.PatternLayout"> 
      <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p: %c - %m%n" /> 
     </layout> 
    </appender> 

    <logger name="specialLogger" additivity="false"> 
     <level value="INFO" /> 
     <appender-ref ref="consoleAppender" /> 
    </logger> 

    <root> 
     <priority value="INFO" /> 
     <appender-ref ref="consoleAppender2" /> 
    </root> 

</log4j:configuration> 

Bạn sử dụng specialLogger cho những thông điệp tinh khiết mà không có thông tin bổ sung. Nó có thể được sử dụng trong nhiều lớp.

Trong cấu hình của đặc biệtLogger, additivity = "false" là cần thiết, bởi vì nếu không cũng là appender consoleAppender2 của logger gốc sẽ đăng nhập cùng một thông điệp. (Thông điệp sẽ được đăng nhập hai lần trong trường hợp này.)

Mã của bạn có thể ví dụ như thế này:

public class TestClassA 
{ 
    private static Logger specialLogger = Logger.getLogger("specialLogger"); 
    private static Logger logger = Logger.getLogger(TestClassA.class);  

    public TestClassA() { 

    } 

    public void doSomething() { 
     logger.info("Some message from TestClassA"); 
     specialLogger.info("Some message via the specialLogger from TestClassA"); 
    } 
} 

Calling kết quả doSomething trong:

17:17:18,125 INFO : com.foo.TestClassA - Some message from TestClassA 
Some message via the specialLogger from TestClassA 

Một nơi nào đó trong lớp học chính của bạn bạn cần định cấu hình log4j như bình thường, ví dụ:

DOMConfigurator.configureAndWatch("log4j.xml", 60 * 1000); 
+0

ngay cả khi tôi sử dụng tất cả những gì bạn đề nghị tôi vẫn không thể loại bỏ "13: 13: 43,428 INFO [STDOUT]" gây phiền toái này trước bất kỳ thứ gì tôi thay đổi trong appender, cài đặt của bạn hoạt động nhưng chỉ sau này phần.. –

1

Hãy thử sử dụng mẫu này vì nó sẽ cung cấp bạn làm sạch thông điệp:

<param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p %c %X %m/> 

Bạn nên thêm một số giá trị duy nhất vào MDC khi có yêu cầu, sau đó thêm% X {uniqueValueKey} vào mẫu của bạn. Nó sẽ cho phép bạn theo dõi các bản ghi cho yêu cầu duy nhất này.

4

Các INFO [STDOUT] thường đến từ log4j cũng nghe System.out. Chúng tôi đã có một trường hợp tương tự mà bản thân ứng dụng có cấu hình log4j riêng của nó và do đó có appender gốc riêng của nó. Điều này sẽ đăng nhập vào giao diện điều khiển được lắng nghe bởi JBoss log4j. Điều này lần lượt thêm INFO [STDOUT] như thể bạn đang viết trực tiếp đến System.out (hoặc ERROR [STDERR] khi viết thư cho System.err).

Giải pháp trong trường hợp của chúng tôi là xóa cấu hình log4j của ứng dụng cụ thể và chỉ sử dụng cấu hình JBoss ghi vào.

Một cách khác có thể là ghi trực tiếp vào tệp nhật ký cụ thể của ứng dụng thay vì ghi vào bảng điều khiển. Trong môi trường máy chủ, bạn có thể tham khảo hầu hết các tệp nhật ký.

Đối với phần thứ hai, tức là tự động mở rộng các bản ghi với phản ứng, yêu cầu, vv dữ liệu:

Trong một trường hợp chúng tôi đã có một lớp siêu cho đậu stateless session đó cung cấp đăng nhập chức năng và đã có một (ghi đè lên) logger mỗi ví dụ. Các phương thức cơ sở như info sau đó sẽ gọi trình ghi nhật ký và tự động thêm dữ liệu cần thiết.

Cách tiếp cận thứ hai có thể là MCD, tức là bạn đặt một số dữ liệu (như yêu cầu) vào MDC địa phương chủ đề (bản đồ) và sau đó truy cập chúng trong định nghĩa mẫu của bạn.

Ví dụ: chúng tôi có một số ứng dụng tương tự nhau, mỗi ứng dụng có một số lớp mà những người khác cũng có. Vì vậy, chúng tôi cần phải ứng dụng nào được thông báo có nguồn gốc từ và do đó thêm vào tên ứng dụng vào MDC:

Trong mã:
MDC.put("app.name", "myapplication");

Trong mô hình log4j config:
<param name="ConversionPattern" value="%d %-5p [%c (%X{app.name})] %m%n"/> (chú ý % X {app.name})

Tôi không kiểm tra xem bạn có thể làm gì đó như đưa yêu cầu vào MDC và sau đó sử dụng: %X{request.getAttribute('xyz')} nhưng nếu nó chỉ nhận giá trị trong MDC và gọi toString() trên đó, bạn có thể tạo yêu cầu wrapper như thế này:

class RequestLogWrapper { 
    private HttpServletRequest request; //initialize through constructor etc. 

    public String toString() { 
    return request.getAttribute("xyz") + ";" + request.getAttribute("abc") + ... //handle null etc. as well 
    } 
} 

Sau đó gọi MDC.put("request", new RequestLogWrapper(request)); và trong cấu hình sử dụng %X{request}.

0

để chỉ in các tin nhắn, mẫu chuyển đổi sau sẽ thực hiện.

<param name="ConversionPattern" value="%m%n"/> 

Tùy thuộc vào yêu cầu của bạn, bạn có thể thiết lập các mô hình chuyển đổi sang bất cứ điều gì bạn muốn

  1. % -5p đề cập đến các loại log entry. Điều này sẽ xuất hiện trong tệp nhật ký dưới dạng INFO, DEBUG, ERROR, v.v. Về mặt kỹ thuật,% p sẽ đủ để bao gồm mô tả này; -5 là để bao gồm từ trong cột có chiều rộng 5 ký tự.
  2. % d đề cập đến ngày.
  3. % t vào tên của chuỗi đã nêu mục nhập nhật ký này.
  4. % c liệt kê danh mục tạo nhật ký này thường là tên lớp .
  5. % m hiển thị thông báo
  6. % n thêm trở lại vận chuyển.

Bạn sẽ đặt tất cả thông tin liên quan chỉ trong tin nhắn? Tôi không chắc chắn nhưng nó không phải là một ý tưởng tốt.

1

Nếu bạn không thích tệp cấu hình log4j xml, bạn có thể chuyển sang tệp thuộc tính thay thế. Bạn không thể cấu hình bộ lọc bằng cách sử dụng tệp thuộc tính đơn giản nhưng vì có vẻ như bạn không cần chúng, đây không phải là vấn đề.

Cho rằng bạn

... hiện đang phát triển sẽ sớm được (khôn ngoan chức năng) dịch vụ web còn lại lớn và tôi muốn chụp các bản ghi thực sự tốt, vì vậy tôi có thể có một cái nhìn sâu sắc tốt về những gì là đang diễn ra ở đâu.

thì tôi sợ rằng đầu ra mong muốn của bạn sẽ không cung cấp cho bạn nhiều thông tin chi tiết, nó sẽ không mở rộng, và nó sẽ khiến bạn mất tập trung khi ứng dụng trở nên lớn như mong đợi ...

Vui lòng tham khảo Log4j Best Practices để có tham khảo tốt về thiết kế nhật ký.Hãy xem TẤT CẢ các đoạn của nó bao gồm cả việc xem xét mỹ phẩm ở cuối cùng. Hi vọng điêu nay co ich.

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