-
Notifications
You must be signed in to change notification settings - Fork 528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug] AccessLogFilter for path matrics make Server OOM #2566
Comments
@dosu can you help me fix this bug |
Bug releated PR #2286 |
The root casue is this class logic AccessLogFilter.java
@dosu could you fix this bug |
To fix the OOM issue caused by variable paths in metrics collection in the Here's the modified package org.apache.hugegraph.api.filter;
import static org.apache.hugegraph.api.filter.PathFilter.REQUEST_TIME;
import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_FAILED_COUNTER;
import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_RESPONSE_TIME_HISTOGRAM;
import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_SUCCESS_COUNTER;
import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_TOTAL_COUNTER;
import java.io.IOException;
import java.net.URI;
import org.apache.hugegraph.auth.HugeAuthenticator;
import org.apache.hugegraph.config.HugeConfig;
import org.apache.hugegraph.config.ServerOptions;
import org.apache.hugegraph.core.GraphManager;
import org.apache.hugegraph.metrics.MetricsUtil;
import org.apache.hugegraph.util.Log;
import org.slf4j.Logger;
import jakarta.inject.Singleton;
import jakarta.ws.rs.HttpMethod;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.container.ContainerResponseFilter;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.ext.Provider;
@Provider
@Singleton
public class AccessLogFilter implements ContainerResponseFilter {
private static final Logger LOG = Log.logger(AccessLogFilter.class);
private static final String DELIMITER = "/";
private static final String GRAPHS = "graphs";
private static final String GREMLIN = "gremlin";
private static final String CYPHER = "cypher";
@Context
private jakarta.inject.Provider<HugeConfig> configProvider;
@Context
private jakarta.inject.Provider<GraphManager> managerProvider;
public static boolean needRecordLog(ContainerRequestContext context) {
String path = context.getUriInfo().getPath();
if (path.startsWith(GRAPHS)) {
if (HttpMethod.GET.equals(context.getMethod()) || path.endsWith(CYPHER)) {
return true;
}
}
return path.endsWith(GREMLIN);
}
private String join(String path1, String path2) {
return String.join(DELIMITER, path1, path2);
}
private String normalizePath(String path) {
// Replace variable parts of the path with placeholders
return path.replaceAll("/\\d+", "/{id}")
.replaceAll("/[a-f0-9-]{36}", "/{uuid}");
}
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
URI uri = requestContext.getUriInfo().getRequestUri();
String path = normalizePath(uri.getRawPath());
String method = requestContext.getMethod();
String metricsName = join(path, method);
MetricsUtil.registerCounter(join(metricsName, METRICS_PATH_TOTAL_COUNTER)).inc();
if (statusOk(responseContext.getStatus())) {
MetricsUtil.registerCounter(join(metricsName, METRICS_PATH_SUCCESS_COUNTER)).inc();
} else {
MetricsUtil.registerCounter(join(metricsName, METRICS_PATH_FAILED_COUNTER)).inc();
}
Object requestTime = requestContext.getProperty(REQUEST_TIME);
if (requestTime != null) {
long now = System.currentTimeMillis();
long start = (Long) requestTime;
long executeTime = now - start;
MetricsUtil.registerHistogram(join(metricsName, METRICS_PATH_RESPONSE_TIME_HISTOGRAM))
.update(executeTime);
HugeConfig config = configProvider.get();
long timeThreshold = config.get(ServerOptions.SLOW_QUERY_LOG_TIME_THRESHOLD);
if (timeThreshold > 0 && executeTime > timeThreshold &&
needRecordLog(requestContext)) {
LOG.info("[Slow Query] execTime={}ms, body={}, method={}, path={}, query={}",
executeTime, null, method, path, uri.getQuery());
}
}
GraphManager manager = managerProvider.get();
if (manager.requireAuthentication()) {
manager.unauthorize(requestContext.getSecurityContext());
}
}
private boolean statusOk(int status) {
return status >= 200 && status < 300;
}
} In this code, the |
@dosu 上边思路是正确的,但是
方法不能覆盖path = /graphs/hugegraph/graph/vertices/"2:mako" 这种场景,请修正下代码 |
To handle paths with variable parts such as Here is an example of how you can modify the private static final String VARIABLE_PART_REGEX = "/\\d+:\\w+";
private String normalizePath(String path) {
// Replace variable parts with a placeholder
return path.replaceAll(VARIABLE_PART_REGEX, "/{variable}")
.replaceAll("/\\d+", "/{id}")
.replaceAll("/[a-f0-9-]{36}", "/{uuid}");
} You can then use this @Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
URI uri = requestContext.getUriInfo().getRequestUri();
String rawPath = uri.getRawPath();
String path = normalizePath(rawPath);
String method = requestContext.getMethod();
String metricsName = join(path, method);
MetricsUtil.registerCounter(join(metricsName, METRICS_PATH_TOTAL_COUNTER)).inc();
if (statusOk(responseContext.getStatus())) {
MetricsUtil.registerCounter(join(metricsName, METRICS_PATH_SUCCESS_COUNTER)).inc();
} else {
MetricsUtil.registerCounter(join(metricsName, METRICS_PATH_FAILED_COUNTER)).inc();
}
Object requestTime = requestContext.getProperty(REQUEST_TIME);
if (requestTime != null) {
long now = System.currentTimeMillis();
long start = (Long) requestTime;
long executeTime = now - start;
MetricsUtil.registerHistogram(join(metricsName, METRICS_PATH_RESPONSE_TIME_HISTOGRAM))
.update(executeTime);
HugeConfig config = configProvider.get();
long timeThreshold = config.get(ServerOptions.SLOW_QUERY_LOG_TIME_THRESHOLD);
if (timeThreshold > 0 && executeTime > timeThreshold &&
needRecordLog(requestContext)) {
LOG.info("[Slow Query] execTime={}ms, body={}, method={}, path={}, query={}",
executeTime, null, method, path, uri.getQuery());
}
}
GraphManager manager = managerProvider.get();
if (manager.requireAuthentication()) {
manager.unauthorize(requestContext.getSecurityContext());
}
} This modification ensures that paths with variable parts are normalized, making the logging and metrics collection more consistent [1]. |
fix #2569 |
Bug Type (问题类型)
logic (逻辑设计问题)
Before submit
Environment (环境信息)
Expected & Actual behavior (期望与实际表现)
API
Get metrics
when there is many Vetices update
This Map will be oom
ServerReporter.java
The text was updated successfully, but these errors were encountered: