Skip to content

Commit

Permalink
[#10377] Backport: Add uri stat user input for tomcat plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
ga-ram committed Oct 10, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 091523d commit 1cd7497
Showing 6 changed files with 104 additions and 0 deletions.
2 changes: 2 additions & 0 deletions agent/src/main/resources/profiles/local/pinpoint.config
Original file line number Diff line number Diff line change
@@ -320,6 +320,8 @@ profiler.uri.stat.vertx.enable=true
profiler.uri.stat.vertx.useuserinput=false
profiler.uri.stat.spring.webflux.enable=true
profiler.uri.stat.spring.webflux.useuserinput=false
profiler.uri.stat.tomcat.useuserinput=false

###########################################################
# TOMCAT #
###########################################################
1 change: 1 addition & 0 deletions agent/src/main/resources/profiles/release/pinpoint.config
Original file line number Diff line number Diff line change
@@ -320,6 +320,7 @@ profiler.uri.stat.vertx.enable=true
profiler.uri.stat.vertx.useuserinput=false
profiler.uri.stat.spring.webflux.enable=true
profiler.uri.stat.spring.webflux.useuserinput=false
profiler.uri.stat.tomcat.useuserinput=false

###########################################################
# TOMCAT #
Original file line number Diff line number Diff line change
@@ -39,6 +39,10 @@ public class TomcatConfig {
private final String realIpEmptyValue;
private final Filter<String> excludeProfileMethodFilter;

private final boolean uriStatEnable;
private final boolean uriStatUseUserInput;
private final boolean uriStatCollectMethod;

public TomcatConfig(ProfilerConfig config) {
Objects.requireNonNull(config, "config");

@@ -53,6 +57,10 @@ public TomcatConfig(ProfilerConfig config) {
this.realIpHeader = serverConfig.getRealIpHeader("profiler.tomcat.realipheader");
this.realIpEmptyValue = serverConfig.getRealIpEmptyValue("profiler.tomcat.realipemptyvalue");
this.excludeProfileMethodFilter = serverConfig.getExcludeMethodFilter("profiler.tomcat.excludemethod");
// uri stat
this.uriStatEnable = config.readBoolean("profiler.uri.stat.enable", true);
this.uriStatUseUserInput = config.readBoolean("profiler.uri.stat.tomcat.useuserinput", false);
this.uriStatCollectMethod = config.readBoolean("profiler.uri.stat.collect.http.method", false);
}

public boolean isEnable() {
@@ -87,6 +95,18 @@ public Filter<String> getExcludeProfileMethodFilter() {
return excludeProfileMethodFilter;
}

public boolean isUriStatEnable() {
return uriStatEnable;
}

public boolean isUriStatUseUserInput() {
return uriStatUseUserInput;
}

public boolean isUriStatCollectMethod() {
return uriStatCollectMethod;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("TomcatConfig{");
@@ -101,4 +121,5 @@ public String toString() {
sb.append('}');
return sb.toString();
}

}
Original file line number Diff line number Diff line change
@@ -44,4 +44,5 @@ private TomcatConstants() {
*/
public static final String JAVAX_ERROR_EXCEPTION = "javax.servlet.error.exception";
public static final String JAKARTA_ERROR_EXCEPTION = "jakarta.servlet.error.exception";
public static final String[] TOMCAT_URI_USER_INPUT_ATTRIBUTE_KEYS = {"pinpoint.metric.uri-template"};
}
Original file line number Diff line number Diff line change
@@ -18,6 +18,8 @@

import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig;
import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor;
import com.navercorp.pinpoint.bootstrap.context.SpanRecorder;
import com.navercorp.pinpoint.bootstrap.context.Trace;
import com.navercorp.pinpoint.bootstrap.context.TraceContext;
import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor;
import com.navercorp.pinpoint.bootstrap.logging.PLogger;
@@ -34,6 +36,7 @@
import com.navercorp.pinpoint.bootstrap.plugin.response.ServletResponseListenerBuilder;
import com.navercorp.pinpoint.bootstrap.util.argument.Validation;
import com.navercorp.pinpoint.bootstrap.util.argument.Validator;
import com.navercorp.pinpoint.common.util.StringUtils;
import com.navercorp.pinpoint.plugin.common.servlet.jakarta.util.HttpServletRequestAdaptor;
import com.navercorp.pinpoint.plugin.common.servlet.jakarta.util.HttpServletResponseAdaptor;
import com.navercorp.pinpoint.plugin.common.servlet.jakarta.util.ParameterRecorderFactory;
@@ -57,14 +60,22 @@ public class StandardHostValveInvokeInterceptor implements AroundInterceptor {
private final ServletRequestListener<HttpServletRequest> servletRequestListener;
private final ServletResponseListener<HttpServletResponse> servletResponseListener;

private final TraceContext traceContext;
private final boolean uriStatEnable;
private final boolean uriStatUseUserInput;
private final boolean uriStatCollectMethod;

public StandardHostValveInvokeInterceptor(TraceContext traceContext, MethodDescriptor descriptor,
RequestRecorderFactory<HttpServletRequest> requestRecorderFactory) {
this.traceContext = traceContext;
this.methodDescriptor = descriptor;

this.validator = buildValidator();
final TomcatConfig config = new TomcatConfig(traceContext.getProfilerConfig());

this.uriStatEnable = config.isUriStatEnable();
this.uriStatUseUserInput = config.isUriStatUseUserInput();
this.uriStatCollectMethod = config.isUriStatCollectMethod();

RequestAdaptor<HttpServletRequest> requestAdaptor = new HttpServletRequestAdaptor();
ParameterRecorder<HttpServletRequest> parameterRecorder = ParameterRecorderFactory.newParameterRecorderFactory(config.getExcludeProfileMethodFilter(), config.isTraceRequestParam());
@@ -147,13 +158,41 @@ public void after(Object target, Object[] args, Object result, Throwable throwab
}
}
}
if (uriStatEnable && uriStatUseUserInput) {
recordUserUriTemplate(request);
}
this.servletResponseListener.destroyed(response, throwable, statusCode); //must before request listener due to trace block ending
this.servletRequestListener.destroyed(request, throwable, statusCode);
} catch (Throwable t) {
logger.info("Failed to servlet request event handle.", t);
}
}

private void recordUserUriTemplate(HttpServletRequest request) {
final Trace trace = traceContext.currentRawTraceObject();
if (trace == null) {
return;
}
for (String attributeName : TomcatConstants.TOMCAT_URI_USER_INPUT_ATTRIBUTE_KEYS) {
final Object uriMapping = request.getAttribute(attributeName);
if (!(uriMapping instanceof String)) {
continue;
}

String uriTemplate = (String) uriMapping;
if (!StringUtils.hasLength(uriTemplate)) {
continue;
}

if (uriStatCollectMethod) {
uriTemplate = request.getMethod() + " " + uriTemplate;
}

final SpanRecorder spanRecorder = trace.getSpanRecorder();
spanRecorder.recordUriTemplate(uriTemplate, true);
}
}

private int getStatusCode(final HttpServletResponse response) {
try {
// Tomcat 6
Original file line number Diff line number Diff line change
@@ -18,6 +18,8 @@

import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig;
import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor;
import com.navercorp.pinpoint.bootstrap.context.SpanRecorder;
import com.navercorp.pinpoint.bootstrap.context.Trace;
import com.navercorp.pinpoint.bootstrap.context.TraceContext;
import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor;
import com.navercorp.pinpoint.bootstrap.logging.PLogger;
@@ -34,6 +36,7 @@
import com.navercorp.pinpoint.bootstrap.plugin.response.ServletResponseListenerBuilder;
import com.navercorp.pinpoint.bootstrap.util.argument.Validation;
import com.navercorp.pinpoint.bootstrap.util.argument.Validator;
import com.navercorp.pinpoint.common.util.StringUtils;
import com.navercorp.pinpoint.plugin.common.servlet.util.HttpServletRequestAdaptor;
import com.navercorp.pinpoint.plugin.common.servlet.util.HttpServletResponseAdaptor;
import com.navercorp.pinpoint.plugin.common.servlet.util.ParameterRecorderFactory;
@@ -58,14 +61,23 @@ public class StandardHostValveInvokeInterceptor implements AroundInterceptor {
private final ServletRequestListener<HttpServletRequest> servletRequestListener;
private final ServletResponseListener<HttpServletResponse> servletResponseListener;

private final TraceContext traceContext;
private final boolean uriStatEnable;
private final boolean uriStatUseUserInput;
private final boolean uriStatCollectMethod;


public StandardHostValveInvokeInterceptor(TraceContext traceContext, MethodDescriptor descriptor,
RequestRecorderFactory<HttpServletRequest> requestRecorderFactory) {
this.traceContext = traceContext;
this.methodDescriptor = descriptor;

this.validator = buildValidator();
final TomcatConfig config = new TomcatConfig(traceContext.getProfilerConfig());

this.uriStatEnable = config.isUriStatEnable();
this.uriStatUseUserInput = config.isUriStatUseUserInput();
this.uriStatCollectMethod = config.isUriStatCollectMethod();

RequestAdaptor<HttpServletRequest> requestAdaptor = new HttpServletRequestAdaptor();
ParameterRecorder<HttpServletRequest> parameterRecorder = ParameterRecorderFactory.newParameterRecorderFactory(config.getExcludeProfileMethodFilter(), config.isTraceRequestParam());
@@ -148,13 +160,41 @@ public void after(Object target, Object[] args, Object result, Throwable throwab
}
}
}
if (uriStatEnable && uriStatUseUserInput) {
recordUserUriTemplate(request);
}
this.servletResponseListener.destroyed(response, throwable, statusCode); //must before request listener due to trace block ending
this.servletRequestListener.destroyed(request, throwable, statusCode);
} catch (Throwable t) {
logger.info("Failed to servlet request event handle.", t);
}
}

private void recordUserUriTemplate(HttpServletRequest request) {
final Trace trace = traceContext.currentRawTraceObject();
if (trace == null) {
return;
}
for (String attributeName : TomcatConstants.TOMCAT_URI_USER_INPUT_ATTRIBUTE_KEYS) {
final Object uriMapping = request.getAttribute(attributeName);
if (!(uriMapping instanceof String)) {
continue;
}

String uriTemplate = (String) uriMapping;
if (!StringUtils.hasLength(uriTemplate)) {
continue;
}

if (uriStatCollectMethod) {
uriTemplate = request.getMethod() + " " + uriTemplate;
}

final SpanRecorder spanRecorder = trace.getSpanRecorder();
spanRecorder.recordUriTemplate(uriTemplate, true);
}
}

private int getStatusCode(final HttpServletResponse response) {
try {
// Tomcat 6

0 comments on commit 1cd7497

Please sign in to comment.