如何覆盖执行器/普罗米修斯中的查询参数以隐藏其值

问题描述 投票:0回答:0
我不经常在这里写信,但我面临着一个有趣的问题。 我们有一个启用了执行器/普罗米修斯的 spring 项目 2.5.x。 有一些 get 查询使用我们希望在 /actuator/prometheus 中隐藏的数据(仅是查询的查询参数的子集,而不是全部),因为默认情况下任何 get 请求都会使用查询参数记录(这是有道理的) )。现在我知道所有这些麻烦都可以通过切换到帖子来避免,但目前我们还不能。

这是我现在拥有的:

http_client_requests_seconds_sum{client_name="client",method="GET",outcome="SUCCESS",status="200",uri="/test?query=1234&field1=value2&field2=value3",} 0.050652838

这是我想获得的:
http_client_requests_seconds_sum{client_name="client",method="GET",outcome="SUCCESS",status="200",uri="/test?query=****&field1=value2&field2=value3",} 0.050652838

我想要隐藏的部分始终称为查询。

到目前为止我尝试过的:

    创建一个过滤器来过滤掉日志中的查询:这有效,但执行器仍然注册正常查询
@Component @Order(1) public class QueryParameterSanitizationFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest) { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String requestURI = httpServletRequest.getRequestURI(); // List of URIs that require query parameter sanitization String[] endpointsToSanitize = {"endpoint1", "/endpoint2"}; if (requiresSanitization(requestURI, endpointsToSanitize)) { SanitizedRequestWrapper wrappedRequest = new SanitizedRequestWrapper(httpServletRequest); chain.doFilter(wrappedRequest, response); } else { chain.doFilter(request, response); } } else { chain.doFilter(request, response); } } // Implement a method to check if the URI requires query parameter sanitization private boolean requiresSanitization(String requestURI, String[] endpointsToSanitize) { for (String endpoint : endpointsToSanitize) { if (requestURI.startsWith(endpoint)) { return true; } } return false; } // Custom wrapper to capture the request and modify query parameters private static class SanitizedRequestWrapper extends HttpServletRequestWrapper { private String sanitizedQueryString; public SanitizedRequestWrapper(HttpServletRequest request) { super(request); this.sanitizedQueryString = sanitizeQueryParameters(request.getQueryString()); } @Override public String getQueryString() { return sanitizedQueryString; } private String sanitizeQueryParameters(String queryString) { if (queryString != null) { String[] params = queryString.split("&"); for (int i = 0; i < params.length; i++) { String param = params[i]; if (param.startsWith("param=")) { // If it does, replace the value with "***" params[i] = "param=***"; } } // Reconstruct the sanitized query string return String.join("&", params); } return queryString; } } }
创建自定义 

HttpServletWrapper

HandlerInterceptor
HandlerInterceptorAdapter

public class QueryParameterSanitizationInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); String[] endpointsToSanitize = {"/endpoint1","endpoint2"}; if (requiresSanitization(requestURI, endpointsToSanitize)) { SanitizedRequestWrapper wrappedRequest = new SanitizedRequestWrapper(request); request = wrappedRequest; } return true; } private boolean requiresSanitization(String requestURI, String[] endpointsToSanitize) { for (String endpoint : endpointsToSanitize) { if (requestURI.startsWith(endpoint)) { return true; } } return false; } }
public class QueryParameterSanitizationInterceptorAdapter extends HandlerInterceptorAdapter {

    private final QueryParameterSanitizationInterceptor interceptor;

    public QueryParameterSanitizationInterceptorAdapter(QueryParameterSanitizationInterceptor interceptor) {
        this.interceptor = interceptor;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        return interceptor.preHandle(request, response, handler);
    }

}
public class SanitizedRequestWrapper extends HttpServletRequestWrapper {

    private final String sanitizedQueryString;

    public SanitizedRequestWrapper(HttpServletRequest request) {
        super(request);
        this.sanitizedQueryString = sanitizeQueryParameters(request.getQueryString());
    }

    @Override
    public String getQueryString() {
        return sanitizedQueryString;
    }

    private String sanitizeQueryParameters(String queryString) {
        if (queryString != null) {
            // Split the query string into individual parameter-value pairs
            String[] params = queryString.split("&");
            for (int i = 0; i < params.length; i++) {
                String param = params[i];
                // Check if the parameter starts with "query="
                if (param.startsWith("query=")) {
                    // If it does, replace the value with "***"
                    params[i] = "query=***";
                }
            }
            // Reconstruct the sanitized query string
            return String.join("&", params);
        }
        return queryString;
    }
}
这效果不太好。
我再次知道,如果我们切换到发布请求,一切都可以解决,但目前这是不可能的。
大家还有什么额外的想法吗?

提前致谢

编辑:

我通过创建一个应用所需转换的新计量过滤器解决了这个问题。

java spring-boot spring-boot-actuator
© www.soinside.com 2019 - 2024. All rights reserved.