Skip to content
This repository was archived by the owner on Sep 6, 2025. It is now read-only.

Commit 1da281b

Browse files
BrowserMob 0 response metrics (#7)
* BrowserMob 0 response metrics * Fix failed tests * Fix metrics names * Release snapshot version
1 parent accde93 commit 1da281b

File tree

10 files changed

+54
-28
lines changed

10 files changed

+54
-28
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ When you build the latest code from source, you'll have access to the latest sna
395395
<dependency>
396396
<groupId>net.lightbody.bmp</groupId>
397397
<artifactId>browsermob-core</artifactId>
398-
<version>2.1.10-SNAPSHOT</version>
398+
<version>2.1.11-SNAPSHOT</version>
399399
<scope>test</scope>
400400
</dependency>
401401
```

browsermob-core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<artifactId>browsermob-proxy</artifactId>
88
<groupId>net.lightbody.bmp</groupId>
9-
<version>2.1.10-SNAPSHOT</version>
9+
<version>2.1.11-SNAPSHOT</version>
1010
</parent>
1111
<modelVersion>4.0.0</modelVersion>
1212

browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.google.common.collect.ImmutableList;
44
import com.google.common.io.BaseEncoding;
5+
import com.timgroup.statsd.NonBlockingStatsDClient;
6+
import com.timgroup.statsd.StatsDClient;
57
import io.netty.buffer.ByteBuf;
68
import io.netty.channel.ChannelHandlerContext;
79
import io.netty.handler.codec.http.HttpContent;
@@ -44,8 +46,12 @@
4446
import java.util.concurrent.TimeUnit;
4547
import java.util.concurrent.atomic.AtomicInteger;
4648

49+
import static net.lightbody.bmp.filters.StatsDMetricsFilter.*;
50+
import static net.lightbody.bmp.filters.StatsDMetricsFilter.getStatsDPort;
51+
4752
public class HarCaptureFilter extends HttpsAwareFiltersAdapter {
4853
private static final Logger log = LoggerFactory.getLogger(HarCaptureFilter.class);
54+
private static final StatsDClient statsDClient = new NonBlockingStatsDClient("automated_tests", getStatsDHost(), getStatsDPort());
4955

5056
/**
5157
* The currently active HAR at the time the current request is received.
@@ -123,16 +129,16 @@ public class HarCaptureFilter extends HttpsAwareFiltersAdapter {
123129
* <p/>
124130
* Regardless of the CaptureTypes specified in <code>dataToCapture</code>, the HarCaptureFilter will always capture:
125131
* <ul>
126-
* <li>Request and response sizes</li>
127-
* <li>HTTP request and status lines</li>
128-
* <li>Page timing information</li>
132+
* <li>Request and response sizes</li>
133+
* <li>HTTP request and status lines</li>
134+
* <li>Page timing information</li>
129135
* </ul>
130136
*
131137
* @param originalRequest the original HttpRequest from the HttpFiltersSource factory
132-
* @param har a reference to the ProxyServer's current HAR file at the time this request is received (can be null if HAR capture is not required)
133-
* @param currentPageRef the ProxyServer's currentPageRef at the time this request is received from the client
134-
* @param dataToCapture the data types to capture for this request. null or empty set indicates only basic information will be
135-
* captured (see {@link net.lightbody.bmp.proxy.CaptureType} for information on data collected for each CaptureType)
138+
* @param har a reference to the ProxyServer's current HAR file at the time this request is received (can be null if HAR capture is not required)
139+
* @param currentPageRef the ProxyServer's currentPageRef at the time this request is received from the client
140+
* @param dataToCapture the data types to capture for this request. null or empty set indicates only basic information will be
141+
* captured (see {@link net.lightbody.bmp.proxy.CaptureType} for information on data collected for each CaptureType)
136142
*/
137143
public HarCaptureFilter(HttpRequest originalRequest, ChannelHandlerContext ctx, Har har, String currentPageRef, Set<CaptureType> dataToCapture) {
138144
super(originalRequest, ctx);
@@ -199,6 +205,8 @@ public HttpResponse clientToProxyRequest(HttpObject httpObject) {
199205
HarResponse defaultHarResponse = HarCaptureUtil.createHarResponseForFailure();
200206
defaultHarResponse.setError(HarCaptureUtil.getNoResponseReceivedErrorMessage());
201207
harEntry.setResponse(defaultHarResponse);
208+
statsDClient.increment(getProxyPrefix().concat(prepareMetric(harEntry.getRequest().getUrl()))
209+
.concat("." + harEntry.getResponse().getStatus()).concat(".client_proxy_connection_fail"));
202210

203211
captureQueryParameters(httpRequest);
204212
// not capturing user agent: in many cases, it doesn't make sense to capture at the HarLog level, since the proxy could be
@@ -278,6 +286,8 @@ public void serverToProxyResponseTimedOut() {
278286
// replace any existing HarResponse that was created if the server sent a partial response
279287
HarResponse response = HarCaptureUtil.createHarResponseForFailure();
280288
harEntry.setResponse(response);
289+
statsDClient.increment(getProxyPrefix().concat(prepareMetric(harEntry.getRequest().getUrl()))
290+
.concat("." + harEntry.getResponse().getStatus()).concat(".response_timeout"));
281291

282292
response.setError(HarCaptureUtil.getResponseTimedOutErrorMessage());
283293

@@ -408,7 +418,7 @@ protected void captureRequestContent(HttpRequest httpRequest, byte[] fullMessage
408418

409419
Charset charset;
410420
try {
411-
charset = BrowserMobHttpUtil.readCharsetInContentTypeHeader(contentType);
421+
charset = BrowserMobHttpUtil.readCharsetInContentTypeHeader(contentType);
412422
} catch (UnsupportedCharsetException e) {
413423
log.warn("Found unsupported character set in Content-Type header '{}' in HTTP request to {}. Content will not be captured in HAR.", contentType, httpRequest.getUri(), e);
414424
return;
@@ -651,6 +661,8 @@ public InetSocketAddress proxyToServerResolutionStarted(String resolvingServerHo
651661
public void proxyToServerResolutionFailed(String hostAndPort) {
652662
HarResponse response = HarCaptureUtil.createHarResponseForFailure();
653663
harEntry.setResponse(response);
664+
statsDClient.increment(getProxyPrefix().concat(prepareMetric(harEntry.getRequest().getUrl()))
665+
.concat("." + harEntry.getResponse().getStatus()).concat(".server_resolution_fail"));
654666

655667
response.setError(HarCaptureUtil.getResolutionFailedErrorMessage(hostAndPort));
656668

@@ -692,6 +704,8 @@ public void proxyToServerConnectionStarted() {
692704
@Override
693705
public void proxyToServerConnectionFailed() {
694706
HarResponse response = HarCaptureUtil.createHarResponseForFailure();
707+
statsDClient.increment(getProxyPrefix().concat(prepareMetric(harEntry.getRequest().getUrl()))
708+
.concat("." + harEntry.getResponse().getStatus()).concat(".server_connection_fail"));
695709
harEntry.setResponse(response);
696710

697711
response.setError(HarCaptureUtil.getConnectionFailedErrorMessage());

browsermob-core/src/main/java/net/lightbody/bmp/filters/HttpConnectHarCaptureFilter.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package net.lightbody.bmp.filters;
22

33
import com.google.common.cache.CacheBuilder;
4+
import com.timgroup.statsd.NonBlockingStatsDClient;
5+
import com.timgroup.statsd.StatsDClient;
46
import io.netty.channel.ChannelHandlerContext;
57
import io.netty.handler.codec.http.HttpObject;
68
import io.netty.handler.codec.http.HttpRequest;
@@ -23,6 +25,8 @@
2325
import java.util.concurrent.ConcurrentMap;
2426
import java.util.concurrent.TimeUnit;
2527

28+
import static net.lightbody.bmp.filters.StatsDMetricsFilter.*;
29+
2630
/**
2731
* This filter captures HAR data for HTTP CONNECT requests. CONNECTs are "meta" requests that must be made before HTTPS
2832
* requests, but are not populated as separate requests in the HAR. Most information from HTTP CONNECTs (such as SSL
@@ -31,10 +35,10 @@
3135
* static methods. This filter also handles HTTP CONNECT errors and creates HAR entries for those errors, since there
3236
* would otherwise not be any record in the HAR of the error (if the CONNECT fails, there will be no subsequent "real"
3337
* request in which to record the error).
34-
*
3538
*/
3639
public class HttpConnectHarCaptureFilter extends HttpsAwareFiltersAdapter implements ModifiedRequestAwareFilter {
3740
private static final Logger log = LoggerFactory.getLogger(HttpConnectHarCaptureFilter.class);
41+
private static final StatsDClient statsDClient = new NonBlockingStatsDClient("automated_tests", getStatsDHost(), getStatsDPort());
3842

3943
/**
4044
* The currently active HAR at the time the current request is received.
@@ -104,7 +108,7 @@ public class HttpConnectHarCaptureFilter extends HttpsAwareFiltersAdapter implem
104108
/**
105109
* Stores SSL connection timing information from HTTP CONNNECT requests. This timing information is stored in the first HTTP request
106110
* after the CONNECT, not in the CONNECT itself, so it needs to be stored across requests.
107-
*
111+
* <p>
108112
* This is the only state stored across multiple requests.
109113
*/
110114
private static final ConcurrentMap<InetSocketAddress, HttpConnectTiming> httpConnectTimes =
@@ -330,6 +334,8 @@ private HarEntry createHarEntryForFailedCONNECT(String errorMessage) {
330334

331335
HarResponse response = HarCaptureUtil.createHarResponseForFailure();
332336
harEntry.setResponse(response);
337+
statsDClient.increment(getProxyPrefix().concat(prepareMetric(harEntry.getRequest().getUrl()))
338+
.concat("." + harEntry.getResponse().getStatus()).concat(".failed_connect_request"));
333339

334340
response.setError(errorMessage);
335341

browsermob-core/src/main/java/net/lightbody/bmp/filters/StatsDMetricsFilter.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,10 @@ public HttpObject serverToProxyResponse(HttpObject httpObject) {
4343
if (status > 399 || status == 0) {
4444
String metric;
4545
String url = HTTP_RESPONSE_STACK.pop();
46-
try {
47-
URI uri = new URI(url);
48-
metric = "proxy.".concat(
49-
prepareMetric(uri.getHost().concat(uri.getPath())).concat(String.format(".%s", status)));
50-
client.increment(metric);
51-
HTTP_RESPONSE_STACK.clear();
52-
} catch (URISyntaxException e) {
53-
e.printStackTrace();
54-
}
46+
metric = getProxyPrefix().concat(
47+
prepareMetric(url)).concat(String.format(".%s", status));
48+
client.increment(metric);
49+
HTTP_RESPONSE_STACK.clear();
5550
}
5651
}
5752
return super.serverToProxyResponse(httpObject);
@@ -65,8 +60,19 @@ public static int getStatsDPort() {
6560
return StringUtils.isEmpty(System.getenv("STATSD_PORT")) ? 8125 : NumberUtils.toInt(System.getenv("STATSD_PORT"));
6661
}
6762

68-
private String prepareMetric(String initialUrl) {
69-
return initialUrl.replaceAll("/", "_").replaceAll("\\.", "_");
63+
public static String getProxyPrefix() {
64+
return "proxy.";
65+
}
66+
67+
public static String prepareMetric(String initialUrl) {
68+
URI uri = null;
69+
try {
70+
uri = new URI(initialUrl);
71+
} catch (URISyntaxException e) {
72+
e.printStackTrace();
73+
}
74+
return uri.getHost().concat(uri.getPath()).replaceAll("/", "_")
75+
.replaceAll("\\.", "_");
7076
}
7177

7278
}

browsermob-dist/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<parent>
44
<artifactId>browsermob-proxy</artifactId>
55
<groupId>net.lightbody.bmp</groupId>
6-
<version>2.1.10-SNAPSHOT</version>
6+
<version>2.1.11-SNAPSHOT</version>
77
</parent>
88
<modelVersion>4.0.0</modelVersion>
99

browsermob-legacy/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<artifactId>browsermob-proxy</artifactId>
77
<groupId>net.lightbody.bmp</groupId>
8-
<version>2.1.10-SNAPSHOT</version>
8+
<version>2.1.11-SNAPSHOT</version>
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111

browsermob-rest/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<artifactId>browsermob-proxy</artifactId>
77
<groupId>net.lightbody.bmp</groupId>
8-
<version>2.1.10-SNAPSHOT</version>
8+
<version>2.1.11-SNAPSHOT</version>
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111

mitm/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<parent>
44
<artifactId>browsermob-proxy</artifactId>
55
<groupId>net.lightbody.bmp</groupId>
6-
<version>2.1.10-SNAPSHOT</version>
6+
<version>2.1.11-SNAPSHOT</version>
77
</parent>
88
<modelVersion>4.0.0</modelVersion>
99

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>net.lightbody.bmp</groupId>
55
<artifactId>browsermob-proxy</artifactId>
6-
<version>2.1.10-SNAPSHOT</version>
6+
<version>2.1.11-SNAPSHOT</version>
77
<modules>
88
<module>browsermob-core</module>
99
<module>browsermob-legacy</module>

0 commit comments

Comments
 (0)