CHÀO! Khi viết các bài học, tôi đặc biệt nhấn mạnh nếu có một chủ đề cụ thể sẽ thực sự cần thiết trong công việc thực tế. Vì vậy, HÃY NGHE LÊN! Chủ đề chúng ta đề cập hôm nay chắc chắn sẽ hữu ích trong tất cả các dự án của bạn ngay từ ngày đầu đi làm. Chúng ta sẽ nói về Nhật ký Java. Chủ đề này không hề phức tạp (thậm chí tôi có thể nói là dễ dàng). Nhưng bạn sẽ có đủ điều rõ ràng để căng thẳng trong công việc đầu tiên của mình, vì vậy tốt hơn hết là bạn nên hiểu kỹ về nó ngay bây giờ :) Chà, hãy bắt đầu nào.

Đăng nhập trong Java là gì?

Ghi nhật ký là hành động ghi lại dữ liệu về hoạt động của một chương trình. Nơi chúng tôi ghi lại dữ liệu này được gọi là "nhật ký". Hai câu hỏi ngay lập tức nảy sinh: dữ liệu nào được ghi và ở đâu? Hãy bắt đầu với "ở đâu". Bạn có thể ghi dữ liệu về công việc của chương trình ở nhiều nơi khác nhau. Ví dụ, trong quá trình học, bạn thường System.out.println()để xuất dữ liệu ra bàn điều khiển. Đây thực sự là ghi nhật ký, mặc dù ở dạng đơn giản nhất. Tất nhiên, điều này không thuận tiện lắm cho người dùng hoặc nhóm hỗ trợ sản phẩm: rõ ràng là họ sẽ không muốn cài đặt IDE và theo dõi bảng điều khiển :) Có một định dạng thông thường hơn để ghi thông tin: tệp văn bản. Con người cảm thấy thoải mái hơn nhiều khi đọc dữ liệu ở định dạng này và chắc chắn việc lưu trữ dữ liệu sẽ thuận tiện hơn nhiều! Bây giờ câu hỏi thứ hai: dữ liệu chương trình nào sẽ được ghi lại? Điều đó hoàn toàn phụ thuộc vào bạn! Hệ thống ghi nhật ký của Java rất linh hoạt. Bạn có thể định cấu hình nó để ghi nhật ký mọi thứ mà chương trình của bạn thực hiện. Một mặt, điều này là tốt. Nhưng mặt khác, hãy tưởng tượng nhật ký của Facebook hoặc Twitter sẽ lớn như thế nào nếu họ viết mọi thứ vào đó. Những công ty lớn này có thể có khả năng lưu trữ nhiều dữ liệu đó. Nhưng hãy tưởng tượng việc tìm thông tin về một lỗi nghiêm trọng trong 500 gigabyte nhật ký văn bản sẽ khó đến mức nào? Điều đó còn tệ hơn là mò kim đáy bể. Theo đó, Java có thể được cấu hình để chỉ ghi dữ liệu lỗi. Hoặc thậm chí chỉ là lỗi nghiêm trọng! Điều đó nói rằng, không hoàn toàn chính xác khi nói về hệ thống ghi nhật ký gốc của Java. Thực tế là các lập trình viên cần đăng nhập trước khi chức năng này được thêm vào ngôn ngữ. Vào thời điểm Java giới thiệu thư viện ghi nhật ký của riêng mình, mọi người đã sử dụng thư viện log4j. Lịch sử ghi nhật ký trong Java thực sự rất dài và nhiều thông tin. Nói tóm lại là Java có thư viện ghi nhật ký riêng nhưng hầu như không ai dùng :) Sau này, khi một số thư viện ghi nhật ký khác nhau xuất hiện và bắt đầu được các lập trình viên sử dụng, các vấn đề về tính tương thích đã nảy sinh. Để ngăn mọi người phát minh lại bánh xe trong hàng chục thư viện khác nhau với các giao diện khác nhau, khung SLF4J trừu tượng ("Mặt tiền ghi nhật ký dịch vụ cho Java") đã được tạo. Nó được gọi là trừu tượng, bởi vì ngay cả khi bạn sử dụng và gọi các phương thức của các lớp SLF4J, thì dưới vỏ bọc, chúng thực sự sử dụng tất cả các khung ghi nhật ký có trước đó: log4j, java.util.logging tiêu chuẩn và các khung khác. Nếu tại một thời điểm nào đó, bạn cần một số tính năng cụ thể của Log4j mà các thư viện khác không có, nhưng bạn không muốn liên kết trực tiếp dự án của mình với thư viện này, chỉ cần sử dụng SLF4J. Và sau đó để nó gọi các phương thức Log4j. Nếu bạn đổi ý và quyết định rằng bạn không cần các tính năng của Log4j nữa, bạn chỉ cần cấu hình lại "tại đây , và thư viện Log4j tại đây . Tiếp theo, giải nén kho lưu trữ và sử dụng IntelliJ IDEA để thêm các tệp JAR vào đường dẫn lớp. Các mục menu: Tệp -> Cấu trúc dự án -> Thư viện Chọn các tệp JAR cần thiết và thêm chúng vào dự án (các tệp lưu trữ mà chúng tôi đã tải xuống chứa nhiều tệp JAR — hãy nhìn vào hình ảnh để biết những tệp bạn cần) Lưu ý rằng hướng dẫn này dành cho những sinh viên Tại sao chúng ta cần đăng nhập - 2Tại sao chúng ta cần đăng nhập - 3đó những người không biết cách sử dụng Maven. Nếu bạn biết cách sử dụng Maven, sẽ tốt hơn (dễ dàng hơn nhiều) nếu bạn cố gắng bắt đầu từ đó. Nếu bạn sử dụng Maven , hãy thêm phần phụ thuộc này:

    	<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.14.0</version>
    	</dependency>
Tuyệt vời! Chúng tôi đã tìm ra các cài đặt :) Hãy xem cách SLF4J hoạt động. Làm cách nào để chúng tôi đảm bảo rằng công việc của chương trình được ghi lại ở đâu đó? Để làm điều này, chúng ta cần hai thứ: logger và appender. Hãy bắt đầu với cái đầu tiên. Trình ghi nhật ký là một đối tượng cung cấp toàn quyền kiểm soát việc ghi nhật ký. Tạo một bộ ghi nhật ký rất dễ dàng: chúng tôi thực hiện việc này bằng cách sử dụng các phương thức LoggerFactory.getLogger() tĩnh . Tham số phương thức là lớp có hoạt động sẽ được ghi lại. Hãy chạy mã của chúng tôi:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("Test log entry!!!");
       LOGGER.error("An error occurred!");
   }
}
Đầu ra bảng điều khiển:

ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2 15:49:08.907 [main] ERROR MyTestClass - An error occurred!
Chúng ta thấy gì ở đây? Đầu tiên, chúng ta thấy một thông báo lỗi. Đây là kết quả của thực tế là hiện tại chúng tôi đang thiếu các cài đặt cần thiết. Theo đó, bộ ghi của chúng tôi hiện chỉ có thể xuất thông báo lỗi (ERROR) và chỉ cho bảng điều khiển. Phương thức logger.info() không hoạt động. Nhưng logger.error() đã làm được! Trên bảng điều khiển, chúng ta thấy ngày hiện tại, phương thức xảy ra lỗi ( main), từ "ERROR" và thông điệp của chúng tôi! LỖI là cấp độ ghi nhật ký. Nói chung, nếu một mục nhật ký được đánh dấu bằng từ "ERROR", thì đã xảy ra lỗi tại thời điểm này trong chương trình. Nếu mục nhập được đánh dấu bằng từ "INFO", thì thông báo chỉ đơn giản là đại diện cho thông tin hiện tại về hoạt động bình thường của chương trình. Thư viện SLF4J có nhiều cấp độ ghi nhật ký khác nhau cho phép bạn định cấu hình ghi nhật ký một cách linh hoạt. Tất cả đều rất dễ quản lý: tất cả logic cần thiết đã có sẵn trong lớp Java Logger . Bạn chỉ cần gọi các phương thức có liên quan. Nếu bạn muốn ghi nhật ký một thông báo thường xuyên, hãy gọi phương thức logger.info() . Đối với thông báo lỗi, hãy sử dụng logger.error() . Để có cảnh báo, hãy sử dụng logger.warn()

Bây giờ hãy nói về appender

Một appender là nơi dữ liệu của bạn đi. Theo một cách nào đó, đối diện với nguồn dữ liệu, tức là "điểm B". Theo mặc định, dữ liệu được xuất ra bàn điều khiển. Lưu ý rằng trong ví dụ trước, chúng tôi không phải định cấu hình bất kỳ thứ gì: văn bản xuất hiện trong bảng điều khiển và trình ghi nhật ký của thư viện Log4j chỉ có thể xuất các thông báo ở mức LỖI ra bảng điều khiển. Rõ ràng, mọi người sẽ thuận tiện hơn khi đọc và ghi nhật ký trong một tệp văn bản. Để thay đổi hành vi mặc định của trình ghi nhật ký, chúng tôi cần định cấu hình trình nối tệp của mình. Để bắt đầu, bạn cần tạo tệp log4j.xml trực tiếp trong thư mục src. Bạn đã quen thuộc với định dạng XML: gần đây chúng ta đã có một bài học về nó :) Đây là nội dung của tệp:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
   <Appenders>
       <File name="MyFileAppender" fileName="C:\Users\Username\Desktop\testlog.txt" immediateFlush="false" append="false">
           <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
       </File>
   </Appenders>
   <Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
   </Loggers>
</Configuration>
Không có gì đặc biệt hay khó khăn ở đây :) Tuy nhiên, chúng ta hãy xem qua nội dung.
<Configuration status="INFO">
Đây là cái gọi là StatusLogger. Nó không liên quan đến trình ghi nhật ký của chúng tôi và được sử dụng trong các quy trình nội bộ của Log4j. Nếu bạn đặt status="TRACE" thay vì status="INFO" và tất cả thông tin về công việc nội bộ của Log4j sẽ được hiển thị trên bảng điều khiển (StatusLogger hiển thị dữ liệu trên bảng điều khiển, ngay cả khi trình bổ sung của chúng tôi là một tệp). Bây giờ chúng tôi không cần nó, vì vậy hãy để nó như vậy.

<Appenders>
   <File name="MyFileAppender" fileName="C:\Users\Evgeny\Desktop\testlog.txt" append="true">
       <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
   </File>
</Appenders>
Ở đây chúng tôi tạo ứng dụng của chúng tôi. Thẻ <File> chỉ ra rằng nó sẽ là một trình nối thêm tệp. name="MyFileAppender" đặt tên của appender. fileName="C:\Users\Username\Desktop\testlog.txt" cho biết đường dẫn đến tệp nhật ký nơi tất cả dữ liệu sẽ được ghi. append="true" cho biết dữ liệu có nên được ghi ở cuối tệp hay không. Trong trường hợp của chúng tôi, đây chính xác là những gì chúng tôi sẽ làm. Nếu bạn đặt giá trị thành false, thì nội dung cũ của tệp nhật ký sẽ bị xóa mỗi khi chương trình được khởi động. <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>cho biết cài đặt định dạng. Tại đây, chúng ta có thể sử dụng các biểu thức chính quy để tùy chỉnh cách định dạng văn bản trong nhật ký của mình.

<Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
</Loggers>
Ở đây chúng tôi chỉ ra cấp độ gốc. Chúng tôi đã đặt mức "INFO", có nghĩa là tất cả thư có mức cao hơn INFO (theo bảng mà chúng tôi đã xem ở trên) sẽ không được ghi lại. Chương trình của chúng ta sẽ có 3 thông báo: một THÔNG TIN, một CẢNH BÁO và một LỖI. Với cấu hình hiện tại, cả 3 tin nhắn sẽ được ghi lại. Nếu bạn thay đổi cấp độ gốc thành ERROR, thì chỉ thông báo cuối cùng từ lệnh gọi phương thức LOGGER.error() mới được đưa vào nhật ký. Ngoài ra, một tham chiếu đến appender cũng có ở đây. Để tạo tham chiếu như vậy, bạn cần tạo thẻ <ApprenderRef> bên trong thẻ <Root> và thêm thuộc tính ref='your appender's name' vào thẻ. Trong trường hợp bạn quên, đây là nơi chúng ta đặt tên của appender: <. Và đây là mã của chúng tôi!

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("The program is starting!!!");

       try {
           LOGGER.warn("Attention! The program is trying to divide a number by another.
           System.out.println(12/0);
       } catch (ArithmeticException x) {

           LOGGER.error("Error! Division by zero!");
       }
   }
}
Tất nhiên, nó hơi kỳ quặc (bắt gặp RuntimeException là một ý tưởng đáng ngờ), nhưng nó hoàn hảo cho mục đích của chúng ta :) Hãy chạy phương thức main() của chúng ta 4 lần liên tiếp và xem tệp testlog.txt của chúng ta. Bạn không cần tạo trước: thư viện sẽ tự động thực hiện việc này. Mọi thứ đã hoạt động! :) Bây giờ bạn đã có một bộ ghi được cấu hình. Bạn có thể chơi xung quanh với một số chương trình cũ của mình, thêm các lệnh gọi logger vào từng phương thức. Sau đó xem nhật ký kết quả :) Nó xem xét chủ đề đăng nhập chuyên sâu. Sẽ rất khó để đọc tất cả trong một lần ngồi. Điều đó nói rằng, nó chứa rất nhiều thông tin hữu ích bổ sung. Ví dụ: bạn sẽ học cách định cấu hình trình ghi nhật ký để nó tạo một tệp văn bản mới nếu tệp testlog.txt của chúng ta đạt đến một kích thước nhất định :) Và điều đó kết thúc lớp học của chúng ta! Hôm nay bạn đã làm quen với một chủ đề rất quan trọng, và kiến ​​thức này chắc chắn sẽ hữu ích cho bạn trong công việc sau này. Cho đến lần sau! :)