2.1 Trình ghi nhật ký đầu tiên - log4j

Như bạn đã biết, lịch sử của nhật ký bắt đầu bằng System.err.println()việc xuất bản ghi ra bàn điều khiển. Nó vẫn được sử dụng tích cực để gỡ lỗi, ví dụ: Intellij IDEA sử dụng nó để hiển thị thông báo lỗi cho bảng điều khiển. Nhưng tùy chọn này không có bất kỳ cài đặt nào, vì vậy hãy tiếp tục.

Trình ghi nhật ký đầu tiên và phổ biến nhất được gọi là Log4j. Đó là một giải pháp tốt và có khả năng tùy biến cao. Do nhiều hoàn cảnh khác nhau, quyết định này không bao giờ được JDK đưa ra, điều này khiến toàn bộ cộng đồng vô cùng khó chịu.

Trình ghi nhật ký này không chỉ có khả năng ghi nhật ký, nó được các lập trình viên tạo ra dành cho các lập trình viên và cho phép họ giải quyết các vấn đề liên tục phát sinh liên quan đến việc ghi nhật ký.

Như bạn đã biết, các bản ghi cuối cùng được viết để một số người đọc chúng và cố gắng hiểu điều gì đã xảy ra trong quá trình hoạt động của chương trình - điều gì và khi nào sai như mong đợi.

log4jba điều cho việc này:

  • ghi nhật ký gói con;
  • bộ appender (kết quả);
  • cài đặt tải lại nóng.

Đầu tiên, các cài đặt log4jcó thể được viết theo cách cho phép đăng nhập trong một gói và tắt nó trong một gói khác. Ví dụ: có thể kích hoạt đăng nhập trong com.codegym.server, nhưng vô hiệu hóa nó trong com.codegym.server.payment. Điều này giúp có thể nhanh chóng xóa thông tin không cần thiết khỏi nhật ký.

Thứ hai, log4jnó cho phép ghi kết quả ghi nhật ký vào một số tệp nhật ký cùng một lúc. Và đầu ra cho từng cái có thể được cấu hình riêng lẻ. Ví dụ: trong một tệp, chỉ có thể ghi thông tin về các lỗi nghiêm trọng, trong tệp khác - nhật ký từ một mô-đun cụ thể và trong tệp thứ ba - nhật ký trong một thời gian nhất định.

Do đó, mỗi tệp nhật ký được điều chỉnh theo một loại vấn đề dự kiến ​​cụ thể. Điều này đơn giản hóa đáng kể cuộc sống của các lập trình viên, những người không thích xem qua các tệp nhật ký gigabyte theo cách thủ công.

Và cuối cùng, thứ ba, log4jnó cho phép thay đổi cài đặt nhật ký trực tiếp trong khi chương trình đang chạy mà không cần khởi động lại. Điều này rất hữu ích khi cần sửa công việc của nhật ký để tìm thêm thông tin về một lỗi cụ thể.

Quan trọng! Có hai phiên bản nhật ký log4j: 1.2.x2.xx , không tương thích với nhau .

Bạn có thể kết nối bộ ghi với dự án bằng mã:

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
  </dependency>

  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
  </dependency>
</dependencies>

2.2 Trình ghi nhật ký chính thức đầu tiên - THÁNG 7: java.util.logging

Sau khi sở thú các trình ghi nhật ký xuất hiện trong cộng đồng Java, các nhà phát triển JDKđã quyết định tạo một trình ghi nhật ký tiêu chuẩn mà mọi người sẽ sử dụng. Đây là cách trình ghi nhật ký xuất hiện JUL: gói java.util.logging.

Tuy nhiên, trong quá trình phát triển, những người tạo ra trình ghi nhật ký không phải là cơ sở log4jmà là một biến thể của trình ghi nhật ký của IBM, điều này đã ảnh hưởng đến sự phát triển của nó. Tin tốt là máy ghi JULđược bao gồm JDK, tin xấu là ít người sử dụng nó.

THÁNG 7

Các nhà phát triển không chỉ JULtạo ra “một tiêu chuẩn chung khác” , mà họ còn tạo ra các cấp độ ghi nhật ký của riêng họ cho tiêu chuẩn đó, khác với các cấp độ được những người ghi nhật ký phổ biến chấp nhận vào thời điểm đó.

Và đó là một vấn đề lớn. Rốt cuộc, các sản phẩm Javathường được thu thập từ một số lượng lớn thư viện và mỗi thư viện như vậy có bộ ghi riêng. Vì vậy, cần phải định cấu hình tất cả các trình ghi nhật ký trong ứng dụng.

Mặc dù bản thân logger là khá tốt. Tạo một logger ít nhiều giống nhau. Để làm điều này, bạn cần nhập:


java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());

Tên lớp được thông qua đặc biệt để biết việc ghi nhật ký đến từ đâu.

Chỉ với bản phát hành, các nhà phát triển đã giải quyết được các vấn đề quan trọng, sau đó nó JULthực sự thuận tiện khi sử dụng. Trước đó, nó là một loại máy ghi nhật ký hạng hai.

Trình ghi nhật ký này cũng hỗ trợ các biểu thức lambda và đánh giá lười biếng. Bắt đầu với Java 8, bạn có thể vượt qua Supplier<String>. Điều này giúp chỉ đọc và tạo chuỗi vào thời điểm thực sự cần thiết chứ không phải mọi lúc như trước đây.

Các phương thức có đối số Supplier<String> msgSuppliertrông như thế này:

public void info(Supplier msgSupplier) {
   log(Level.INFO, msgSupplier);
}

2.3 Trình bao bọc logger đầu tiên - JCL: jakarta commons logging

Trong một thời gian dài, không có một tiêu chuẩn duy nhất nào giữa những người ghi nhật ký, lẽ ra nó JULphải trở thành một, nhưng tệ hơn là log4j, nên một tiêu chuẩn duy nhất không bao giờ xuất hiện. Nhưng cả một sở thú của những người khai thác gỗ đã xuất hiện, mỗi người đều muốn trở nên giống nhau.

JCL

Tuy nhiên, các nhà phát triển Java thông thường không thích rằng hầu hết mọi thư viện đều có bộ ghi nhật ký riêng và cần được cấu hình theo một cách đặc biệt nào đó. Do đó, cộng đồng đã quyết định tạo một trình bao bọc đặc biệt đối với các trình ghi nhật ký khác - đây là cáchJCL: jakarta commons logging

Và một lần nữa, dự án, được tạo ra để trở thành người dẫn đầu, đã không trở thành một. Bạn không thể tạo ra người chiến thắng, bạn chỉ có thể trở thành người chiến thắng. Chức năng JCLrất kém và không ai muốn sử dụng nó. Máy ghi nhật ký, được thiết kế để thay thế tất cả các máy ghi nhật ký, cũng chịu chung số phận vì nó JULkhông được sử dụng.

Mặc dù nó đã được thêm vào nhiều thư viện do cộng đồng Apache phát hành, vườn thú của những người ghi nhật ký chỉ ngày càng phát triển.

2.4 Trình ghi nhật ký cuối cùng đầu tiên - Logback

Nhưng đó không phải là tất cả. Nhà phát triển log4jđã quyết định rằng anh ta là người thông minh nhất (xét cho cùng, hầu hết mọi người đều sử dụng máy ghi nhật ký của anh ta) và quyết định viết một trình ghi nhật ký cải tiến mới có thể kết hợp các ưu điểm log4jcủa các trình ghi nhật ký khác.

Trình ghi nhật ký mới được gọi là Logback. Máy ghi nhật ký này được cho là sẽ trở thành máy ghi nhật ký đơn trong tương lai mà mọi người sẽ sử dụng. Nó dựa trên cùng một ý tưởng như trong log4j.

Bạn có thể kết nối bộ ghi này với dự án bằng mã:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

Sự khác biệt là ở Logback:

  • hiệu suất được cải thiện;
  • thêm hỗ trợ bản địa slf4j;
  • tùy chọn lọc mở rộng.

Một ưu điểm khác của trình ghi nhật ký này là nó có các cài đặt mặc định rất tốt. Và bạn chỉ phải định cấu hình trình ghi nhật ký nếu bạn muốn thay đổi điều gì đó trong chúng. Ngoài ra, tệp cài đặt được điều chỉnh tốt hơn cho phần mềm của công ty - tất cả các cấu hình của nó được đặt thành xml/.

Theo mặc định, Logbacknó không yêu cầu bất kỳ cài đặt nào và ghi lại tất cả nhật ký từ cấp độ DEBUGtrở lên. Nếu bạn cần hành vi khác, nó có thể được cấu hình thông qua xmlcấu hình:

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern>
        </encoder>
    </appender>
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.type.descriptor.sql" level="TRACE" />
    <root level="info">
        <appender-ref ref="FILE" />
    </root>
</configuration>

2.5 Trình ghi nhật ký phổ quát mới nhất - SLF4J: Mặt tiền ghi nhật ký đơn giản cho Java

Bao lâu mới có thể tìm được ý nghĩa vàng...

Vào năm 2006, một trong những người sáng tạo log4jđã rời dự án và quyết định thử lại để tạo một bộ ghi phổ quát. Nhưng lần này nó không phải là một bộ ghi mới, mà là một tiêu chuẩn phổ quát mới (trình bao bọc) cho phép các bộ ghi khác nhau tương tác với nhau.

Trình ghi nhật ký này được gọi là slf4j — Simple Logging Facade for Java, nó là một trình bao bọc xung quanh log4j, JUL, common-loggins and logback. Trình ghi nhật ký này đã giải quyết một vấn đề thực sự - quản lý một vườn thú ghi nhật ký, vì vậy mọi người ngay lập tức bắt đầu sử dụng nó.

Chúng tôi anh dũng giải quyết các vấn đề mà chúng tôi tạo ra cho chính mình. Như bạn có thể thấy, tiến độ đã đạt đến mức chúng tôi đã tạo một trình bao bọc bên ngoài trình bao bọc ...

Bản thân gói bao gồm hai phần:

  • API, được sử dụng trong các ứng dụng;
  • Việc triển khai được thêm dưới dạng phụ thuộc riêng cho từng bộ ghi.

Bạn có thể kết nối bộ ghi với dự án bằng mã:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.2</version>
</dependency>

Chỉ cần kết nối việc triển khai chính xác là đủ và thế là xong: toàn bộ dự án sẽ hoạt động với nó.

2.6 Tối ưu hóa trong slf4j

Slf4jhỗ trợ tất cả các tính năng mới như định dạng chuỗi để ghi nhật ký . Trước đây đã có một vấn đề như vậy. Giả sử bạn muốn in một thông báo vào nhật ký:

log.debug("User " + user + " connected from " + request.getRemoteAddr());

Có một vấn đề với mã này. Giả sử ứng dụng của bạn vẫn hoạt động productionvà không ghi bất kỳ thứ gì vào nhật ký DEBUG-messages, tuy nhiên, phương thức này log.debug()vẫn sẽ được gọi và khi nó được gọi, các phương thức sau cũng sẽ được gọi:

  • user.toString();
  • request.getRemoteAddr();

Gọi các phương thức này làm chậm ứng dụng. Cuộc gọi của họ chỉ cần thiết trong quá trình gỡ lỗi, nhưng dù sao thì họ cũng được gọi.

Từ quan điểm logic, vấn đề này phải được giải quyết trong chính thư viện ghi nhật ký. Và trong phiên bản đầu tiên của log4j, giải pháp đã xuất hiện:

if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}

Thay vì một dòng nhật ký, bây giờ cần phải viết ba dòng. Điều này làm xấu đi đáng kể khả năng đọc mã và làm giảm mức độ phổ biến của log4j.

Trình ghi nhật ký slf4jđã có thể cải thiện một chút tình hình bằng cách cung cấp tính năng ghi nhật ký thông minh. Nó trông như thế này:

log.debug("User {} connected from {}", user, request.getRemoteAddr());

nơi {}biểu thị việc chèn các đối số được truyền trong phương thức. Tức là, cái đầu tiên {}tương ứng với người dùng, cái thứ hai {}tương ứng với request.getRemoteAddr().

Các tham số này sẽ chỉ được nối vào một thông báo nếu cấp độ ghi nhật ký cho phép ghi nhật ký. Không hoàn hảo, nhưng tốt hơn tất cả các tùy chọn khác.

Sau đó, SLF4Jnó bắt đầu trở nên phổ biến nhanh chóng, tại thời điểm này đây là giải pháp tốt nhất.

Do đó, chúng tôi sẽ xem xét ghi nhật ký bằng cách sử dụng ví dụ về gói slf4j-log4j12.