Apache Log4j2 API官方使用指南(一) —— Marker类怎么用

文章目录

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于Javalog4j2日志脱敏的过滤器示例: 首先,在log4j2配置文件中添加以下内容: ```xml <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> <filters> <Filter type="Script" language="java" script="com.example.LogFilter.filter(logEvent);"/> </filters> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration> ``` 其中,filters标签用于添加过滤器,type属性为“Script”,表示使用脚本过滤器,language属性为“java”,表示使用Java语言编写脚本。 然后,创建一个Java,实现LogEventFilter接口,并编写脱敏逻辑。例如: ```java package com.example; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.filter.AbstractFilter; @Plugin(name = "LogFilter", category = "Core", elementType = "filter", printObject = true) public class LogFilter extends AbstractFilter { @Override public Result filter(LogEvent logEvent) { if (logEvent.getMessage().getFormattedMessage().contains("password")) { String message = logEvent.getMessage().getFormattedMessage().replaceAll("password=\\S+", "password=******"); logEvent.setMessage(logEvent.getMessage().newInstance(message)); return Result.ACCEPT; } else { return Result.NEUTRAL; } } @Override public Result filter(Logger logger, Level level, Marker marker, String s, Object... objects) { return null; } @Override public Result filter(Logger logger, Level level, Marker marker, Object o, Throwable throwable) { return null; } @Override public Result filter(Logger logger, Level level, Marker marker, Message message, Throwable throwable) { return null; } } ``` 该实现了LogEventFilter接口,并重写了filter方法,实现了日志脱敏的逻辑。具体来说,该方法会检查日志消息中是否包含“password”关键字,如果包含,则将“password”后面的字符替换为“******”,然后返回Result.ACCEPT,表示接受该日志事件,并修改了消息内容。如果不包含,则返回Result.NEUTRAL,表示不对该日志事件进行任何修改。 最后,在log4j2配置文件中的filters标签中,使用该过滤器即可。例如: ```xml <filters> <LogFilter/> </filters> ``` 这样配置后,当日志中包含“password”关键字时,日志消息中的“password”后面的字符就会被替换为“******”,从而实现了日志脱敏的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值