Log4j 2 API

Marker

原文地址

日志框架最主要的目的之一,就是仅在需要的时候生成调试和诊断信息,并且过滤这些信息以防淹没系统或需要使用它的个体。举个例子,程序渴望记录它的进入、退出和其他操作,要与SQL语句的执行分离开,并且希望可以将查询和更新分开记录。一种做法是像下面这样做:

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.MarkerManager;
import java.util.Map;

public class MyApp {

    private Logger logger = LogManager.getLogger(MyApp.class.getName());
    private static final Marker SQL_MARKER = MarkerManager.getMarker("SQL");
    private static final Marker UPDATE_MARKER = MarkerManager.getMarker("SQL_UPDATE").setParents(SQL_MARKER);
    private static final Marker QUERY_MARKER = MarkerManager.getMarker("SQL_QUERY").setParents(SQL_MARKER);

    public String doQuery(String table) {
        logger.entry(param);

        logger.debug(QUERY_MARKER, "SELECT * FROM {}", table);

        return logger.exit();
    }

    public String doUpdate(String table, Map<String, String> params) {
        logger.entry(param);

        if (logger.isDebugEnabled()) {
          logger.debug(UPDATE_MARKER, "UPDATE {} SET {}", table, formatCols());

        return logger.exit();
    }

    private String formatCols(Map<String, String> cols) {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> entry : cols.entrySet()) {
            if (!first) {
                sb.append(", ");
            }
            sb.append(entry.getKey()).append("=").append(entry.getValue());
            first = false;
        }
        return sb.toString();
    }
}

在上例中,现在可以通过添加MarkerFilter来在MyApp中做到:只允许SQL更新操作被记录、所有的SQL更新被记录或记录所有。

使用Marker时必须注意一些重要的规则:

  1. Marker必须是唯一的。它们将根据名称被永久地注册,应该注意确保应用程序使用的Marker和应用所依赖的那些是不同的,除非那是确实需要的。
  2. 父Marker可以被动态地添加或删除。然而,这代价非常高。相反,推荐像上面例子中那样在首次获取Marker时定位父Marker。特别注意,set方法会在一次添加或删除操作中一次性地替换掉所有的Marker。
  3. 评估一个拥有多个祖先的Marker比没有祖先的Marker成本要更高。例如,在一组测试中评估一个Marker是否匹配其祖父要比评估该Marker自身花费三倍更长的时间。尽管如此,与处理调用者类名和行号相比,Marker的成本还不是很高。

results matching ""

    No results matching ""