Permalink
Browse files

POC using yammer metrics ( http://metrics.codahale.com ) in NX.

  • Loading branch information...
1 parent 20ebbdb commit 010d992c82d2e7567b2625af8d7b4941d272cb4f @jdillon jdillon committed Mar 19, 2013
View
@@ -257,6 +257,27 @@
<artifactId>javasimon-core</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.yammer.metrics</groupId>
+ <artifactId>metrics-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.yammer.metrics</groupId>
+ <artifactId>metrics-guice</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>com.yammer.metrics</groupId>
+ <artifactId>metrics-httpclient</artifactId>
+ </dependency>
+
<!-- Testing -->
<dependency>
<groupId>org.sonatype.nexus</groupId>
@@ -265,9 +265,8 @@ protected void configureProxy( final DefaultHttpClient httpClient, final RemoteP
* Sub-classed here to customize the http processor and to keep a sane logger name.
*/
private static class DefaultHttpClientImpl
- extends DefaultHttpClient
+ extends InstrumentedHttpClient
{
-
private DefaultHttpClientImpl( final ClientConnectionManager conman, final HttpParams params )
{
super( conman, params );
@@ -18,6 +18,7 @@
import javax.inject.Named;
import javax.inject.Singleton;
+import com.yammer.metrics.httpclient.InstrumentedClientConnManager;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.conn.scheme.PlainSocketFactory;
@@ -275,7 +276,7 @@ protected PoolingClientConnectionManager createClientConnectionManager(
schemeRegistry.register( new Scheme( "http", 80, PlainSocketFactory.getSocketFactory() ) );
schemeRegistry.register( new Scheme( "https", 443, SSLSocketFactory.getSocketFactory() ) );
- final PoolingClientConnectionManager connManager = new PoolingClientConnectionManager( schemeRegistry )
+ final PoolingClientConnectionManager connManager = new InstrumentedClientConnManager( schemeRegistry )
{
@Override
protected ClientConnectionOperator createConnectionOperator( final SchemeRegistry defaultSchemeRegistry )
@@ -0,0 +1,74 @@
+package org.sonatype.nexus.apachehttpclient;
+
+import com.yammer.metrics.Metrics;
+import com.yammer.metrics.core.MetricsRegistry;
+import com.yammer.metrics.httpclient.InstrumentedClientConnManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.client.*;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
+import org.apache.http.conn.routing.HttpRoutePlanner;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestExecutor;
+
+// NOTE: Duplicated and augmented from original 2.2.0 source to change signature of CTOR ClientConnectionManager parameter
+// NOTE: Should get this changes into metrics-httpclient and avoid needing this
+
+public class InstrumentedHttpClient extends DefaultHttpClient {
+ private final Log log = LogFactory.getLog(getClass());
+
+ private final MetricsRegistry registry;
+
+ public InstrumentedHttpClient(MetricsRegistry registry,
+ ClientConnectionManager manager,
+ HttpParams params) {
+ super(manager, params);
+ this.registry = registry;
+ }
+
+ public InstrumentedHttpClient(ClientConnectionManager manager, HttpParams params) {
+ this(Metrics.defaultRegistry(), manager, params);
+ }
+
+ public InstrumentedHttpClient(HttpParams params) {
+ this(new InstrumentedClientConnManager(), params);
+ }
+
+ public InstrumentedHttpClient() {
+ this(null);
+ }
+
+ @Override
+ protected RequestDirector createClientRequestDirector(HttpRequestExecutor requestExec,
+ ClientConnectionManager conman,
+ ConnectionReuseStrategy reustrat,
+ ConnectionKeepAliveStrategy kastrat,
+ HttpRoutePlanner rouplan,
+ HttpProcessor httpProcessor,
+ HttpRequestRetryHandler retryHandler,
+ RedirectStrategy redirectStrategy,
+ AuthenticationStrategy targetAuthStrategy,
+ AuthenticationStrategy proxyAuthStrategy,
+ UserTokenHandler userTokenHandler,
+ HttpParams params) {
+ return new InstrumentedRequestDirector(
+ registry,
+ log,
+ requestExec,
+ conman,
+ reustrat,
+ kastrat,
+ rouplan,
+ httpProcessor,
+ retryHandler,
+ redirectStrategy,
+ targetAuthStrategy,
+ proxyAuthStrategy,
+ userTokenHandler,
+ params);
+ }
+}
@@ -0,0 +1,116 @@
+package org.sonatype.nexus.apachehttpclient;
+
+import com.yammer.metrics.core.MetricsRegistry;
+import com.yammer.metrics.core.Timer;
+import com.yammer.metrics.core.TimerContext;
+import org.apache.commons.logging.Log;
+import org.apache.http.*;
+import org.apache.http.client.*;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
+import org.apache.http.conn.routing.HttpRoutePlanner;
+import org.apache.http.impl.client.DefaultRequestDirector;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestExecutor;
+
+import java.io.IOException;
+
+// NOTE: Duplicated and unchanged from original 2.2.0 source to support change in InstrumentedHttpClient
+// NOTE: Should get this changes into metrics-httpclient and avoid needing this
+
+class InstrumentedRequestDirector
+ extends DefaultRequestDirector {
+ private final static String GET = "GET", POST = "POST", HEAD = "HEAD", PUT = "PUT",
+ OPTIONS = "OPTIONS", DELETE = "DELETE", TRACE = "TRACE",
+ CONNECT = "CONNECT", MOVE = "MOVE", PATCH = "PATCH";
+
+ private final Timer getTimer;
+ private final Timer postTimer;
+ private final Timer headTimer;
+ private final Timer putTimer;
+ private final Timer deleteTimer;
+ private final Timer optionsTimer;
+ private final Timer traceTimer;
+ private final Timer connectTimer;
+ private final Timer moveTimer;
+ private final Timer patchTimer;
+ private final Timer otherTimer;
+
+ InstrumentedRequestDirector(MetricsRegistry registry,
+ Log log,
+ HttpRequestExecutor requestExec,
+ ClientConnectionManager conman,
+ ConnectionReuseStrategy reustrat,
+ ConnectionKeepAliveStrategy kastrat,
+ HttpRoutePlanner rouplan,
+ HttpProcessor httpProcessor,
+ HttpRequestRetryHandler retryHandler,
+ RedirectStrategy redirectStrategy,
+ AuthenticationStrategy targetAuthStrategy,
+ AuthenticationStrategy proxyAuthStrategy,
+ UserTokenHandler userTokenHandler,
+ HttpParams params) {
+ super(log,
+ requestExec,
+ conman,
+ reustrat,
+ kastrat,
+ rouplan,
+ httpProcessor,
+ retryHandler,
+ redirectStrategy,
+ targetAuthStrategy,
+ proxyAuthStrategy,
+ userTokenHandler,
+ params);
+ getTimer = registry.newTimer(HttpClient.class, "get-requests");
+ postTimer = registry.newTimer(HttpClient.class, "post-requests");
+ headTimer = registry.newTimer(HttpClient.class, "head-requests");
+ putTimer = registry.newTimer(HttpClient.class, "put-requests");
+ deleteTimer = registry.newTimer(HttpClient.class, "delete-requests");
+ optionsTimer = registry.newTimer(HttpClient.class, "options-requests");
+ traceTimer = registry.newTimer(HttpClient.class, "trace-requests");
+ connectTimer = registry.newTimer(HttpClient.class, "connect-requests");
+ moveTimer = registry.newTimer(HttpClient.class, "move-requests");
+ patchTimer = registry.newTimer(HttpClient.class, "patch-requests");
+ otherTimer = registry.newTimer(HttpClient.class, "other-requests");
+ }
+
+ @Override
+ public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException, IOException {
+ final TimerContext timerContext = timer(request).time();
+ try {
+ return super.execute(target, request, context);
+ } finally {
+ timerContext.stop();
+ }
+ }
+
+ private Timer timer(HttpRequest request) {
+ final String method = request.getRequestLine().getMethod();
+ if (GET.equalsIgnoreCase(method)) {
+ return getTimer;
+ } else if (POST.equalsIgnoreCase(method)) {
+ return postTimer;
+ } else if (PUT.equalsIgnoreCase(method)) {
+ return putTimer;
+ } else if (HEAD.equalsIgnoreCase(method)) {
+ return headTimer;
+ } else if (DELETE.equalsIgnoreCase(method)) {
+ return deleteTimer;
+ } else if (OPTIONS.equalsIgnoreCase(method)) {
+ return optionsTimer;
+ } else if (TRACE.equalsIgnoreCase(method)) {
+ return traceTimer;
+ } else if (CONNECT.equalsIgnoreCase(method)) {
+ return connectTimer;
+ } else if (PATCH.equalsIgnoreCase(method)) {
+ return patchTimer;
+ } else if (MOVE.equalsIgnoreCase(method)) {
+ return moveTimer;
+ }
+ return otherTimer;
+ }
+}
@@ -14,6 +14,7 @@
package org.sonatype.nexus.guice;
import com.google.inject.AbstractModule;
+import com.yammer.metrics.guice.InstrumentationModule;
import org.apache.shiro.guice.aop.ShiroAopModule;
import org.sonatype.nexus.timing.TimingModule;
@@ -33,7 +34,8 @@
@Override
protected void configure() {
install(new ShiroAopModule());
- install(new TimingModule());
+ //install(new TimingModule());
+ install(new InstrumentationModule());
}
}
@@ -30,6 +30,7 @@
import javax.inject.Named;
import javax.inject.Singleton;
+import com.yammer.metrics.annotation.Timed;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
@@ -132,6 +133,7 @@ public DefaultNexusPluginManager( final RepositoryTypeRegistry repositoryTypeReg
return new HashMap<GAVCoordinate, PluginResponse>( pluginResponses );
}
+ @Timed
public Collection<PluginManagerResponse> activateInstalledPlugins()
{
final List<PluginManagerResponse> result = new ArrayList<PluginManagerResponse>();
@@ -23,6 +23,7 @@
<pattern>${appender.pattern}</pattern>
</encoder>
</appender>
+
<appender name="logfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${appender.file}</File>
<Append>true</Append>
@@ -34,6 +35,8 @@
</rollingPolicy>
</appender>
+ <appender name="metrics" class="com.yammer.metrics.logback.InstrumentedAppender"/>
+
<logger name="org.sonatype.nexus.rest.NexusApplication" level="WARN" />
<logger name="httpclient" level="INFO" />
<logger name="org.apache.http" level="INFO" />
@@ -47,6 +50,7 @@
<root level="${root.level}">
<appender-ref ref="console" />
<appender-ref ref="logfile" />
+ <appender-ref ref="metrics" />
</root>
</included>
View
@@ -123,6 +123,21 @@
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>com.yammer.metrics</groupId>
+ <artifactId>metrics-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.yammer.metrics</groupId>
+ <artifactId>metrics-jetty</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.yammer.metrics</groupId>
+ <artifactId>metrics-logback</artifactId>
+ </dependency>
</dependencies>
<build>
@@ -106,6 +106,7 @@
<exclude>WEB-INF/lib/logback-core*.jar</exclude>
<exclude>WEB-INF/lib/logback-classic*.jar</exclude>
<exclude>WEB-INF/lib/nexus-logging-extras-appender*.jar</exclude>
+ <exclude>WEB-INF/lib/metrics-core*.jar</exclude>
<exclude>WEB-INF/classes/logback.xml</exclude>
</excludes>
</unpackOptions>
@@ -128,6 +129,9 @@
<include>org.sonatype.appcontext:*</include>
<include>org.slf4j:*</include>
<include>ch.qos.logback:*</include>
+ <include>com.yammer.metrics:metrics-core</include>
+ <include>com.yammer.metrics:metrics-jetty</include>
+ <include>com.yammer.metrics:metrics-logback</include>
</includes>
</dependencySet>
</dependencySets>
@@ -24,13 +24,14 @@
<!-- ============================================================ -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Set name="threadPool">
- <New class="org.sonatype.sisu.jetty.thread.InstrumentedQueuedThreadPool"/>
+ <New class="com.yammer.metrics.jetty.InstrumentedQueuedThreadPool"/>
</Set>
<Call name="addConnector">
<Arg>
- <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
- <Set name="host">${application-host}</Set>
- <Set name="port">${application-port}</Set>
+ <New class="com.yammer.metrics.jetty.InstrumentedSelectChannelConnector">
+ <Arg type="int">${application-port}</Arg>
+ <!--<Set name="host">${application-host}</Set>-->
+ <!--<Set name="port">${application-port}</Set>-->
</New>
</Arg>
</Call>
View
@@ -72,6 +72,16 @@
<artifactId>nexus-core</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.yammer.metrics</groupId>
+ <artifactId>metrics-servlet</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.yammer.metrics</groupId>
+ <artifactId>metrics-web</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-oss-edition</artifactId>
Oops, something went wrong.

0 comments on commit 010d992

Please sign in to comment.