CodeGym /Blog Java /Ngẫu nhiên /Ghi nhật ký: cái gì, như thế nào, ở đâu và với cái gì?
John Squirrels
Mức độ
San Francisco

Ghi nhật ký: cái gì, như thế nào, ở đâu và với cái gì?

Xuất bản trong nhóm
Xin chào tất cả mọi người trong cộng đồng CodeGym! Ghi nhật ký: cái gì, như thế nào, ở đâu và với cái gì?  - 1 Hôm nay chúng ta hãy nói về đăng nhập:
  1. Nó là gì, tại sao nó tồn tại, khi nào bạn nên sử dụng nó, khi nào bạn nên tránh nó.
  2. Những triển khai ghi nhật ký nào có sẵn trong Java và bạn nên làm gì với tất cả các tùy chọn ghi nhật ký này.
  3. Và đăng nhập cấp độ. Chúng ta sẽ thảo luận appender là gì và cách định cấu hình nó một cách chính xác.
  4. Các nút ghi nhật ký và cách định cấu hình chúng một cách chính xác để mọi thứ hoạt động theo cách chúng tôi muốn.
Tài liệu này dành cho nhiều đối tượng. Điều này sẽ rõ ràng đối với bất kỳ ai mới biết về Java, cũng như những người đã đi làm nhưng mới chỉ khám phá logger.info("log something"); Let's go!

Tại sao bạn cần đăng nhập?

Hãy xem xét một số trường hợp thực tế mà việc ghi nhật ký có thể giải quyết vấn đề. Đây là một ví dụ từ công việc của tôi. Có những điểm mà một ứng dụng tích hợp với các dịch vụ khác. Tôi sử dụng việc ghi nhật ký tại những thời điểm này để thiết lập một loại "bằng chứng ngoại phạm" : nếu tích hợp không hoạt động, thì sẽ dễ dàng tìm ra bên nào có vấn đề. Cũng nên ghi nhật ký thông tin quan trọng được lưu trữ trong cơ sở dữ liệu. Ví dụ: việc tạo người dùng quản trị. Đây chính xác là loại điều sẽ tốt để đăng nhập.

Công cụ đăng nhập Java

Trong số các giải pháp ghi nhật ký nổi tiếng trong Java, chúng ta có thể làm nổi bật các giải pháp sau:
  • Nhật ký4j
  • THÁNG 7 — java.util.logging
  • JCL — Khai thác gỗ chung Jakarta
  • Đăng lại
  • SLF4J — Mặt tiền ghi nhật ký đơn giản cho Java
Chúng tôi sẽ cung cấp một cái nhìn tổng quan về từng người trong số họ. Sau đó, chúng ta sẽ lấy ràng buộc slf4j - log4j làm cơ sở cho một cuộc thảo luận thực tế. Bây giờ điều này có vẻ lạ, nhưng đừng lo lắng: đến cuối bài viết, mọi thứ sẽ rõ ràng.

System.err.println

Ban đầu, có System.err.println (hiển thị các mục nhật ký trên bàn điều khiển). Thậm chí ngày nay, kỹ thuật này được sử dụng để nhanh chóng ghi nhật ký khi gỡ lỗi. Tất nhiên, không có cài đặt nào để thảo luận ở đây, vì vậy chỉ cần nhớ phương pháp này và chúng ta sẽ tiếp tục.

Nhật ký4j

Đây là một giải pháp hoàn chỉnh mà các nhà phát triển đã tạo ra khi cần thiết. Kết quả là một công cụ thực sự thú vị mà bạn có thể sử dụng. Do nhiều hoàn cảnh khác nhau, giải pháp này đã không xuất hiện trong JDK, một thực tế đã khiến toàn bộ cộng đồng vô cùng khó chịu. Log4j có các tùy chọn cấu hình cho phép bạn kích hoạt đăng nhập trong com.example.typegói và tắt nó trong com.example.type.genericgói phụ. Điều này giúp bạn có thể nhanh chóng loại bỏ mã không cần phải ghi nhật ký. Điều quan trọng cần lưu ý ở đây là có hai phiên bản Log4j: 1.2.x và 2.xx và chúng không tương thích với nhau . Log4j đã thêm các khái niệm về appender(công cụ dùng để ghi nhật ký) và bố cục (định dạng nhật ký). Điều này cho phép bạn chỉ ghi nhật ký những gì bạn cần và ghi nhật ký theo cách bạn cần. Chúng ta sẽ nói thêm về appender sau.

THÁNG 7 — java.util.logging

Một trong những lợi ích chính của giải pháp này là JUL được bao gồm trong JDK (Bộ công cụ phát triển Java). Thật không may, khi nó được phát triển, những người tạo ra nó đã không dựa trên tiện ích Log4j phổ biến mà dựa trên một giải pháp của IBM. Quyết định đó đã có hậu quả. Thực tế là bây giờ không ai sử dụng JUL. Các cấp độ nhật ký trong JUL khác với những gì Logback, Log4j và Slf4j có. Điều này khiến họ khó hiểu nhau hơn. Tạo một logger ít nhiều giống nhau. Để làm điều này, bạn cần thực hiện nhập:

java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
Tên lớp được thông qua, vì vậy chúng tôi biết việc ghi nhật ký của chúng tôi sẽ đến từ đâu. Bắt đầu với Java 8, bạn có thể vượt qua Supplier<String>. Điều này giúp chúng tôi chỉ đọc và tạo một dòng khi chúng tôi thực sự cần nó, thay vì mọi lúc như trường hợp trước đây. Chỉ với việc phát hành Java 8, các nhà phát triển cuối cùng đã giải quyết được các vấn đề quan trọng và làm cho JUL thực sự có thể sử dụng được. Cụ thể, các phương thức có Supplier<String> msgSuppliertham số, như hình bên dưới:

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

JCL — Khai thác gỗ chung Jakarta

Bởi vì không có tiêu chuẩn ngành nào liên quan đến việc ghi nhật ký trong một thời gian dài và nhiều người đã tạo các trình ghi nhật ký tùy chỉnh của riêng họ, nên quyết định được đưa ra là phát hành JCL, một trình bao bọc chung có thể được sử dụng bên trên các trình bao bọc khác. Tại sao? Đôi khi các phần phụ thuộc được thêm vào dự án đã sử dụng một bộ ghi nhật ký khác với bộ ghi trong dự án. Do đó, chúng đã được thêm vào dự án dưới dạng phụ thuộc bắc cầu và điều này tạo ra các vấn đề thực sự khi cố gắng kết hợp tất cả lại với nhau. Thật không may, trình bao bọc không có nhiều chức năng và không thêm bất cứ thứ gì. Có lẽ sẽ thuận tiện nếu mọi người sử dụng JCL. Nhưng đó không phải là những gì đã xảy ra, vì vậy sử dụng JCL không phải là ý tưởng tốt nhất vào lúc này.

Đăng lại

Con đường mã nguồn mở đầy chông gai... Chính nhà phát triển đã viết Log4j cũng đã viết Logback như một khung ghi nhật ký kế nhiệm. Nó dựa trên ý tưởng tương tự như Log4j. Sự khác biệt trong Logback là:
  • hiệu suất được cải thiện
  • đã thêm hỗ trợ riêng cho Slf4j
  • tùy chọn lọc mở rộng
Theo mặc định, Logback không yêu cầu bất kỳ cấu hình nào và ghi lại tất cả các sự kiện ở cấp GỠ LỖI trở lên. Nếu bạn cần một số tùy chỉnh, bạn có thể đạt được điều đó thông qua cấu hình XML:

<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>

SLF4J — Mặt tiền ghi nhật ký đơn giản cho Java

Vào khoảng năm 2006, một trong những người sáng lập Log4j đã rời dự án và tạo ra Slf4j (Mặt tiền ghi nhật ký đơn giản cho Java), một trình bao bọc cho Log4j, JUL, ghi nhật ký chung và Logback. Như bạn có thể thấy, chúng tôi đã nâng cao đến mức tạo một trình bao bọc trên một trình bao bọc... Trong trường hợp này, nó được chia thành hai phần: Một API được sử dụng trong ứng dụng và một triển khai được thêm vào bằng các phần riêng biệt. phụ thuộc cho từng loại ghi nhật ký. Ví dụ, slf4j-log4j12.jarslf4j-jdk14.jar. Bạn cần kết nối việc triển khai chính xác và đó là: toàn bộ dự án của bạn sẽ sử dụng nó. Slf4j hỗ trợ tất cả các tính năng mới nhất, chẳng hạn như định dạng chuỗi để ghi nhật ký. Trước đây, có một vấn đề như vậy. Giả sử chúng ta tạo một mục nhật ký như thế này:

log.debug("User " + user + " connected from " + request.getRemoteAddr());
Do toán tử nối, userđối tượng âm thầm trở thành một chuỗi nhờ user.toString(). Điều này làm mất thời gian và làm chậm hệ thống. Và điều đó có thể ổn nếu chúng tôi đang gỡ lỗi ứng dụng. Chúng tôi bắt đầu gặp sự cố nếu cấp nhật ký cho lớp này là THÔNG TIN hoặc cao hơn. Nói cách khác, chúng ta không nên viết mục nhập nhật ký này (đối với INFO hoặc cao hơn) và chúng ta không nên sử dụng nối chuỗi. Về lý thuyết, chính thư viện ghi nhật ký sẽ giải quyết vấn đề này. Khi nó xảy ra, điều này hóa ra lại là vấn đề lớn nhất trong phiên bản đầu tiên của Log4j. Nó không mang lại một giải pháp tốt, mà thay vào đó đề xuất làm một cái gì đó như thế này:

if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
Đó là, thay vì một dòng mã để ghi nhật ký, họ đề xuất viết 3! Ghi nhật ký sẽ giảm thiểu thay đổi mã và ba dòng rõ ràng vi phạm cách tiếp cận chung đó. Slf4j không gặp vấn đề về khả năng tương thích với JDK và API, vì vậy một giải pháp hay đã xuất hiện ngay lập tức:

log.debug("User {} connected from {}", user, request.getRemoteAddr());
nơi {}biểu thị trình giữ chỗ cho các đối số được truyền cho phương thức. Nghĩa là, cái đầu tiên {}tương ứng với user, và cái thứ hai {}tương ứng với request.getRemoteAddr(). Bằng cách thực hiện theo cách này, chúng tôi sẽ chỉ thực hiện nối chuỗi nếu cấp nhật ký yêu cầu chúng tôi ghi mục nhập nhật ký. Sau đó, Sjf4j bắt đầu nổi tiếng nhanh chóng. Hiện tại, nó là giải pháp tốt nhất. Theo đó, chúng ta hãy xem ghi nhật ký bằng cách sử dụng slf4j-log4j12ràng buộc.

Những gì cần phải được đăng nhập

Tất nhiên, bạn không nên đăng nhập mọi thứ. Điều này thường không cần thiết và đôi khi còn nguy hiểm. Ví dụ: nếu bạn đăng nhập dữ liệu cá nhân của ai đó và bằng cách nào đó nó bị rò rỉ, sẽ có vấn đề thực sự xảy ra, đặc biệt là trong các dự án tập trung vào thị trường phương Tây. Nhưng cũng có những thứ mà bạn chắc chắn nên đăng nhập :
  1. Bắt đầu/kết thúc ứng dụng. Chúng ta cần biết liệu ứng dụng có thực sự bắt đầu và kết thúc như mong đợi hay không.
  2. Vân đê bảo mật. Tại đây, sẽ rất tốt nếu ghi lại các lần thử đoán mật khẩu của ai đó, các trường hợp khi quản trị viên đăng nhập, v.v.
  3. Một số trạng thái ứng dụng . Ví dụ, sự chuyển đổi từ trạng thái này sang trạng thái khác trong một quy trình kinh doanh.
  4. Một số thông tin gỡ lỗi cùng với cấp độ nhật ký tương ứng.
  5. Một số tập lệnh SQL. Có những trường hợp trong thế giới thực khi điều này là cần thiết. Nhưng một lần nữa, bằng cách điều chỉnh khéo léo các mức nhật ký, bạn có thể đạt được kết quả xuất sắc.
  6. Các luồng đang chạy có thể được ghi lại khi xác minh rằng mọi thứ đang hoạt động bình thường.

Các lỗi phổ biến khi đăng nhập

Có nhiều sắc thái ở đây, nhưng chúng tôi sẽ đặc biệt đề cập đến một số lỗi phổ biến:
  1. Đăng nhập quá mức. Bạn không nên ghi lại mọi bước mà về mặt lý thuyết có thể là quan trọng. Đây là một nguyên tắc nhỏ: Nhật ký không được vượt quá 10% tải. Nếu không, sẽ có vấn đề về hiệu suất.
  2. Ghi nhật ký tất cả dữ liệu vào một tệp. Tại một số điểm, điều này sẽ khiến việc đọc/ghi nhật ký trở nên rất khó khăn, chưa kể thực tế là một số hệ thống nhất định có giới hạn về kích thước tệp.
  3. Sử dụng cấp nhật ký không chính xác. Mỗi cấp độ nhật ký có ranh giới rõ ràng và chúng phải được tôn trọng. Nếu ranh giới không rõ ràng, bạn có thể đi đến thỏa thuận về cấp độ sẽ sử dụng.

cấp nhật ký

x: Hiển thị
GÂY TỬ VONG LỖI CẢNH BÁO THÔNG TIN GỠ LỖI DẤU VẾT TẤT CẢ
TẮT
GÂY TỬ VONG x
LỖI x x
CẢNH BÁO x x x
THÔNG TIN x x x x
GỠ LỖI x x x x x
DẤU VẾT x x x x x x
TẤT CẢ x x x x x x x
Cấp độ nhật ký là gì? Để bằng cách nào đó tạo ra một hệ thống phân cấp các mục nhập nhật ký, cần có các quy ước và phân định nhất định. Đây là lý do tại sao các cấp nhật ký đã được giới thiệu. Mức được đặt trong ứng dụng. Nếu một mục dưới một mức được chỉ định, thì nó sẽ không được ghi lại. Ví dụ: chúng tôi có nhật ký mà chúng tôi sử dụng khi gỡ lỗi ứng dụng. Trong quá trình hoạt động bình thường (khi ứng dụng được sử dụng cho mục đích đã định), các nhật ký như vậy là không cần thiết. Do đó, mức nhật ký cao hơn để gỡ lỗi. Hãy xem các cấp nhật ký bằng Log4j. Ngoài JUL, các giải pháp khác sử dụng cùng cấp độ nhật ký. Ở đây chúng theo thứ tự giảm dần:
  • TẮT: Không có mục nhật ký nào được ghi lại; mọi thứ đều bị bỏ qua.
  • FATAL: Lỗi ngăn ứng dụng tiếp tục chạy. Ví dụ: "Lỗi JVM hết bộ nhớ".
  • LỖI: Lỗi ở cấp độ này cho thấy các vấn đề cần được giải quyết. Lỗi không dừng toàn bộ ứng dụng. Các yêu cầu khác có thể hoạt động chính xác.
  • CẢNH BÁO: Các mục nhật ký đại diện cho cảnh báo. Đã xảy ra sự cố ngoài ý muốn, nhưng hệ thống đã có thể xử lý và đáp ứng yêu cầu
  • THÔNG TIN: Các mục nhật ký cho biết các hành động quan trọng trong ứng dụng. Đây không phải là lỗi hoặc cảnh báo. Chúng là các sự kiện hệ thống được mong đợi.
  • GỠ LỖI: Các mục nhật ký cần gỡ lỗi ứng dụng. Để đảm bảo rằng ứng dụng thực hiện chính xác những gì được mong đợi hoặc để mô tả các hành động mà ứng dụng thực hiện, tức là "Đã nhập phương thức 1".
  • TRACE: Các mục nhật ký có mức độ ưu tiên thấp hơn để gỡ lỗi. Mức nhật ký thấp nhất.
  • TẤT CẢ: Cấp nhật ký để ghi tất cả các mục nhật ký của ứng dụng.
Ở cấp độ nhật ký INFO được bật ở đâu đó trong ứng dụng, thì các mục nhập cho mọi cấp độ sẽ được ghi lại, từ INFO đến FATAL. Nếu mức nhật ký FATAL được đặt, chỉ các mục nhật ký có mức đó mới được ghi.

Ghi nhật ký và gửi nhật ký: Appender

Hãy xem xét cách tất cả những điều này hoạt động khi chúng ta sử dụng Log4j, cung cấp nhiều cơ hội để viết/gửi nhật ký:
  • để ghi vào một tập tin -DailyRollingFileAppender
  • để ghi thông tin vào bảng điều khiển —ConsoleAppender
  • để ghi nhật ký vào cơ sở dữ liệu —JDBCAppender
  • để quản lý việc gửi nhật ký qua TCP/IP —TelnetAppender
  • để đảm bảo rằng việc ghi nhật ký không ảnh hưởng tiêu cực đến hiệu suất —AsyncAppender
Có một số triển khai khác: danh sách đầy đủ có sẵn tại đây . Nhân tiện, nếu appender bạn cần không tồn tại, thì cũng không vấn đề gì. Bạn có thể viết appender của riêng mình bằng cách triển khai giao diện Appender mà Log4j hỗ trợ.

Các nút ghi nhật ký

Đối với mục đích trình diễn, chúng tôi sẽ sử dụng giao diện Slf4j, với việc triển khai từ Log4j. Tạo một bộ ghi nhật ký rất đơn giản: trong một lớp có tên MainDemo, lớp này sẽ thực hiện một số thao tác ghi nhật ký, chúng ta cần thêm vào như sau:

org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MainDemo.class);
Điều này sẽ tạo ra một logger cho chúng tôi. Để tạo một mục nhập nhật ký, có một số phương pháp khả dụng có tên phản ánh mức nhật ký nào sẽ được sử dụng. Ví dụ:

logger.trace("Method 1 started with argument={}", argument);
logger.debug("Database updated with script = {}", script);
logger.info("Application has started on port = {}", port);
logger.warn("Log4j didn't find the log4j.properties file. Please fix this.");
logger.error("Connection refused to host = {}", host);
Mặc dù chúng tôi đang chuyển lớp, tên cuối cùng là tên đầy đủ của lớp, bao gồm các gói. Điều này được thực hiện để sau này bạn có thể chia việc ghi nhật ký thành các nút và định cấu hình cấp độ ghi nhật ký và trình bổ sung cho mỗi nút. Ví dụ, bộ ghi đã được tạo trong com.github.romankh3.logginglecture.MainDemolớp. Tên cung cấp cơ sở để tạo một hệ thống phân cấp các nút ghi nhật ký. Nút chính là RootLogger cấp cao nhất . Đây là nút nhận tất cả các mục nhật ký cho toàn bộ ứng dụng. Các nút còn lại có thể được mô tả như hình bên dưới: Ghi nhật ký: cái gì, như thế nào, ở đâu và với cái gì?  - 3Các ứng dụng được định cấu hình cho các nút ghi nhật ký cụ thể. Bây giờ chúng ta sẽ xem tệp log4j.properties để xem ví dụ về cách định cấu hình chúng.

Hướng dẫn từng bước về tệp log4j.properties

Chúng tôi sẽ thiết lập mọi thứ từng bước một và xem những gì có thể:

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
Dòng này nói rằng chúng tôi đang đăng ký ứng dụng CONSOLE, ứng dụng này sử dụng triển khai org.apache.log4j.ConsoleAppender. Appender này ghi thông tin vào bàn điều khiển. Tiếp theo, chúng tôi đăng ký một appender khác. Cái này sẽ ghi vào một tập tin:

log4j.appender.FILE=org.apache.log4j.RollingFileAppender
Điều quan trọng cần lưu ý là bản thân các appender vẫn cần được cấu hình. Khi chúng tôi đã đăng ký các ứng dụng của mình, chúng tôi có thể xác định cấp nhật ký nào và ứng dụng nào sẽ được sử dụng tại các nút.

log4j.rootLogger=DEBUG, CONSOLE, FILE

  • log4j.rootLogger có nghĩa là chúng tôi đang định cấu hình nút gốc chứa tất cả các mục nhật ký
  • Từ đầu tiên sau dấu bằng cho biết mức nhật ký tối thiểu cần ghi (trong trường hợp của chúng tôi, đó là GỠ LỖI)
  • Sau dấu phẩy, chúng tôi chỉ ra tất cả các phần bổ sung sẽ được sử dụng.
Để cấu hình một nút ghi nhật ký cụ thể hơn, bạn sẽ sử dụng một mục như sau:

log4j.logger.com.github.romankh3.logginglecture=TRACE, OWN, CONSOLE
nơi log4j.logger.được sử dụng để tham chiếu một nút cụ thể. Trong trường hợp của chúng tôi, com.github.romankh3.logginglecture. Bây giờ hãy nói về cách định cấu hình ứng dụng CONSOLE:

# CONSOLE appender customization
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] : %c:%L : %m%n
Ở đây, chúng tôi thấy rằng có thể đặt mức cụ thể mà ứng dụng sẽ bắt đầu hoạt động. Đây là một ví dụ về những gì thực sự xảy ra: giả sử một thông báo có mức INFO được nhận bởi nút ghi nhật ký và được chuyển đến ứng dụng bổ sung được gán cho nó. Nếu ngưỡng của ứng dụng được đặt thành CẢNH BÁO, thì nó sẽ nhận được mục nhập nhật ký nhưng không làm gì với nó. Tiếp theo, chúng ta cần quyết định bố cục tin nhắn sẽ sử dụng. Tôi sử dụng PatternLayout trong ví dụ, nhưng có nhiều tùy chọn khác. Chúng tôi sẽ không đề cập đến chúng trong bài viết này. Ví dụ về cấu hình FILE appender:

# File appender customization
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=./target/logging/logging.log
log4j.appender.FILE.MaxFileSize=1MB
log4j.appender.FILE.threshold=DEBUG
log4j.appender.FILE.MaxBackupIndex=2
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[ %-5p] - %c:%L - %m%n
Bạn có thể định cấu hình tệp cụ thể mà các mục nhật ký sẽ được ghi, như có thể thấy từ dòng này:

log4j.appender.FILE.File=./target/logging/logging.log
Mục nhập được ghi vào logging.logtập tin. Để tránh sự cố với kích thước tệp, bạn có thể định cấu hình tối đa, trong trường hợp này là 1MB. MaxBackupIndexcho biết sẽ có bao nhiêu tệp nhật ký như vậy. Nếu chúng ta cần tạo nhiều tệp hơn số này, thì tệp đầu tiên sẽ bị xóa. Để xem một ví dụ thực tế nơi cấu hình ghi nhật ký, bạn có thể truy cập kho lưu trữ công khai trên GitHub.

Củng cố những gì chúng ta đã thảo luận

Hãy tự mình cố gắng làm mọi thứ chúng tôi đã mô tả:
  • Tạo dự án của riêng bạn tương tự như ví dụ của chúng tôi ở trên.
  • Nếu bạn biết cách sử dụng Maven, hãy sử dụng nó. Nếu không, hãy đọc phần hướng dẫn này , nó mô tả cách kết nối thư viện.

Tóm tắt

  1. Chúng tôi đã nói về các giải pháp ghi nhật ký tồn tại trong Java.
  2. Hầu như tất cả các thư viện ghi nhật ký nổi tiếng đều được viết bởi một người :D
  3. Chúng tôi đã học được những gì nên và không nên đăng nhập.
  4. Chúng tôi đã tìm ra các cấp nhật ký.
  5. Chúng tôi đã được giới thiệu về các nút ghi nhật ký.
  6. Chúng tôi đã xem appender là gì và nó dùng để làm gì.
  7. Chúng tôi đã từng bước tạo tệp log4j.proterties.

Tài liệu bổ sung

  1. CodeGym: Bài học Logger
  2. Geekly hàng tuần: Ghi nhật ký Java. Chào thế giới
  3. Mã hóa kinh dị: Vấn đề với việc ghi nhật ký
  4. YouTube: Tìm hiểu địa ngục ghi nhật ký Java - Khái niệm cơ bản. Địa ngục ghi nhật ký Java & Cách tránh xa nó
  5. Log4j: Ứng dụng
  6. Log4j: Bố cục
Cũng xem bài viết khác của tôi:
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION