文章目录
Markers
One of the primary purpose of a logging framework is to provide the means to generate debugging and diagnostic information only when it is needed, and to allow filtering of that information so that it does not overwhelm the system or the individuals who need to make use of it.
日志记录框架的主要目的之一是提供一种仅在需要时才生成调试和诊断信息的方法,并允许对该信息进行过滤,以使其不会对系统或需要使用该信息的个人显得太多(太多等于没有)。
As an example, an application desires to log its entry, exit and other operations separately from SQL statements being executed, and wishes to be able to log queries separate from updates.
例如,应用程序希望从执行的SQL语句来分开记录其进入,退出和其他操作,并希望能够把查询SQL语句的日志和更新语句的日志区分开。
One way to accomplish this is shown below:
实现此目的的一种方法如下所示:
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.traceEntry();
logger.debug(QUERY_MARKER, "SELECT * FROM {}", table);
String result = ...
return logger.traceExit(result);
}
public String doUpdate(String table, Map<String, String> params) {
logger.traceEntry();
if (logger.isDebugEnabled()) {
logger.debug(UPDATE_MARKER, "UPDATE {} SET {}", table, formatCols());
}
String result = ...
return logger.traceExit(result);
}
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();
}
}
In the example above it is now possible to add MarkerFilters to only allow SQL update operations to be logged, all SQL updates to be logged or to log everything in MyApp.
在上面的示例中,现在可以添加MarkerFilters仅允许记录SQL更新操作,记录所有SQL更新或将所有内容记录在MyApp中。
Some important rules about Markers must be considered when using them.
在使用Markers的时候,一些关于Markers的重要规则需要被考虑。
Markers must be unique. They are permanently registered by name so care should be taken to insure that Markers used in your application are distinct from those in the application’s dependencies, unless that is what is desired.
标记必须唯一。
它们是通过名称永久注册的,因此如非必要,请小心以确保应用程序中使用的Markers与应用程序依赖中的 不同(区分开,确保唯一)。
Parent Markers can be added or removed dynamically. However, this is fairly expensive to do. Instead, it is recommended that the parents be identified when obtaining the Marker the first time as shown in the examples above. Specifically, the set method replaces all the markers in a single operation while add and remove act on only a single Marker at a time.
可以动态地添加或删除Parent Markers。然而,这是相当昂贵的(耗性能)。相反,建议在第一次获取Marker时就设置Parent Marker,如上面的示例所示(直接初始化的时候就设置了Parent Marker,因为后面设置开销大)。具体地说,set方法替换单个操作中的所有标记( 我的理解是,只需初始化时候的一次操作对该java类中所有当前对象都生效,不知有没有更好的理解?欢迎评论 ),而add和remove一次只作用于一个标记。
Evaluating Markers with multiple ancestors is much more expensive than Markers with no parents. For example, in one set of tests to evaluate whether a Marker matched its grandparent took 3 times longer than evaluating the Marker itself. Even then though, evaluating Markers is inexpensive compared to resolving the callers class name or line number.
评估有多个祖先的Marker比没有双亲的标记开销要大很多。例如,在一组测试中,评估一个Marker是否与它的祖父标记(往上两层的parent marker)匹配的时间比评估Marker本身的时间长3倍。尽管如此,与解析调用者类名或行号相比,平局Merkers的开销还算小的。
https://logging.apache.org/log4j/2.x/manual/markers.html