Apache Log4j2 API官方使用指南(四) —— EventLogger

什麼是EventLogger

The EventLogger class provides a simple mechanism for logging events that occur in an application. While the EventLogger is useful as a way of initiating events that should be processed by an audit Logging system, by itself it does not implement any of the features an audit logging system would require such as guaranteed delivery.
EventLogger類提供了一種用於記錄應用程序中發生的日誌事件的簡單機制。
儘管EventLogger作爲一種啓動事件的有效方法,(這種啓動方法)應該被審覈日誌記錄系統處理。但EventLogger本身並未實現審覈日誌記錄系統所需的任何功能,例如保證交付。

EventLogger的使用

The recommended way of using the EventLogger in a typical web application is to populate the ThreadContext Map with data that is related to the entire lifespan of the request such as the user’s id, the user’s IP address, the product name, etc. This can easily be done in a servlet filter where the ThreadContext Map can also be cleared at the end of the request. When an event that needs to be recorded occurs a StructuredDataMessage should be created and populated. Then call EventLogger.logEvent(msg) where msg is a reference to the StructuredDataMessage.
在典型的Web應用程序中,使用EventLogger的推薦方法是,

  1. 用與請求的整個生命週期相關的數據(例如用戶的ID,用戶的IP地址,產品名稱等)去填充ThreadContext Map。以上這些可以在一個Servlet過濾器中輕鬆做到,在該過濾器中,ThreadContext Map也可以在請求結束時被清除。
  2. 當需要記錄的事件發生時,應創建並填充一個StructuredDataMessage對象。
  3. 然後調用EventLogger.logEvent(msg),其中msg是對StructuredDataMessage的引用。
import org.apache.logging.log4j.ThreadContext;
import org.apache.commons.lang.time.DateUtils;
 
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.TimeZone;
 
public class RequestFilter implements Filter {
    private FilterConfig filterConfig;
    private static String TZ_NAME = "timezoneOffset";
 
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }
 
    /**
     * Sample filter that populates the MDC on every request.
     * 在每次請求都填充MDC的過濾器示例
     * 什麼是MDC在文末會提到
     */
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        //在ThreadContext中填充相關數據,這邊是IP地址
        ThreadContext.put("ipAddress", request.getRemoteAddr());
        HttpSession session = request.getSession(false);
        TimeZone timeZone = null;
        if (session != null) {
            // Something should set this after authentication completes 在完成鑑權後需要設定的一些東西
            String loginId = (String)session.getAttribute("LoginId");
            if (loginId != null) {
                ThreadContext.put("loginId", loginId);
            }
            // This assumes there is some javascript on the user's page to create the cookie. 這裏假設有一些js在用戶頁面上用來創建Cookie
            if (session.getAttribute(TZ_NAME) == null) {
                if (request.getCookies() != null) {
                    for (Cookie cookie : request.getCookies()) {
                        if (TZ_NAME.equals(cookie.getName())) {
                            int tzOffsetMinutes = Integer.parseInt(cookie.getValue());
                            timeZone = TimeZone.getTimeZone("GMT");
                            timeZone.setRawOffset((int)(tzOffsetMinutes * DateUtils.MILLIS_PER_MINUTE));
                            request.getSession().setAttribute(TZ_NAME, tzOffsetMinutes);
                            cookie.setMaxAge(0);
                            response.addCookie(cookie);
                        }
                    }
                }
            }
        }
        ThreadContext.put("hostname", servletRequest.getServerName());
        ThreadContext.put("productName", filterConfig.getInitParameter("ProductName"));
        ThreadContext.put("locale", servletRequest.getLocale().getDisplayName());
        if (timeZone == null) {
            timeZone = TimeZone.getDefault();
        }
        ThreadContext.put("timezone", timeZone.getDisplayName());
        filterChain.doFilter(servletRequest, servletResponse);
        ThreadContext.clear();
    }
 
    public void destroy() {
    }
}

Sample class that uses EventLogger. 使用EventLogger的示例類

import org.apache.logging.log4j.StructuredDataMessage;
import org.apache.logging.log4j.EventLogger;
 
import java.util.Date;
import java.util.UUID;
 
public class MyApp {
 
    public String doFundsTransfer(Account toAccount, Account fromAccount, long amount) {
        toAccount.deposit(amount);
        fromAccount.withdraw(amount);
        String confirm = UUID.randomUUID().toString();
        //當需要記錄的事件發生時,應創建並填充一個StructuredDataMessage對象。
        StructuredDataMessage msg = new StructuredDataMessage(confirm, null, "transfer");
        msg.put("toAccount", toAccount);
        msg.put("fromAccount", fromAccount);
        msg.put("amount", amount);
        //最後調用EventLogger的logEvent方法來記錄日誌。
        EventLogger.logEvent(msg);
        return confirm;
    }
}

EventLogger日誌的格式化和打印

The EventLogger class uses a Logger named “EventLogger”. EventLogger uses a logging level of OFF as the default to indicate that it cannot be filtered. These events can be formatted for printing using the StructuredDataLayout.
EventLogger使用OFF作爲默認的日誌級別來表示它不能被過濾。
這些日誌事件可以使用StructuredDataLayout 格式化之後打印。

What is MDC filter?

“Mapped Diagnostic Context” is essentially a map maintained by the logging framework where the application code provides key-value pairs which can then be inserted by the logging framework in log messages. MDC data can also be highly helpful in filtering messages or triggering certain actions.
“映射的診斷上下文”實質上是由日誌記錄框架維護的映射,其中應用程序代碼提供鍵值對,然後可以由日誌記錄框架將其插入日誌消息中。
MDC數據在篩選消息或觸發某些操作方面也可能非常有幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章