配置log4j2 日志,只想获取到 可执行的那一条日志,如何过滤?
原提问者GitHub用户joviqiao
在使用log4j2记录SQL执行日志时,出现同一条SQL语句被记录多次的问题,通常是由于多个log4j2的filter同时对SQL语句进行了处理所导致的。为了只获取到可执行的那条SQL语句,您可以考虑通过配置log4j2的filter来解决这个问题。
具体来说,可以通过配置一个自定义的log4j2 filter,在filter中进行SQL语句去重和过滤。
要过滤 log4j2 中的日志,以仅获取可执行的 SQL 语句,您可以使用 log4j2 的过滤器功能。下面是一种可能的配置方法:
首先,需要创建一个自定义的过滤器类,用于过滤日志事件。可以参考以下示例:
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.filter.AbstractFilter;
import org.apache.logging.log4j.core.filter.Filter.Result;
@Plugin(name = "ExecutableSqlFilter", category = "Core", elementType = "filter", printObject = true)
public class ExecutableSqlFilter extends AbstractFilter {
private static final String EXECUTABLE_SQL_MARKER = "ExecutableSqlMarker";
@Override
public Result filter(LogEvent event) {
if (event.getLevel() == Level.INFO && event.getLoggerName().equals("yourLoggerName") &&
event.getMessage() != null && event.getMessage().getFormattedMessage() != null &&
event.getMessage().getFormattedMessage().startsWith("Executing SQL:")) {
// 标记该事件为可执行的 SQL 日志
event.getContextData().put(EXECUTABLE_SQL_MARKER, true);
}
// 判断该事件是否为可执行的 SQL 日志并返回相应的 Result
boolean isExecutableSqlEvent = event.getContextData().containsKey(EXECUTABLE_SQL_MARKER);
return isExecutableSqlEvent ? Result.NEUTRAL : Result.DENY;
}
}
在上面的代码中,我们定义了一个名为 ExecutableSqlFilter 的自定义过滤器,通过判断日志事件的级别、日志记录器名称以及日志消息的内容来识别可执行的 SQL 日志。如果事件被标记为可执行的 SQL 日志,则返回 Result.NEUTRAL 表示接受该日志事件;否则返回 Result.DENY 表示拒绝该日志事件。
接下来,需要在 log4j2 的配置文件中应用该过滤器。参考下面的示例:
<?xml version="1.0" encoding="UTF-8"?>
在上面的示例中,我们在 部分的 console appender 配置中添加了 ,并指定使用我们创建的自定义过滤器 ExecutableSqlFilter。
通过这样的配置,只有被标记为可执行 SQL 的日志事件才会被记录和输出,其它日志事件将被过滤掉。请替换 yourLoggerName 为您的日志记录器名称,并根据需要进行其他相关的调整。
这样配置后,log4j2 将只获取到可执行的 SQL 日志。
可以使用log4j2的配置参数来过滤日志。具体来说,可以使用log4j2的Filter和Appender来过滤日志。
需要注意的是,如果你使用的是log4j2的其他版本,可能需要使用不同的参数来配置log4j2的日志过滤功能。
Slf4jLogFilter sql_log_filter = new Slf4jLogFilter();
sql_log_filter.setConnectionLogEnabled(false); sql_log_filter.setStatementLogEnabled(false); sql_log_filter.setStatementExecutableSqlLogEnable(true); sql_log_filter.setResultSetLogEnabled(false);
原回答者GitHub用户livem
要只获取可执行的SQL语句,您可以使用Log4j2的过滤器功能。以下是一种可能的解决方案:
<Appenders>
...
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%-5p %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1}:%L - %m%n" />
<Filters>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<MarkerFilter marker="EXECUTING_SQL" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</Console>
...
</Appenders>
在上述示例中,我们添加了一个名为"EXECUTING_SQL"的标记过滤器。只有带有此标记的日志事件才会被接受。
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
public class YourClass {
private static final Logger logger = LogManager.getLogger(YourClass.class);
private static final Marker SQL_MARKER = MarkerManager.getMarker("EXECUTING_SQL");
public void executeSQL(String sql) {
// 执行 SQL 之前
logger.debug(SQL_MARKER, "Executing SQL: {}", sql);
// 执行 SQL
// 执行 SQL 之后
logger.debug(SQL_MARKER, "Executed SQL: {}", sql);
}
}
在上述示例中,我们使用MarkerManager.getMarker("EXECUTING_SQL")
获取了一个名为"EXECUTING_SQL"的标记,并在执行SQL之前和之后使用logger.debug(SQL_MARKER, ...)
来记录带有此标记的日志事件。
现在,只有带有"EXECUTING_SQL"标记的日志事件才会被接受并输出到日志文件或控制台。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。