Mapped Diagnostic Context (MDC) là một khái niệm, nói nôm na là nó cho phép từ Java code, chúng ta có thể truyền một số thông tin vào log message bên cạnh message mà chúng ta cần log sử dụng các Logging Framework như Log4J, Log4J2, Logback, SLF4J. Việc sử dụng chức năng này sẽ giúp chúng ta trong một số trường hợp như tracking việc thực thi của ứng dụng theo một tiêu chí nào đó thông qua message log, … Cụ thể như thế nào, chúng ta hãy cùng nhau tìm hiểu trong bài viết này các bạn nhé!
Đầu tiên, mình sẽ tạo mới một Maven project:
và sử dụng SLF4J cho Log4J để làm ví dụ:
1 2 3 4 5 |
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>2.0.16</version> </dependency> |
Để đơn giản, mình sẽ cấu hình Log4J với nội dung đơn giản như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <!-- Appenders --> <appender name="console" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p: %c - %m%n" /> </layout> </appender> <!-- Root Logger --> <root> <priority value="info" /> <appender-ref ref="console" /> </root> </log4j:configuration> |
Với cấu hình của PatternLayout trên, mỗi log message sẽ có định dạng là: logging level + category + message cần log + ký tự xuống dòng.
Khi đó, nếu mình muốn log một message nào đó:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.huongdanjava.slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Example { private static Logger LOGGER = LoggerFactory.getLogger(Example.class); public static void main(String[] args) { LOGGER.info("An example with Mapped Diagnostic Context"); } } |
thì kết quả sẽ như sau:
Bây giờ, nếu mình muốn identify xem log message đó là từ người dùng nào, nếu không sử dụng Mapped Diagnostic Context thì mình cần phải thêm đoạn code đó vào mỗi message mình cần log. Ví dụ như:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.huongdanjava.slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Example { private static Logger LOGGER = LoggerFactory.getLogger(Example.class); public static void main(String[] args) { String user = "Khanh"; LOGGER.info("An example with Mapped Diagnostic Context"); LOGGER.info(user + ": Messsage 1"); LOGGER.info(user + ": Messsage 2"); LOGGER.info(user + ": Messsage 3"); user = "Quan"; LOGGER.info(user + ": Messsage 1"); LOGGER.info(user + ": Messsage 2"); LOGGER.info(user + ": Messsage 3"); } } |
Kết quả:
Nếu bây giờ, mình sử dụng Mapped Diagnostic Context bằng cách modify đoạn code trên sử dụng đối tượng org.slf4j.MDC của SLF4J:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.huongdanjava.slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; public class Example { private static Logger LOGGER = LoggerFactory.getLogger(Example.class); public static void main(String[] args) { LOGGER.info("An example with Mapped Diagnostic Context"); String user = "Khanh"; MDC.put("user", user); LOGGER.info(": Messsage 1"); LOGGER.info(": Messsage 2"); LOGGER.info(": Messsage 3"); user = "Quan"; MDC.put("user", user); LOGGER.info(": Messsage 1"); LOGGER.info(": Messsage 2"); LOGGER.info(": Messsage 3"); } } |
và khai báo từ khoá user vào PatternLayout trong tập tin cấu hình của Log4J:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <!-- Appenders --> <appender name="console" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p: %c - %X{user}%m%n" /> </layout> </appender> <!-- Root Logger --> <root> <priority value="info" /> <appender-ref ref="console" /> </root> </log4j:configuration> |
thì kết quả cũng như vậy:
Như các bạn thấy, sử dụng đối tượng MDC của SLF4J cho phép chúng ta định nghĩa một key với value của nó. Sau đó, khai báo key này trong tập tin cấu hình của Log4J với cú pháp:
1 |
%X{key} |
giúp chúng ta có thể truyền thông tin mà chúng ta cần vào log message tách bạch với phần message cần log, giảm effort đi rất nhiều.