Skip to content
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

Add parameter to optionally strip deploy path. #639

Merged
merged 2 commits into from Jul 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Expand Up @@ -449,7 +449,10 @@ measuring is also configurable, via the `path-components` init parameter. By
default, the servlet filter will record each path differently, but by setting an
integer here, you can tell the filter to only record up to the Nth slashes. That
is, all requests with greater than N "/" characters in the servlet URI path will
be measured in the same bucket and you will lose that granularity.
be measured in the same bucket and you will lose that granularity. The init
parameter `strip-context-path` can be used to strip the leading part of the URL
which is part of the deploy context (i.e. the folder the servlet is deployed to),
so that the same servlet deployed to different paths can lead to similar metrics.

The code below is an example of the XML configuration for the filter. You will
need to place this (replace your own values) code in your
Expand Down Expand Up @@ -477,6 +480,11 @@ need to place this (replace your own values) code in your
<param-name>path-components</param-name>
<param-value>1</param-value>
</init-param>
<!-- strip-context-path is optional, defaults to false -->
<init-param>
<param-name>strip-context-path</param-name>
<param-value>false</param-value>
</init-param>
</filter>

<!-- You will most likely want this to be the first filter in the chain
Expand Down
Expand Up @@ -25,6 +25,10 @@
* (including servlet context path), but can be configured with the {@code path-components} init parameter. Any number
* provided that is less than 1 will provide the full path granularity (warning, this may affect performance).
*
* <p>The {@code strip-context-path} init parameter can be used to avoid including the leading path components which are
* part of the context (i.e. the folder where the servlet is deployed) so that the same project deployed under different
* paths can produce the same metrics.
*
* <p>The Histogram buckets can be configured with a {@code buckets} init parameter whose value is a comma-separated list
* of valid {@code double} values.
*
Expand All @@ -50,6 +54,11 @@
* <param-name>path-components</param-name>
* <param-value>0</param-value>
* </init-param>
* <!-- strip-context-path is optional, defaults to false -->
* <init-param>
* <param-name>strip-context-path</param-name>
* <param-value>false</param-value>
* </init-param>
* </filter>
* }</pre>
*
Expand All @@ -60,6 +69,7 @@ public class MetricsFilter implements Filter {
static final String HELP_PARAM = "help";
static final String METRIC_NAME_PARAM = "metric-name";
static final String BUCKET_CONFIG_PARAM = "buckets";
static final String STRIP_CONTEXT_PATH_PARAM = "strip-context-path";
static final String UNKNOWN_HTTP_STATUS_CODE = "";

private Histogram histogram = null;
Expand All @@ -68,6 +78,7 @@ public class MetricsFilter implements Filter {
// Package-level for testing purposes.
int pathComponents = 1;
private String metricName = null;
boolean stripContextPath = false;
private String help = "The time taken fulfilling servlet requests";
private double[] buckets = null;

Expand Down Expand Up @@ -145,6 +156,10 @@ public void init(FilterConfig filterConfig) throws ServletException {
buckets[i] = Double.parseDouble(bucketParams[i]);
}
}

if (!isEmpty(filterConfig.getInitParameter(STRIP_CONTEXT_PATH_PARAM))) {
stripContextPath = Boolean.parseBoolean(filterConfig.getInitParameter(STRIP_CONTEXT_PATH_PARAM));
}
}

if (buckets != null) {
Expand All @@ -171,6 +186,9 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
HttpServletRequest request = (HttpServletRequest) servletRequest;

String path = request.getRequestURI();
if (stripContextPath) {
path = path.substring(request.getContextPath().length());
}

String components = getComponents(path);
String method = request.getMethod();
Expand Down
Expand Up @@ -17,6 +17,7 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
Expand Down Expand Up @@ -231,4 +232,26 @@ public void testStatusCodeWithNonHttpServletResponse() throws Exception {
assertNotNull(sampleValue);
assertEquals(1, sampleValue, 0.0001);
}

@Test
public void testStripContextPath() throws Exception {
String metricName = "foo";
FilterConfig cfg = mock(FilterConfig.class);
when(cfg.getInitParameter(MetricsFilter.METRIC_NAME_PARAM)).thenReturn(metricName);
when(cfg.getInitParameter(MetricsFilter.PATH_COMPONENT_PARAM)).thenReturn("0");
when(cfg.getInitParameter(MetricsFilter.STRIP_CONTEXT_PATH_PARAM)).thenReturn("true");
f.init(cfg);
assertTrue(f.stripContextPath);
HttpServletRequest req = mock(HttpServletRequest.class);
when(req.getRequestURI()).thenReturn("/foo/bar/baz/bang");
when(req.getContextPath()).thenReturn("/foo/bar");
when(req.getMethod()).thenReturn(HttpMethods.GET);
HttpServletResponse res = mock(HttpServletResponse.class);
FilterChain c = mock(FilterChain.class);
f.doFilter(req, res, c);
verify(c).doFilter(req, res);
final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue(metricName + "_count", new String[]{"path", "method"}, new String[]{"/baz/bang", HttpMethods.GET});
assertNotNull(sampleValue);
assertEquals(1, sampleValue, 0.0001);
}
}