开发者社区> 问答> 正文

log4j2 filter 日志一条sql会出现三次,如何只获取到可执行的那条sql?

配置log4j2 日志,只想获取到 可执行的那一条日志,如何过滤?

原提问者GitHub用户joviqiao

展开
收起
山海行 2023-07-05 21:29:59 114 0
5 条回答
写回答
取消 提交回答
  • 北京阿里云ACE会长

    在使用log4j2记录SQL执行日志时,出现同一条SQL语句被记录多次的问题,通常是由于多个log4j2的filter同时对SQL语句进行了处理所导致的。为了只获取到可执行的那条SQL语句,您可以考虑通过配置log4j2的filter来解决这个问题。

    具体来说,可以通过配置一个自定义的log4j2 filter,在filter中进行SQL语句去重和过滤。

    2023-07-30 09:36:46
    赞同 展开评论 打赏
  • 值得去的地方都没有捷径

    要过滤 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 日志。

    2023-07-11 19:17:07
    赞同 展开评论 打赏
  • 可以使用log4j2的配置参数来过滤日志。具体来说,可以使用log4j2的Filter和Appender来过滤日志。
    需要注意的是,如果你使用的是log4j2的其他版本,可能需要使用不同的参数来配置log4j2的日志过滤功能。

    2023-07-11 10:33:13
    赞同 展开评论 打赏
  • 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

    2023-07-06 12:14:15
    赞同 展开评论 打赏
  • 要只获取可执行的SQL语句,您可以使用Log4j2的过滤器功能。以下是一种可能的解决方案:

    1. 在您的log4j2配置文件中,为SQL日志记录器定义一个过滤器。例如:
    <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"的标记过滤器。只有带有此标记的日志事件才会被接受。

    1. 在代码中,在执行SQL语句之前和之后使用相应的标记来标记日志事件。例如,在Java代码中,您可以这样做:
    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"标记的日志事件才会被接受并输出到日志文件或控制台。

    2023-07-05 21:33:22
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
PostgresChina2018_赖思超_PostgreSQL10_hash索引的WAL日志修改版final 立即下载
Kubernetes下日志实时采集、存储与计算实践 立即下载
日志数据采集与分析对接 立即下载