Tin tức và phân tích của tất cả các thiết bị di động

Hướng dẫn dành cho nhà phát triển Java

Một trong những phần quan trọng nhất của quá trình phát triển phần mềm là ghi nhật ký thích hợp. Vì có sẵn nhiều khung công tác ghi nhật ký Java khác nhau nên điều quan trọng là phải chọn một khung công tác dễ sử dụng. Đồng thời, nền tảng bạn chọn phải có hiệu suất cao, có thể mở rộng và tùy chỉnh. Log4j2 là thư viện ghi nhật ký Java miễn phí đáp ứng mọi nhu cầu của bạn.

Việc tích hợp Log4j2 vào bất kỳ ứng dụng nào sẽ mở ra các tùy chọn như lọc nâng cao, hỗ trợ Java lambda 8, tìm kiếm thuộc tính và cấp độ nhật ký tùy chỉnh. Hãy xem cách bạn có thể thêm Log4j2 vào dự án của mình và những tính năng nào có thể giúp bạn luôn dẫn đầu trò chơi của mình.

Log4j2 là gì?

Ghi nhật ký là một phương pháp ghi lại thông tin hữu ích, được gọi là nhật ký, mà bạn có thể tham khảo và phân tích sau này. Bạn có thể sử dụng nhật ký để nhanh chóng gỡ lỗi mã ứng dụng của mình. Nhật ký ứng dụng giúp bạn hiểu luồng mã và khắc phục sự cố và lỗi sản xuất.

Ngoài các trường hợp sử dụng chẩn đoán, nhật ký còn được sử dụng cho mục đích kiểm tra – ví dụ: để theo dõi xem tin nhắn thông báo có được gửi thành công cho người dùng hay không.

Log4j2 là một trong những thư viện ghi nhật ký phổ biến nhất trong Java. Nó là sự kế thừa của thư viện Log4j có ảnh hưởng lớn. Được phát triển bởi Quỹ phần mềm Apache và một phần của Dịch vụ ghi nhật ký Apache, Log4j2 là phần mềm mã nguồn mở và miễn phí (FOSS) được phân phối theo phiên bản Apache 2.0.

Log4j2 được xây dựng trên nền tảng vững chắc của Log4j gốc. Việc sử dụng Logger có nhiều ưu điểm hơn so với các câu lệnh in đơn giản trong System.out.println(). Điều này bao gồm việc kiểm soát thông báo nào xuất hiện đồng thời tránh các thông báo tường trình khác. Việc có nhật ký thích hợp là rất quan trọng trong môi trường sản xuất nơi không có trình gỡ lỗi.

Làm cách nào để thêm Log4j2 vào dự án của bạn?

Có một số cách để thêm Log4j2 vào dự án Java. Nên sử dụng Java 8 trở lên để sử dụng tất cả các tính năng của Log4j2.

Hãy thảo luận về các phương pháp khác nhau để thêm Log4j2 tùy thuộc vào yêu cầu của bạn.

Thêm Log4j2 vào các dự án bằng Apache Maven

Nếu dự án của bạn sử dụng Apache Maven làm hệ thống xây dựng, thì các phần phụ thuộc Log4j2 cần được thêm vào tệp pom.xml.

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

Để giúp duy trì cùng một phiên bản trên các tạo phẩm khác nhau dễ dàng hơn, Log4j2 có tệp Hóa đơn Vật liệu (BOM) pom.xml. Nếu thêm nó như một phần của quản lý phần phụ thuộc thì bạn không cần thêm từng phiên bản.

<!-- Add the BOM to the dependencyManagement -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-bom</artifactId>
      <version>2.20.0</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>
  </dependencies>
</dependencyManagement>

<!-- Once the BOM is added, the versions are not required -->
<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
  </dependency>
</dependencies>

Thêm Log4j2 vào các dự án bằng Apache Gradle

Nếu đang sử dụng Apache Gradle làm công cụ xây dựng, bạn có thể thêm các phần phụ thuộc Log4j2 vào tệp build.gradle của mình.

dependencies {
  implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
  implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
}

Nếu bạn đang sử dụng phiên bản Gradle 5.0 trở lên, bạn có tùy chọn nhập Hóa đơn vật liệu (BOM) Log4j2 Maven để duy trì các phiên bản phụ thuộc nhất quán. Điều này có thể đạt được bằng cách thêm phần sau vào tệp build.gradle của bạn.

dependencies {
  implementation platform('org.apache.logging.log4j:log4j-bom:2.20.0')

  implementation 'org.apache.logging.log4j:log4j-api'
  runtimeOnly 'org.apache.logging.log4j:log4j-core'
}

Trong Gradle trong các phiên bản 2.8-4.10 không có tùy chọn nhập trực tiếp BOM Maven. Bạn cần thêm plugin bổ sung cho tính năng quản lý phụ thuộc.

plugins {
  id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

dependencyManagement {
  imports {
    mavenBom 'org.apache.logging.log4j:log4j-bom:2.20.0'
  }
}

dependencies {
  implementation 'org.apache.logging.log4j:log4j-api'
  runtimeOnly 'org.apache.logging.log4j:log4j-core'
}

Thêm Log4j2 vào các ứng dụng độc lập mà không cần công cụ xây dựng

Nếu dự án của bạn không có công cụ xây dựng, bạn có thể tải xuống phiên bản bắt buộc của tạo phẩm Log4j2 từ trang tải xuống Log4j2 chính thức.

Sau khi tải chúng xuống, bạn cần đảm bảo rằng đường dẫn lớp của ứng dụng chứa các lọ sau.

  • log4j-api-20,20.0.cái lọ
  • log4j-lõi-20,20.0.cái lọ

Các thành phần trong Log4j2 là gì?

Để hiểu các tính năng của Log4j2 và tận dụng tối đa các khả năng của nó, điều quan trọng là phải hiểu cách thức hoạt động của Log4j2. Bên dưới bề mặt, một số khối xây dựng tạo nên Log4j2. Hãy nói về họ từng cái một.

# 1. LoggerContext

LoggerContext là đơn vị trung tâm của hệ thống ghi nhật ký. Chứa tất cả các logger được yêu cầu trong ứng dụng. Nó cũng chứa một tham chiếu đến cấu hình.

#2. Cấu hình

Cấu hình chứa tất cả thông tin được yêu cầu bởi hệ thống đăng nhập. Điều này bao gồm trình ghi nhật ký, trình bổ sung, bộ lọc, v.v. Trong Log4j2, bạn có thể xác định cấu hình bằng nhiều định dạng tệp khác nhau như XML, JSON và YAML, cũng như theo lập trình thông qua API Log4j2.

Tự động tải lại xảy ra bất cứ khi nào bất kỳ thuộc tính nào trong cấu hình thay đổi. Do đó, không có yêu cầu phải khởi động lại ứng dụng.

#3. Máy ghi âm

Thành phần chính của hệ thống Log4j2 là Logger. Trình ghi nhật ký được lấy trong mã ứng dụng bằng cách sử dụng câu lệnh LogManager.getLogger() và được dùng để tạo nhật ký. Thông báo tường trình có thể được tạo ở các mức độ nghiêm trọng khác nhau, chẳng hạn như gỡ lỗi, thông tin, cảnh báo, lỗi và nghiêm trọng.

#4. LoggerConfig

LoggerConfig chịu trách nhiệm về hành vi của một Logger cụ thể. Xác định hành vi và cài đặt cho các sự kiện ghi nhật ký được tạo bởi trình ghi nhật ký cụ thể này. Nó cho phép bạn định cấu hình các cấp độ ghi nhật ký khác nhau, định cấu hình phần bổ sung và áp dụng các bộ lọc.

#5. Lọc

Bạn có thể xử lý có chọn lọc các sự kiện nhật ký trong Log4j2 bằng các bộ lọc. Bộ lọc được áp dụng dựa trên các tiêu chí cụ thể. Những bộ lọc này có thể được áp dụng cho máy ghi hoặc phần bổ sung. Bộ lọc kiểm soát những sự kiện nhật ký nào có thể đi qua quy trình ghi nhật ký để xử lý thêm. Bằng cách sử dụng các bộ lọc, hành vi ghi nhật ký có thể được tinh chỉnh để đảm bảo rằng chỉ những nhật ký có liên quan mới được xử lý.

#6. Phép cộng

Đích của mỗi thông điệp tường trình được xác định bởi người nối thêm. Một nhà đăng ký có thể có nhiều Người đăng ký. Sự kiện nhật ký sẽ được gửi đến tất cả Người đăng ký cho trình ghi nhật ký đã cho. Log4j2 có nhiều ứng dụng được cấu hình sẵn. Ví dụ: ConsoleAppender được sử dụng để ghi thông báo vào bảng điều khiển và FileAppender được sử dụng để gửi thông báo đến một tệp. Mỗi ứng dụng cần có bố cục riêng để xác định thông điệp tường trình cuối cùng sẽ trông như thế nào.

#7. Hệ thống

Trong Bố cục Log4j2 được sử dụng để xác định thông điệp tường trình cuối cùng sẽ trông như thế nào. Bố cục có liên quan đến Appender. Trong khi Appender chỉ định đích đầu ra thì Layout mô tả cách in thông báo.

5 Tính năng chính của Log4j2

Log4j2 có nhiều tính năng phong phú và đây chính là điểm khiến nó khác biệt so với các nền tảng ghi nhật ký Java khác hiện có. Từ việc có trình ghi nhật ký không đồng bộ đến hỗ trợ Java lambda 8.Log4j2 có lợi thế hơn những người khác. Hãy cùng thảo luận về một số tính năng đáng chú ý của framework này.

# 1. Mở rộng chức năng với plugin

Trong Log4j 1Việc phát triển các tiện ích mở rộng .x yêu cầu rất nhiều sửa đổi mã. Log4j2 giải quyết vấn đề về khả năng mở rộng bằng cách giới thiệu hệ thống plugin.

Bạn có thể khai báo một plugin mới bằng cách sử dụng chú thích @Plugin trong lớp của mình. Sử dụng sức mạnh của plugin, bạn có thể tạo các thành phần của riêng mình như bộ lọc và tiện ích bổ sung. Bạn cũng có thể dễ dàng thêm các thành phần của bên thứ ba vào thư viện.

#2. Hỗ trợ Java 8 Lambda

Với việc phát hành phiên bản Log4j2 2.4 hỗ trợ cho các biểu thức lambda Java đã được giới thiệu 8. Bạn có thể sử dụng biểu thức lambda để xác định trực tiếp logic ghi nhật ký. Điều này làm giảm nhu cầu kiểm tra nhiều hàng hoặc các lớp bên trong ẩn danh. Điều này cũng đảm bảo rằng các phương pháp đắt tiền không được thực hiện một cách không cần thiết. Bằng cách này, mã không chỉ sạch hơn và dễ đọc hơn mà còn giảm tải cho hệ thống.

Hãy xem xét một ví dụ trong đó bạn ghi lại kết quả của một thao tác tốn kém nhưng chỉ khi mức gỡ lỗi được bật. Trước khi hỗ trợ lambda, việc này sẽ được thực hiện bằng mã bên dưới:

if (logger.isDebugEnabled()) {
    logger.debug("The output of the given operation is: {}", expensiveOperation());
}

Việc có nhiều trường hợp sử dụng như vậy sẽ dẫn đến việc kiểm tra có điều kiện một cách không cần thiết. Tuy nhiên, đối với Log42, hành động tương tự có thể được thực hiện như sau:

logger.debug("The output of the given operation is: {}", () -> expensiveOperation()

Phương thức exprensiveOperation() chỉ được đánh giá khi mức gỡ lỗi được bật. Không cần bất kỳ kiểm tra rõ ràng.

#3. Trình ghi nhật ký không đồng bộ

Mỗi sự kiện nhật ký là một thao tác I/O, làm tăng tải cho hệ thống. Để khắc phục điều này, Log4j2 giới thiệu các trình ghi nhật ký không đồng bộ chạy trong một luồng riêng biệt với luồng ứng dụng. Khi sử dụng trình ghi nhật ký không đồng bộ, luồng gọi ngay lập tức lấy lại quyền kiểm soát khi logger.log() được gọi.

Điều này cho phép nó tiếp tục logic ứng dụng thay vì đợi sự kiện ghi nhật ký hoàn tất. Việc tận dụng hành vi không đồng bộ này sẽ mang lại thông lượng ghi nhật ký cao hơn. Bạn có thể chọn đặt tất cả các trình ghi nhật ký thành không đồng bộ theo mặc định hoặc kết hợp hành vi đồng bộ và không đồng bộ.

#4. Đăng nhập không rác

Trong Java, thu gom rác là quá trình các đối tượng không sử dụng trong ứng dụng sẽ tự động được dọn sạch. Mặc dù bạn không phải xử lý thao tác này một cách thủ công nhưng việc thu gom rác có chi phí riêng.

Nếu một ứng dụng tạo quá nhiều đối tượng trong một thời gian ngắn, quá trình thu gom rác có thể tiêu tốn nhiều tài nguyên hệ thống hơn mức cần thiết. Một số thư viện ghi nhật ký, bao gồm các phiên bản trước của Log4j, tạo nhiều đối tượng tạm thời trong quá trình ghi nhật ký. Sau đó, áp lực tăng lên trên bộ thu gom rác sẽ ảnh hưởng đến hiệu suất hệ thống.

Từ phiên bản 2.6 Log4j2 chạy ở chế độ “không có rác”. Đây là hành vi mặc định. Do đó, các vật phẩm được tái sử dụng và việc tạo ra những vật phẩm tạm thời được giảm thiểu đáng kể.

Những hình ảnh dưới đây cho thấy phiên bản 2.6 Phần mềm Log4j2 giảm thiểu vấn đề thừa đối tượng so với phiên bản 2.5 Chương trình Log4j2.

Trong phiên bản Log4j2 2.5 nhiều đối tượng tạm thời được tạo trong quá trình đăng nhập; nguồn: apache.org

Trong Log4j2.6 không có đối tượng tạm thời nào được tạo trong quá trình đăng nhập; nguồn: apache.org

#5. Tìm kiếm

Trong log4j2, bạn có thể thêm thông tin theo ngữ cảnh vào nhật ký của mình bằng siêu liên kết. Bằng cách sử dụng chúng, bạn có thể thêm dữ liệu từ nhiều nguồn khác nhau, chẳng hạn như thuộc tính hệ thống, biến môi trường hoặc giá trị do người dùng xác định. Bằng cách này, bạn có thể bao gồm thông tin liên quan được tìm nạp động, làm cho nhật ký trở nên hữu ích hơn.

Hãy xem xét một ví dụ trong đó bạn muốn ghi lại ID phiên của người dùng với tất cả các dòng nhật ký. Điều này sẽ cho phép bạn tìm kiếm tất cả nhật ký khớp với id phiên.

Một cách mạnh mẽ để làm điều này là thêm rõ ràng id phiên riêng lẻ, điều này trở nên khó duy trì. Bạn có thể sớm quên thêm nó, do đó làm mất thông tin có giá trị.

logger.info("The user data has been fetched for session id {}", sessionId);
...
logger.info("The transaction has been processed for session id {}", sessionId);
...
logger.info("Request has been successfully processed for session id {}", sessionId);

Cách tốt hơn để làm điều này là sử dụng tìm kiếm bản đồ ngữ cảnh. Bạn có thể thêm ID phiên vào ngữ cảnh luồng trong mã ứng dụng của mình. Giá trị sau đó có thể được sử dụng trong cấu hình Log4j2. Điều này giúp loại bỏ sự cần thiết phải đề cập rõ ràng đến nó trong thông điệp tường trình.

ThreadContext.put("sessionId", sessionId);

Sau khi thêm một giá trị, bạn có thể sử dụng giá trị đó trong tìm kiếm bằng từ khóa ctx.

<File name="Application" fileName="application.log">
  <PatternLayout>
    <pattern>%d %p %c{1.} [%t] $${ctx:sessionId} %m%n</pattern>
  </PatternLayout>
</File>

Làm cách nào để tạo cấp độ nhật ký tùy chỉnh trong Log4j2?

Các cấp độ ghi nhật ký trong Log4j2 được sử dụng để phân loại các sự kiện nhật ký dựa trên mức độ nghiêm trọng hoặc tầm quan trọng của chúng. Bạn có thể kiểm soát mức độ ghi nhật ký khi ghi thông báo vào mã ứng dụng của mình.

Ví dụ: logger.debug() thêm cấp độ DEBUG. Theo đó, logger.error() thêm mức ERROR. Điều này xác định thông báo nào cuối cùng sẽ xuất hiện ở đầu ra. Mức ghi nhật ký có thể được cấu hình trong tệp cấu hình.

Các cấp độ nhật ký được cấu hình sẵn trong Log4j2 và các giá trị tương ứng của chúng được liệt kê bên dưới.

OFF0FATAL100ERROR200WARN300INFO400DEBUG500TACE600ALLMAX GIÁ TRỊ

Nếu Cấp nhật ký được đặt ở một mức nhất định, tất cả các dòng nhật ký cho giá trị tương ứng đó và những dòng ở trên (với giá trị nhỏ hơn) sẽ được xuất ra. Những người khác bị bỏ qua.

Ví dụ: nếu bạn đặt mức ghi nhật ký thành CẢNH BÁO, các thông báo CẢNH BÁO, LỖI và LỚN sẽ được hiển thị. Bất kỳ dòng nhật ký nào có cấp độ khác sẽ bị bỏ qua. Điều này đặc biệt hữu ích khi bạn chạy cùng một mã trong các môi trường khác nhau.

Bạn có thể muốn đặt cấp độ nhật ký thành INFO hoặc DEBUG khi chạy mã trong môi trường phát triển của mình. Điều này sẽ cho phép bạn xem nhiều nhật ký hơn và trợ giúp trong quá trình phát triển. Tuy nhiên, khi chạy trong sản xuất, bạn muốn đặt nó thành LỖI. Bằng cách này, bạn sẽ có thể tập trung vào việc tìm ra vấn đề nếu có bất kỳ điều bất thường nào xảy ra và bạn sẽ không phải trải qua các dòng nhật ký không cần thiết.

Có thể đôi khi bạn muốn thêm cấp độ nhật ký tùy chỉnh của riêng mình ngoài các cấp độ được định cấu hình trước. Log4j2 cho phép bạn thực hiện việc này một cách dễ dàng. Hãy xem cách bạn có thể thêm cấp độ nhật ký của riêng mình và sử dụng chúng trong ứng dụng của mình.

# 1. Thêm cấp độ nhật ký tùy chỉnh bằng tệp cấu hình

Bạn có thể thêm các cấp độ ghi nhật ký tùy chỉnh bằng cách khai báo chúng trong tệp cấu hình.

Ví dụ bên dưới xác định cấp độ nhật ký tùy chỉnh được gọi là THÔNG BÁO với giá trị 450. Điều này sẽ đặt nó giữa INFO (với giá trị 400) và DEBUG (với giá trị 500). Điều này có nghĩa là nếu mức được đặt thành THÔNG BÁO, thông báo INFO sẽ được ghi lại nhưng thông báo DEBUG sẽ bị bỏ qua.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <CustomLevels>
    <CustomLevel name="NOTICE" intLevel="450" />
  </CustomLevels>
 
  <Appenders>
    <File name="MyFile" fileName="logs/app.log">
      <PatternLayout pattern="%d %-7level %logger{36} - %msg%n"/>
    </File>
  </Appenders>
  <Loggers>
    <Root level="trace">
      <AppenderRef ref="MyFile" level="NOTICE" />
    </Root>
  </Loggers>
</Configuration>

#2. Thêm cấp độ nhật ký tùy chỉnh trong mã

Ngoài việc khai báo chúng trong tệp cấu hình, bạn có thể xác định cấp độ nhật ký tùy chỉnh của riêng mình trong mã của mình.

final Level VERBOSE = Level.forName("VERBOSE", 550);

Điều này sẽ tạo ra một cấp độ nhật ký mới gọi là ĐỘNG TỪ. Cấp độ nhật ký này sẽ nằm trong khoảng DEBUG (với giá trị 500) và TRACE (với giá trị 600). Nếu trình ghi nhật ký được đặt ở mức ĐỘNG TỪ, tất cả các thông báo nhật ký ĐỘNG TỪ và cao hơn sẽ được ghi lại, bao gồm cả GỠ LỖI. Tuy nhiên, tin nhắn TRACE sẽ bị bỏ qua.

#3. Sử dụng cấp độ nhật ký tùy chỉnh trong mã của bạn

Mức ghi nhật ký tùy chỉnh trước tiên phải được khai báo trước khi có thể sử dụng. Bạn có thể khai báo chúng trong tệp cấu hình hoặc trong mã của mình. Sau khi khai báo, bạn có thể sử dụng chúng một cách tự do.

Ví dụ về mã này cho thấy cách bạn có thể khai báo một mức tùy chỉnh có tên là LƯU Ý và sau đó sử dụng mức đó.

final Level NOTICE = Level.forName("NOTICE", 550);

final Logger logger = LogManager.getLogger();
logger.log(NOTICE, "a notice level message");

Mặc dù điều này sẽ tạo ra thông báo cần thiết với cấp độ mới được tạo, nhưng việc vượt qua cấp độ đó một cách rõ ràng luôn có thể gây rắc rối. May mắn thay, bạn có thể tạo mã nguồn để nhận các phương thức trợ giúp ghi nhật ký các cấp độ tùy chỉnh. Bằng cách tương tự, bạn sẽ có thể sử dụng phương thức logger.notice() của riêng mình tương tự như logger.debug() hoặc logger.error().

Log4j2 đi kèm với một công cụ giúp bạn tạo trình ghi nhật ký mở rộng của riêng mình. Lệnh sau tạo một tệp Java có tên CustomLogger.java. Tệp này chứa các phương thức nhật ký hiện có cùng với các phương thức mới được tạo cho cấp độ THÔNG BÁO.

java -cp log4j-core-2.20.0.jar org.apache.logging.log4j.core.tools.ExtendedLoggerGenerator \
        com.example.CustomLogger NOTICE=450 > com/example/CustomLogger.java

Sau khi tệp được tạo, bạn có thể sử dụng lớp trong mã của mình để tạo trình ghi nhật ký mới. Những trình ghi nhật ký này sẽ chứa các phương thức bổ sung cho cấp độ nhật ký tùy chỉnh. Bằng cách này, bạn có thể mở rộng chức năng của trình ghi nhật ký của mình.

final Logger logger = CustomLogger.create(ValueFirstSmsSender.class);

//this new method is similar to using logger.debug()
logger.notice("a notice level message");

Ứng dụng

Log4j2 là một khung ghi nhật ký Java rất mạnh mẽ, cung cấp nhiều tính năng, cấu hình, cải tiến hiệu suất và hơn thế nữa. Vì nhật ký là một phần rất quan trọng trong quá trình phát triển phần mềm nên việc có một khung mạnh mẽ như Log4j2 sẽ giúp ứng dụng của bạn có nhiều khả năng hơn.

Tính linh hoạt và khả năng mở rộng của Log4j2 cho phép bạn nắm bắt chính xác các sự kiện diễn ra trong ứng dụng của mình. Sau đó, nó cho phép bạn coi nhật ký như một công cụ kiểm tra và gỡ lỗi mạnh mẽ. Với tất cả các tính năng và cải tiến, Log4j2 nổi bật và là lựa chọn ưu tiên trong nhiều dự án phần mềm.

Bạn cũng có thể quan tâm đến các IDE Java và trình biên dịch trực tuyến này.