You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot中过滤Tomcat访问日志中的TCP请求?

过滤Tomcat访问日志中的非HTTP请求(如HAProxy健康检查)

你的Servlet Filter仅对合法HTTP请求生效,而HAProxy那种返回400的健康检查请求属于不符合HTTP规范的TCP请求——这类请求在Tomcat走到Servlet Filter阶段前就被处理了,因此需要从Tomcat的访问日志核心组件层面解决。

以下是两种可行方案:

方案一:自定义AccessLogValve拦截日志记录

Tomcat的AccessLogValve是生成访问日志的核心组件,我们可以通过继承它并重写日志逻辑,实现特定请求的过滤。

1. 自定义AccessLogValve

import org.apache.catalina.valves.AccessLogValve;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;

public class FilteredAccessLogValve extends AccessLogValve {
    @Override
    protected void log(Request request, Response response, long time) {
        // 过滤掉请求URI为"-"且状态码为400的请求(对应HAProxy健康检查日志)
        String requestUri = request.getRequestURI();
        int statusCode = response.getStatus();
        if ("-".equals(requestUri) && statusCode == 400) {
            return; // 跳过记录该日志
        }
        // 正常请求继续执行原有日志逻辑
        super.log(request, response, time);
    }
}

2. 在Spring Boot中替换默认Valve

通过WebServerFactoryCustomizer配置Tomcat,替换默认的AccessLogValve为自定义实现:

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
import org.apache.catalina.valves.AccessLogValve;

@Component
public class TomcatAccessLogCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // 移除默认的AccessLogValve
        factory.getEngineValves().removeIf(valve -> valve instanceof AccessLogValve);
        // 添加自定义Valve并配置原有日志参数
        FilteredAccessLogValve customValve = new FilteredAccessLogValve();
        customValve.setDirectory("logs");
        customValve.setPrefix("localhost_access_log");
        customValve.setSuffix(".txt");
        customValve.setPattern("%h %l %u %t \"%r\" %s %b"); // 保持原有日志格式
        factory.addEngineValves(customValve);
    }
}

方案二:利用Tomcat AccessLogValve的条件过滤

如果不想自定义类,可直接通过配置condition属性,基于请求属性过滤日志。在Spring Boot配置文件中添加:

application.properties

server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.directory=logs
server.tomcat.accesslog.prefix=localhost_access_log
server.tomcat.accesslog.suffix=.txt
server.tomcat.accesslog.pattern=%h %l %u %t \"%r\" %s %b
# 排除状态码400且请求URI为"-"的请求
server.tomcat.accesslog.condition=not (statusCode == 400 and requestURI == '-')

说明

  • 该方式依赖Tomcat的EL表达式支持,condition属性允许通过表达式判断是否记录日志。
  • HAProxy健康检查请求会被Tomcat标记为请求URI="-"、状态码400,正好匹配上述过滤条件。

注意:两种方案均适配Tomcat 10.1.18版本,方案一中AccessLogValve.log方法为protected权限,可直接重写。

内容的提问来源于stack exchange,提问作者rmf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 13:25:09