Khác phục lỗi khi cài java lỗi file logx năm 2024

Log là một quá trình ghi lại những thông tin được thông báo, lưu lại trong quá trình hoạt động của một ứng dụng ở một nơi tập trung. Mục đích chính là để có thể xem lại các thông tin hoạt động của ứng dụng trong quá khứ như debug khi có lỗi xảy ra, check health, xem info, error, warning,…

Có nhiều cách để ghi log: có thể lưu vào file, console (sử dụng lệnh sysout), database hoặc đâu đó để có thể xem lại được.

Trong các ứng dụng thực tế, lưu ra console ít được lựa chọn bởi có một số hạn chế sau:

  • Chỉ hiển thị kết quả ra console. Vì vậy, mỗi khi console được đóng thì tất cả thông tin log được show trên console cũng mất.
  • Nội dụng log được hiển thị trên console rất khó đọc.

Log như thế nào?

Việc đầu tiên trước khi output dòng log ra hãy tưởng tượng sau đó có thể sử dụng được không, hay chỉ là thông tin vô nghĩa.

Ví dụ: khi bạn xử lý một HTTP request từ phía client, request này khi được xử lý thì gây ra lỗi 500 – “Internal server error”. Khi đó thông tin log ở đây ít nhất phải có:

  • Thời gian request.
  • Người request.
  • HTTP request info: header, request, body,…
  • HTTP response info.
  • Error stack trace về error đó như lỗi ở đoạn nào, dòng nào, lỗi gì, input như thế nào,…

Khi xem lại đoạn log, chúng ta biết được cách tái hiện lại lỗi hay phán đoán lỗi xảy ra như thế nào để khác phục nhanh hơn và chính xác hơn.

Phân loại log (Log level)

Log nên được phân loại tùy theo mục đích sử dụng, theo level:

  • All: đây là cấp độ thấp nhất, Logger và Appender được định nghĩa với cấp độ này, mọi thông tin cần log sẽ được log.
  • Debug: các thông tin dùng để debug, chúng ta có thể bật/ tắt log này dựa vào mode của application.
  • Info: các thông tin mà bạn muốn ghi nhận thêm trong quá trình hoạt động của hệ thống. Ví dụ: log số lượng request, status, duration, … để biết traffic của hệ thống thế nào.
  • Warning: log các thông tin cảnh báo của chương trình.
  • Error: các lỗi khi chạy chương trình sẽ được log. Cố gắng log toàn bộ thông tin liên quan nhiều nhất có thể để có thể reproduce lại được mà ít tốn thời gian nhất.
  • Fatal: log các lỗi nghiêm trọng xảy ra trong chương trình, có thể làm cho chương trình không sử dụng được nữa.
  • Off: đây là cấp độ cao nhất, được sử dụng khi chúng ta không muốn log bất kỳ thông tin nào nữa.

Độ ưu tiên của các cấp độ log từ thấp đến cao như sau:

ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF.

Format log

Một điều quan trọng là log đó phải sử dụng được, nghĩa là dễ đọc, dễ trace ra được thông tin cần tìm. Để làm được điều này, các log của chúng ta phải tuân thủ theo một format được chỉ định.

Có nhiều ứng dụng phục vụ cho việc thu thập và phân tích dữ liệu từ file log để có thể thống kê, search,… Một trong những ứng dụng trong Java thường dùng là Logstash. Vì vậy file log nên tuân thủ theo format của các ứng dụng này.

Log rotate

Log rotate là việc cắt nhỏ log ra và lưu trữ trên nhiều file thay vì một file.

Một số chiến lược:

  • Có thể sẽ lưu file log riêng theo từng ngày, tuần hoặc tháng. Ví dụ: gpcoder-app-20190414.log, gpcoder-app-20190415.log, gpcoder-app-20190416.log,…
  • File log sẽ chia theo loại log: gpcoder-app-20190414.error.log, gpcoder-app-20190414.info.log
  • File log sẽ cắt theo chiến lược khác như dung lượng file. Ví dụ: mỗi file tối đa 100 MB.
  • Hoặc một số chiến lược khác tùy theo yêu cầu của ứng dụng.

Apache Log4j là gì?

Apache Log4j hay ngắn gọn là Log4j là một thư viện được cung cấp bởi Apache hỗ trợ ghi log được viết bằng ngôn ngữ Java.

Cách thành phần chính của Log4j:

  • Logger: chịu trách nhiệm thu thập thông tin log.
  • Appender: chịu trách nhiệm ghi log tới các vị trí đã được cấu hình (file, console). Các loại Appender: SyslogAppendersends, SMTPAppender, JDBCAppender, FileAppender, SocketHubAppender, SocketAppender, TelnetAppender, ConsoleAppender, JMSAppender, …
  • Layout: chịu trách nhiệm định dạng (format) kết quả log. Các loại Layout: PatternLayout, SimpleLayout, XMLLayout, HTMLLayout.

Khác phục lỗi khi cài java lỗi file logx năm 2024

Các tính năng của Log4j:

  • Thread safe.
  • Tối ưu cho tốc độ.
  • Hỗ trợ nhiều output (file + console).
  • Hỗ trợ nhiều level log: ALL, TRACE, INFO, WARNING, ERROR, FATAL.

Để sử dụng Log4j, chúng ta cần thực hiện theo các bước:

  • Khai báo thư viện cần thiết cho Log4j.
  • Cấu hình Log4j.
  • Đặt câu lệnh log trong ứng dụng.

Cài đặt Log4j

Trong bài này, chúng ta sẽ sử dụng Log4j 2, đây là một version mới của Log4j.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.gpcoder</groupId> <artifactId>JavaLogging</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>JavaLogging</name> <url>http://maven.apache.org</url> <properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.11.2</version>
</dependency>
</dependencies> </project>

Cấu hình Log4j

Log4j 2 có thể được cấu hình bằng nhiều cách.

  • Sử dụng file cấu hình: XML, JSON, YAML, hoặc properties.
  • Tạo ConfigurationFactory và implement Configuration.
  • ….

Để cấu hình Log4j 2, chúng ta sẽ tạo một file log4j2.properties trong thư mục src/main/resources của project. Nội dung file như sau:

status = error dest = err name = PropertiesConfig property.foldername = logs property.filename = ${foldername}/app.log filter.threshold.type = ThresholdFilter filter.threshold.level = debug

Direct log messages to stdout

appender.console.type = Console appender.console.name = STDOUT appender.console.layout.type = PatternLayout appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n appender.console.filter.threshold.type = ThresholdFilter appender.console.filter.threshold.level = debug

Direct log messages to a log file

appender.rolling.type = RollingFile appender.rolling.name = ROLLING_FILE appender.rolling.fileName = ${filename} appender.rolling.filePattern = ${foldername}/app-backup-%d{yyyy-MM-dd-HH-mm}-%i.log.gz appender.rolling.layout.type = PatternLayout appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n appender.rolling.policies.type = Policies appender.rolling.policies.time.type = TimeBasedTriggeringPolicy appender.rolling.policies.time.interval = 2 appender.rolling.policies.time.modulate = true appender.rolling.policies.size.type = SizeBasedTriggeringPolicy appender.rolling.policies.size.size = 100MB appender.rolling.strategy.type = DefaultRolloverStrategy appender.rolling.strategy.max = 20 logger.rolling.name = com.gpcoder logger.rolling.level = debug logger.rolling.additivity = true logger.rolling.appenderRef.rolling.ref = ROLLING_FILE rootLogger.level = debug rootLogger.appenderRef.stdout.ref = STDOUT

File log4j2.properties này bao gồm 2 cấu hình: xuất nội dung log ra console và ra file. Tương tự, nếu bạn muốn sử dụng các định dạng khác, có thể tạo file log4j2.xml, log4j2.yml, log4j2.json.

Chi tiết, các bạn tham khảo thêm trên document của Log4j.

Sử dụng Log4j trong ứng dụng

AppController.java

package com.gpcoder; import java.text.MessageFormat; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class AppController { private static final Logger LOGGER = LogManager.getLogger(AppController.class); public static void main(String[] args) {

LOGGER.debug("Debug log message");
divide(4, 2);
divide(4, 0);
LOGGER.fatal("Fatal log message");
} public static void divide(int number1, int number2) {
try {
  int number = number1 / number2;
  LOGGER.info("Info: {} / {} = {}", number1, number2, number);
} catch (ArithmeticException e) {
  String message = MessageFormat.format("Error: Cannot divide two number {0}/{1}", number1, number2);
  LOGGER.error(message, e);
}
} }

Chạy chương trình trên, chúng ta sẽ thấy nội dung của console như sau:

2019-04-14 13:39:42 DEBUG AppController:13 - Debug log message 2019-04-14 13:39:42 INFO AppController:22 - Info: 4 / 2 = 2 2019-04-14 13:39:42 ERROR AppController:25 - Error: Cannot divide two number 4/0 java.lang.ArithmeticException: / by zero at com.gpcoder.AppController.divide(AppController.java:21) [classes/:?] at com.gpcoder.AppController.main(AppController.java:15) [classes/:?] 2019-04-14 13:39:42 FATAL AppController:16 - Fatal log message

Như bạn thấy, nội dung log rất chi tiết, bao gồm: thời gian thực hiện, log level, tên class được thực thi, dòng code được thực thi, nội dung message, chi tiết exception.

Refesh lại project chúng ta sẽ thấy file log được tạo ra trong project.

Khác phục lỗi khi cài java lỗi file logx năm 2024

Nếu trong project của bạn đã sử dụng thư viện Lombok, thì hãy sử dụng tính năng @Log4j2 được hỗ trợ bởi Lombok. Chúng ta có thể gọi trực tiếp log.error() mà không cần phải khai báo biến LOGGER như trên.

package com.gpcoder; import lombok.extern.log4j.Log4j2; @Log4j2 public class LoggerWithLombok { public static void main(String[] args) {

log.error("Something else is wrong here");
} }

Ngoài Log4j, chúng ta có thể sử dụng một số thư viện khác để ghi log như Logback, SLF4J. Cách sử dụng cũng tương tự như Log4j, nếu có thời gian các bạn hãy tìm hiểu thêm để áp dụng trong dự án.