You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by su...@apache.org on 2016/11/10 21:10:43 UTC

knox git commit: KNOX-643 Initial metrics api and implementation

Repository: knox
Updated Branches:
  refs/heads/master c6aa4700a -> f345f8895


KNOX-643 Initial metrics api and implementation


Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/f345f889
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/f345f889
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/f345f889

Branch: refs/heads/master
Commit: f345f889508306c739b15c49a462b3d1d838768a
Parents: c6aa470
Author: Sumit Gupta <su...@apache.org>
Authored: Thu Nov 10 16:09:57 2016 -0500
Committer: Sumit Gupta <su...@apache.org>
Committed: Thu Nov 10 16:10:35 2016 -0500

----------------------------------------------------------------------
 gateway-server/pom.xml                          |   8 ++
 .../apache/hadoop/gateway/GatewayMessages.java  |   9 ++
 .../apache/hadoop/gateway/GatewayServlet.java   |  20 ++-
 .../gateway/config/impl/GatewayConfigImpl.java  |  44 +++++-
 .../gateway/deploy/DeploymentFactory.java       |   1 -
 .../services/DefaultGatewayServices.java        |  14 ++
 .../metrics/impl/DefaultMetricsContext.java     |  49 +++++++
 .../metrics/impl/DefaultMetricsService.java     | 142 +++++++++++++++++++
 .../impl/instr/InstrGatewayFilterProvider.java  |  37 +++++
 .../InstrGatewayFilterProviderDescriptor.java   |  40 ++++++
 .../instr/InstrHttpClientBuilderProvider.java   |  70 +++++++++
 .../InstrHttpClientProviderDescriptor.java      |  40 ++++++
 .../impl/instr/InstrumentedGatewayFilter.java   |  99 +++++++++++++
 .../impl/reporters/AbstractMetricsReporter.java |  33 +++++
 .../impl/reporters/GraphiteMetricsReporter.java |  69 +++++++++
 .../impl/reporters/JmxMetricsReporter.java      |  56 ++++++++
 ...es.metrics.InstrumentationProviderDescriptor |  20 +++
 ...oop.gateway.services.metrics.MetricsReporter |  20 +++
 .../config/impl/GatewayConfigImplTest.java      |  11 ++
 .../metrics/impl/DefaultMetricsServiceTest.java |  80 +++++++++++
 gateway-spi/pom.xml                             |   9 ++
 .../hadoop/gateway/config/GatewayConfig.java    |  12 ++
 .../dispatch/DefaultHttpClientFactory.java      |  14 +-
 .../gateway/services/GatewayServices.java       |   1 +
 .../metrics/InstrumentationProvider.java        |  26 ++++
 .../InstrumentationProviderDescriptor.java      |  25 ++++
 .../services/metrics/MetricsContext.java        |  27 ++++
 .../services/metrics/MetricsReporter.java       |  33 +++++
 .../metrics/MetricsReporterException.java       |  29 ++++
 .../services/metrics/MetricsService.java        |  28 ++++
 .../hadoop/gateway/GatewayTestConfig.java       |  30 ++++
 .../hadoop/gateway/GatewayTestConfig.java       |  30 ++++
 pom.xml                                         |  24 +++-
 33 files changed, 1142 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-server/pom.xml b/gateway-server/pom.xml
index 5094958..01bc1a9 100644
--- a/gateway-server/pom.xml
+++ b/gateway-server/pom.xml
@@ -195,6 +195,14 @@
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-graphite</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-jetty9</artifactId>
+        </dependency>
 
         <!--
         These dependencies (jetty-annotations, apache-jsp, apache-jstl) are required for JSP support.

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
index 93dc68f..908589d 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
@@ -424,4 +424,13 @@ public interface GatewayMessages {
 
   @Message( level = MessageLevel.DEBUG, text = "Failed to parse path into Template: {0} : {1}" )
   void failedToParsePath( String path, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+  @Message( level = MessageLevel.DEBUG, text = "Failed to initialize metrics reporter {0}  : {1}" )
+  void failedToInitializeReporter( String name,  @StackTrace( level = MessageLevel.DEBUG ) Exception e);
+
+  @Message( level = MessageLevel.DEBUG, text = "Failed to start metrics reporter {0}  : {1}" )
+  void failedToStartReporter( String name,  @StackTrace( level = MessageLevel.DEBUG ) Exception e);
+
+  @Message( level = MessageLevel.DEBUG, text = "Failed to stop metrics reporter {0}  : {1}" )
+  void failedToStopReporter( String name,  @StackTrace( level = MessageLevel.DEBUG ) Exception e);
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java
index cb9f7a5..d3339ab 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java
@@ -40,11 +40,14 @@ import org.apache.hadoop.gateway.audit.api.AuditServiceFactory;
 import org.apache.hadoop.gateway.audit.api.Auditor;
 import org.apache.hadoop.gateway.audit.api.ResourceType;
 import org.apache.hadoop.gateway.audit.log4j.audit.AuditConstants;
+import org.apache.hadoop.gateway.config.GatewayConfig;
 import org.apache.hadoop.gateway.descriptor.GatewayDescriptor;
 import org.apache.hadoop.gateway.descriptor.GatewayDescriptorFactory;
 import org.apache.hadoop.gateway.filter.AbstractGatewayFilter;
 import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
 import org.apache.hadoop.gateway.i18n.resources.ResourcesFactory;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.metrics.MetricsService;
 
 public class GatewayServlet implements Servlet, Filter {
 
@@ -201,7 +204,7 @@ public class GatewayServlet implements Servlet, Filter {
     filter = null;
   }
 
-  private static GatewayFilter createFilter( InputStream stream ) throws ServletException {
+  private static GatewayFilter createFilter( InputStream stream, ServletContext servletContext ) throws ServletException {
     try {
       GatewayFilter filter = null;
       if( stream != null ) {
@@ -212,6 +215,17 @@ public class GatewayServlet implements Servlet, Filter {
           stream.close();
         }
       }
+      GatewayConfig gatewayConfig = (GatewayConfig) servletContext.getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+      if (gatewayConfig.isMetricsEnabled()) {
+        GatewayServices gatewayServices = (GatewayServices) servletContext.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+        MetricsService metricsService = gatewayServices.getService(GatewayServices.METRICS_SERVICE);
+        if (metricsService != null) {
+          GatewayFilter instrumentedFilter = metricsService.getInstrumented(filter);
+          if (instrumentedFilter != null) {
+            filter = instrumentedFilter;
+          }
+        }
+      }
       return filter;
     } catch( IOException e ) {
       throw new ServletException( e );
@@ -232,7 +246,7 @@ public class GatewayServlet implements Servlet, Filter {
     } else {
       stream = filterConfig.getServletContext().getResourceAsStream( GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
     }
-    filter = createFilter( stream );
+    filter = createFilter( stream, filterConfig.getServletContext());
     return filter;
   }
 
@@ -248,7 +262,7 @@ public class GatewayServlet implements Servlet, Filter {
     } else {
       stream = servletConfig.getServletContext().getResourceAsStream( GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
     }
-    filter = createFilter( stream );
+    filter = createFilter( stream, servletConfig.getServletContext());
     return filter;
   }
 

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
index d8349d8..8576c2e 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
@@ -130,6 +130,12 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
   public static final String HTTP_SERVER_RESPONSE_HEADER_BUFFER = GATEWAY_CONFIG_FILE_PREFIX + ".httpserver.responseHeaderBuffer";
   public static final String DEPLOYMENTS_BACKUP_VERSION_LIMIT =  GATEWAY_CONFIG_FILE_PREFIX + ".deployment.backup.versionLimit";
   public static final String DEPLOYMENTS_BACKUP_AGE_LIMIT =  GATEWAY_CONFIG_FILE_PREFIX + ".deployment.backup.ageLimit";
+  public static final String METRICS_ENABLED = GATEWAY_CONFIG_FILE_PREFIX + ".metrics.enabled";
+  public static final String JMX_METRICS_REPORTING_ENABLED = GATEWAY_CONFIG_FILE_PREFIX + ".jmx.metrics.reporting.enabled";
+  public static final String GRAPHITE_METRICS_REPORTING_ENABLED = GATEWAY_CONFIG_FILE_PREFIX + ".graphite.metrics.reporting.enabled";
+  public static final String GRAPHITE_METRICS_REPORTING_HOST = GATEWAY_CONFIG_FILE_PREFIX + ".graphite.metrics.reporting.host";
+  public static final String GRAPHITE_METRICS_REPORTING_PORT = GATEWAY_CONFIG_FILE_PREFIX + ".graphite.metrics.reporting.port";
+  public static final String GRAPHITE_METRICS_REPORTING_FREQUENCY = GATEWAY_CONFIG_FILE_PREFIX + ".graphite.metrics.reporting.frequency";
 
   /* @since 0.10 Websocket config variables */
   public static final String WEBSOCKET_FEATURE_ENABLED =  GATEWAY_CONFIG_FILE_PREFIX + ".websocket.feature.enabled";
@@ -651,6 +657,42 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
     return DEFAULT_GLOBAL_RULES_SERVICES;
   }
 
+  @Override
+  public boolean isMetricsEnabled() {
+    String metricsEnabled = get( METRICS_ENABLED, "true" );
+    return "true".equals(metricsEnabled);
+  }
+
+  @Override
+  public boolean isJmxMetricsReportingEnabled() {
+    String enabled = get( JMX_METRICS_REPORTING_ENABLED, "true" );
+    return "true".equals(enabled);
+  }
+
+  @Override
+  public boolean isGraphiteMetricsReportingEnabled() {
+    String enabled = get( GRAPHITE_METRICS_REPORTING_ENABLED, "false" );
+    return "true".equals(enabled);
+  }
+
+  @Override
+  public String getGraphiteHost() {
+    String host = get( GRAPHITE_METRICS_REPORTING_HOST, "localhost" );
+    return host;
+  }
+
+  @Override
+  public int getGraphitePort() {
+    int i = getInt( GRAPHITE_METRICS_REPORTING_PORT, 32772 );
+    return i;
+  }
+
+  @Override
+  public int getGraphiteReportingFrequency() {
+    int i = getInt( GRAPHITE_METRICS_REPORTING_FREQUENCY, 1 );
+    return i;
+  }
+
   /* (non-Javadoc)
    * @see org.apache.hadoop.gateway.config.GatewayConfig#isWebsocketEnabled()
    */
@@ -716,7 +758,7 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
     return getInt( WEBSOCKET_IDLE_TIMEOUT, DEFAULT_WEBSOCKET_IDLE_TIMEOUT);
   }
 
-  private static long parseNetworkTimeout( String s ) {
+  private static long parseNetworkTimeout(String s ) {
     PeriodFormatter f = new PeriodFormatterBuilder()
         .appendMinutes().appendSuffix("m"," min")
         .appendSeconds().appendSuffix("s"," sec")

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java
index d30cb33..e616501 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java
@@ -48,7 +48,6 @@ import org.apache.hadoop.gateway.services.registry.ServiceRegistry;
 import org.apache.hadoop.gateway.topology.Application;
 import org.apache.hadoop.gateway.topology.Provider;
 import org.apache.hadoop.gateway.topology.Service;
-import org.apache.hadoop.gateway.topology.Service;
 import org.apache.hadoop.gateway.topology.Topology;
 import org.apache.hadoop.gateway.topology.Version;
 import org.apache.hadoop.gateway.util.ServiceDefinitionsLoader;

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/DefaultGatewayServices.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/DefaultGatewayServices.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/DefaultGatewayServices.java
index 1024d7f..2cf043e 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/DefaultGatewayServices.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/DefaultGatewayServices.java
@@ -24,6 +24,7 @@ import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor;
 import org.apache.hadoop.gateway.descriptor.ResourceDescriptor;
 import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
 import org.apache.hadoop.gateway.services.registry.impl.DefaultServiceDefinitionRegistry;
+import org.apache.hadoop.gateway.services.metrics.impl.DefaultMetricsService;
 import org.apache.hadoop.gateway.services.topology.impl.DefaultTopologyService;
 import org.apache.hadoop.gateway.services.hostmap.impl.DefaultHostMapperService;
 import org.apache.hadoop.gateway.services.registry.impl.DefaultServiceRegistryService;
@@ -110,6 +111,12 @@ public class DefaultGatewayServices implements GatewayServices {
     DefaultServiceDefinitionRegistry sdr = new DefaultServiceDefinitionRegistry();
     sdr.init( config, options );
     services.put( SERVICE_DEFINITION_REGISTRY, sdr );
+    tops.init( config, options );
+    services.put( TOPOLOGY_SERVICE, tops );
+
+    DefaultMetricsService metricsService = new DefaultMetricsService();
+    metricsService.init( config, options );
+    services.put( METRICS_SERVICE, metricsService );
   }
   
   public void start() throws ServiceLifecycleException {
@@ -128,6 +135,9 @@ public class DefaultGatewayServices implements GatewayServices {
 
     DefaultTopologyService tops = (DefaultTopologyService)services.get(TOPOLOGY_SERVICE);
     tops.start();
+
+    DefaultMetricsService metricsService = (DefaultMetricsService) services.get(METRICS_SERVICE);
+    metricsService.start();
   }
 
   public void stop() throws ServiceLifecycleException {
@@ -146,6 +156,10 @@ public class DefaultGatewayServices implements GatewayServices {
 
     DefaultTopologyService tops = (DefaultTopologyService)services.get(TOPOLOGY_SERVICE);
     tops.stop();
+
+    DefaultMetricsService metricsService = (DefaultMetricsService) services.get(METRICS_SERVICE);
+    metricsService.stop();
+
   }
   
   /* (non-Javadoc)

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsContext.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsContext.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsContext.java
new file mode 100644
index 0000000..18891d0
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsContext.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl;
+
+import org.apache.hadoop.gateway.services.metrics.MetricsContext;
+import org.apache.hadoop.gateway.services.metrics.MetricsService;
+
+import java.util.HashMap;
+
+public class DefaultMetricsContext implements MetricsContext {
+
+  private MetricsService metricsService;
+
+  private HashMap<String, Object> properties = new HashMap<>();
+
+  public DefaultMetricsContext(MetricsService metricsService) {
+    this.metricsService = metricsService;
+  }
+
+  @Override
+  public MetricsService getMetricsService() {
+    return metricsService;
+  }
+
+  @Override
+  public void setProperty(String name, Object value) {
+    properties.put(name, value);
+  }
+
+  @Override
+  public Object getProperty(String name) {
+    return properties.get(name);
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsService.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsService.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsService.java
new file mode 100644
index 0000000..0fa8a44
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsService.java
@@ -0,0 +1,142 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl;
+
+import com.codahale.metrics.MetricRegistry;
+import org.apache.hadoop.gateway.GatewayMessages;
+import org.apache.hadoop.gateway.config.GatewayConfig;
+import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
+import org.apache.hadoop.gateway.services.ServiceLifecycleException;
+import org.apache.hadoop.gateway.services.metrics.InstrumentationProvider;
+import org.apache.hadoop.gateway.services.metrics.InstrumentationProviderDescriptor;
+import org.apache.hadoop.gateway.services.metrics.MetricsContext;
+import org.apache.hadoop.gateway.services.metrics.MetricsReporter;
+import org.apache.hadoop.gateway.services.metrics.MetricsReporterException;
+import org.apache.hadoop.gateway.services.metrics.MetricsService;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+public class DefaultMetricsService implements MetricsService {
+  private static GatewayMessages LOG = MessagesFactory.get( GatewayMessages.class );
+
+  private final MetricRegistry metrics = new MetricRegistry();
+
+  public static final String METRICS_REGISTRY = "metrics-registry";
+
+  private Map<Class<?>, InstrumentationProvider> instrumentationProviders;
+
+  private ArrayList<MetricsReporter> metricsReporters;
+
+  private MetricsContext context;
+
+  public MetricRegistry getMetricRegistry() {
+    return metrics;
+  }
+
+  @Override
+  public void init(GatewayConfig config, Map<String, String> options) throws ServiceLifecycleException {
+    context = new DefaultMetricsContext(this);
+    context.setProperty(METRICS_REGISTRY, getMetricRegistry());
+    instrumentationProviders = new HashMap<>();
+    metricsReporters = new ArrayList<>();
+    loadInstrumentationProviders();
+    loadAndInitReporters(config);
+  }
+
+  private void loadInstrumentationProviders() {
+    ServiceLoader<InstrumentationProviderDescriptor> descriptors = ServiceLoader.load(InstrumentationProviderDescriptor.class);
+    Iterator<InstrumentationProviderDescriptor> descriptorIterator = descriptors.iterator();
+    while ( descriptorIterator.hasNext() ) {
+      instrumentationProviders.putAll(descriptorIterator.next().providesInstrumentation());
+    }
+  }
+
+  private void loadAndInitReporters(GatewayConfig config) {
+    ServiceLoader<MetricsReporter> reporters = ServiceLoader.load(MetricsReporter.class);
+    Iterator<MetricsReporter> reportersIterator = reporters.iterator();
+    while ( reportersIterator.hasNext() ) {
+      MetricsReporter metricsReporter = reportersIterator.next();
+      try {
+        metricsReporter.init(config);
+        metricsReporters.add(metricsReporter);
+      } catch ( MetricsReporterException e ) {
+        LOG.failedToInitializeReporter(metricsReporter.getName(), e);
+      }
+    }
+  }
+
+  @Override
+  public void start() throws ServiceLifecycleException {
+    for (MetricsReporter reporter : metricsReporters) {
+      if ( reporter.isEnabled() ) {
+        try {
+          reporter.start(context);
+        } catch ( MetricsReporterException e ) {
+          LOG.failedToStartReporter(reporter.getName(), e);
+        }
+      }
+    }
+  }
+
+  @Override
+  public void stop() throws ServiceLifecycleException {
+    for (MetricsReporter reporter : metricsReporters) {
+      if (reporter.isEnabled()) {
+        try {
+          reporter.stop();
+        } catch ( MetricsReporterException e ) {
+          LOG.failedToStopReporter(reporter.getName(), e);
+        }
+      }
+    }
+  }
+
+  @Override
+  public <T> T getInstrumented(T instanceClass) {
+    InstrumentationProvider<T> instrumentationProvider = instrumentationProviders.get(instanceClass.getClass());
+    if (instrumentationProvider == null) {
+      return null;
+    }
+    return instrumentationProvider.getInstrumented(instanceClass, context);
+  }
+
+  @Override
+  public <T> T getInstrumented(Class<T> clazz) {
+    InstrumentationProvider<T> instrumentationProvider = instrumentationProviders.get(clazz);
+    if (instrumentationProvider == null) {
+      return null;
+    }
+    return instrumentationProvider.getInstrumented(context);
+  }
+
+  public Map<Class<?>, InstrumentationProvider> getInstrumentationProviders() {
+    return instrumentationProviders;
+  }
+
+  public ArrayList<MetricsReporter> getMetricsReporters() {
+    return metricsReporters;
+  }
+
+  public MetricsContext getContext() {
+    return context;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrGatewayFilterProvider.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrGatewayFilterProvider.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrGatewayFilterProvider.java
new file mode 100644
index 0000000..9dec9cf
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrGatewayFilterProvider.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl.instr;
+
+import com.codahale.metrics.MetricRegistry;
+import org.apache.hadoop.gateway.GatewayFilter;
+import org.apache.hadoop.gateway.services.metrics.InstrumentationProvider;
+import org.apache.hadoop.gateway.services.metrics.MetricsContext;
+import org.apache.hadoop.gateway.services.metrics.impl.DefaultMetricsService;
+
+public class InstrGatewayFilterProvider implements InstrumentationProvider<GatewayFilter> {
+
+  @Override
+  public GatewayFilter getInstrumented(MetricsContext metricsContext) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public GatewayFilter getInstrumented(GatewayFilter gatewayFilter, MetricsContext metricsContext) {
+    return new InstrumentedGatewayFilter(gatewayFilter, (MetricRegistry) metricsContext.getProperty(DefaultMetricsService.METRICS_REGISTRY));
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrGatewayFilterProviderDescriptor.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrGatewayFilterProviderDescriptor.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrGatewayFilterProviderDescriptor.java
new file mode 100644
index 0000000..5383f04
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrGatewayFilterProviderDescriptor.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl.instr;
+
+import org.apache.hadoop.gateway.GatewayFilter;
+import org.apache.hadoop.gateway.services.metrics.InstrumentationProvider;
+import org.apache.hadoop.gateway.services.metrics.InstrumentationProviderDescriptor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class InstrGatewayFilterProviderDescriptor implements InstrumentationProviderDescriptor {
+
+  private HashMap<Class<?>, InstrumentationProvider> providers;
+
+  public InstrGatewayFilterProviderDescriptor() {
+    providers = new HashMap<>();
+    providers.put(GatewayFilter.class, new InstrGatewayFilterProvider());
+  }
+
+  @Override
+  public Map<Class<?>, InstrumentationProvider> providesInstrumentation() {
+    return providers;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
new file mode 100644
index 0000000..d85687b
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl.instr;
+
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.httpclient.HttpClientMetricNameStrategy;
+import com.codahale.metrics.httpclient.InstrumentedHttpClientConnectionManager;
+import com.codahale.metrics.httpclient.InstrumentedHttpRequestExecutor;
+import org.apache.hadoop.gateway.services.metrics.InstrumentationProvider;
+import org.apache.hadoop.gateway.services.metrics.MetricsContext;
+import org.apache.hadoop.gateway.services.metrics.impl.DefaultMetricsService;
+import org.apache.http.Header;
+import org.apache.http.HttpRequest;
+import org.apache.http.RequestLine;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+
+import java.net.URISyntaxException;
+
+public class InstrHttpClientBuilderProvider implements InstrumentationProvider<HttpClientBuilder> {
+
+  @Override
+  public HttpClientBuilder getInstrumented(MetricsContext metricsContext) {
+    MetricRegistry registry = (MetricRegistry) metricsContext.getProperty(DefaultMetricsService.METRICS_REGISTRY);
+    return  HttpClientBuilder.create().setRequestExecutor(new InstrumentedHttpRequestExecutor(registry, TOPOLOGY_URL_AND_METHOD)).
+        setConnectionManager(new InstrumentedHttpClientConnectionManager(registry));
+  }
+
+  @Override
+  public HttpClientBuilder getInstrumented(HttpClientBuilder instanceClass, MetricsContext metricsContext) {
+    throw new UnsupportedOperationException();
+  }
+
+  private static final HttpClientMetricNameStrategy TOPOLOGY_URL_AND_METHOD = new HttpClientMetricNameStrategy() {
+    public String getNameFor(String name, HttpRequest request) {
+      try {
+        String context = "";
+        Header header = request.getFirstHeader("X-Forwarded-Context");
+        if (header != null) {
+          context = header.getValue();
+        }
+        RequestLine requestLine = request.getRequestLine();
+        URIBuilder uriBuilder = new URIBuilder(requestLine.getUri());
+        return MetricRegistry.name("service", new String[]{name, context + uriBuilder.removeQuery().build().toString(), methodNameString(request)});
+      } catch (URISyntaxException e) {
+        throw new IllegalArgumentException(e);
+      }
+    }
+
+    private String methodNameString(HttpRequest request) {
+      return request.getRequestLine().getMethod().toLowerCase() + "-requests";
+    }
+  };
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientProviderDescriptor.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientProviderDescriptor.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientProviderDescriptor.java
new file mode 100644
index 0000000..0f41adf
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientProviderDescriptor.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl.instr;
+
+import org.apache.hadoop.gateway.services.metrics.InstrumentationProvider;
+import org.apache.hadoop.gateway.services.metrics.InstrumentationProviderDescriptor;
+import org.apache.http.impl.client.HttpClientBuilder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class InstrHttpClientProviderDescriptor implements InstrumentationProviderDescriptor {
+
+  private HashMap<Class<?>, InstrumentationProvider> providers;
+
+  public InstrHttpClientProviderDescriptor() {
+    providers = new HashMap<>();
+    providers.put(HttpClientBuilder.class, new InstrHttpClientBuilderProvider());
+  }
+
+  @Override
+  public Map<Class<?>, InstrumentationProvider> providesInstrumentation() {
+    return providers;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrumentedGatewayFilter.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrumentedGatewayFilter.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrumentedGatewayFilter.java
new file mode 100644
index 0000000..a3c75f6
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrumentedGatewayFilter.java
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl.instr;
+
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Timer;
+import org.apache.hadoop.gateway.GatewayFilter;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Map;
+
+public class InstrumentedGatewayFilter extends GatewayFilter {
+
+  private GatewayFilter gatewayFilter;
+
+  private MetricRegistry metricRegistry;
+
+  public InstrumentedGatewayFilter(GatewayFilter gatewayFilter, MetricRegistry metricRegistry) {
+    this.gatewayFilter = gatewayFilter;
+    this.metricRegistry = metricRegistry;
+  }
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+    gatewayFilter.init(filterConfig);
+  }
+
+  @Override
+  public void destroy() {
+    gatewayFilter.destroy();
+  }
+
+  @Override
+  public void addFilter(String path, String name, Filter filter, Map<String, String> params, String resourceRole) throws URISyntaxException {
+    gatewayFilter.addFilter(path, name, filter, params, resourceRole);
+  }
+
+  @Override
+  public void addFilter(String path, String name, String clazz, Map<String, String> params, String resourceRole) throws URISyntaxException {
+    gatewayFilter.addFilter(path, name, clazz, params, resourceRole);
+  }
+
+  @Override
+  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+    Timer.Context timerContext = this.timer(servletRequest).time();
+    try {
+      gatewayFilter.doFilter(servletRequest, servletResponse, filterChain);
+    } finally {
+      timerContext.stop();
+    }
+  }
+
+  @Override
+  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException {
+    Timer.Context timerContext = this.timer(servletRequest).time();
+    try {
+      gatewayFilter.doFilter(servletRequest, servletResponse);
+    } finally {
+      timerContext.stop();
+    }
+  }
+
+  private Timer timer(ServletRequest request) {
+    StringBuilder builder = new StringBuilder();
+    builder.append("client.");
+    builder.append(request.getServletContext().getContextPath());
+    if (request instanceof HttpServletRequest) {
+      HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+      builder.append(httpServletRequest.getPathInfo());
+      builder.append(".");
+      builder.append(httpServletRequest.getMethod());
+      builder.append("-requests");
+    }
+    return metricRegistry.timer(builder.toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/AbstractMetricsReporter.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/AbstractMetricsReporter.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/AbstractMetricsReporter.java
new file mode 100644
index 0000000..2e08c1a
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/AbstractMetricsReporter.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl.reporters;
+
+import org.apache.hadoop.gateway.services.metrics.MetricsReporter;
+
+public abstract class AbstractMetricsReporter implements MetricsReporter {
+  private boolean enabled = false;
+
+  public boolean isEnabled() {
+    return enabled;
+  }
+
+  public void setEnabled(boolean enabled) {
+    this.enabled = enabled;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/GraphiteMetricsReporter.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/GraphiteMetricsReporter.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/GraphiteMetricsReporter.java
new file mode 100644
index 0000000..660d9ba
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/GraphiteMetricsReporter.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl.reporters;
+
+import com.codahale.metrics.MetricFilter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.graphite.Graphite;
+import com.codahale.metrics.graphite.GraphiteReporter;
+import org.apache.hadoop.gateway.config.GatewayConfig;
+import org.apache.hadoop.gateway.services.metrics.MetricsContext;
+import org.apache.hadoop.gateway.services.metrics.MetricsReporterException;
+import org.apache.hadoop.gateway.services.metrics.impl.DefaultMetricsService;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
+
+public class GraphiteMetricsReporter extends AbstractMetricsReporter {
+
+  public static String NAME = "graphite-reporter";
+
+  private Graphite graphite;
+  private GraphiteReporter reporter;
+  private int reportingFrequency = 1;
+
+  @Override
+  public void init(GatewayConfig config) throws MetricsReporterException {
+    if (config.isMetricsEnabled() && config.isGraphiteMetricsReportingEnabled()) {
+      graphite = new Graphite(new InetSocketAddress(config.getGraphiteHost(), config.getGraphitePort()));
+      reportingFrequency = config.getGraphiteReportingFrequency();
+      setEnabled(true);
+    }
+  }
+
+  @Override
+  public void start(MetricsContext metricsContext) throws MetricsReporterException {
+    MetricRegistry registry = (MetricRegistry) metricsContext.getProperty(DefaultMetricsService.METRICS_REGISTRY);
+    reporter = GraphiteReporter.forRegistry(registry)
+        .convertRatesTo(TimeUnit.SECONDS)
+        .convertDurationsTo(TimeUnit.MILLISECONDS)
+        .filter(MetricFilter.ALL)
+        .build(graphite);
+    reporter.start(reportingFrequency, TimeUnit.MINUTES);
+  }
+
+  @Override
+  public void stop() throws MetricsReporterException {
+    reporter.stop();
+  }
+
+  @Override
+  public String getName() {
+    return NAME;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/JmxMetricsReporter.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/JmxMetricsReporter.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/JmxMetricsReporter.java
new file mode 100644
index 0000000..615809e
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/reporters/JmxMetricsReporter.java
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl.reporters;
+
+import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.MetricRegistry;
+import org.apache.hadoop.gateway.config.GatewayConfig;
+import org.apache.hadoop.gateway.services.metrics.MetricsContext;
+import org.apache.hadoop.gateway.services.metrics.MetricsReporterException;
+import org.apache.hadoop.gateway.services.metrics.impl.DefaultMetricsService;
+
+public class JmxMetricsReporter extends AbstractMetricsReporter {
+
+  public static String NAME = "jmx-reporter";
+
+  private JmxReporter jmxReporter;
+
+  @Override
+  public void init(GatewayConfig config) throws MetricsReporterException {
+    if (config.isMetricsEnabled() && config.isJmxMetricsReportingEnabled()) {
+      setEnabled(true);
+    }
+  }
+
+  @Override
+  public void start(MetricsContext metricsContext) throws MetricsReporterException {
+    MetricRegistry registry = (MetricRegistry) metricsContext.getProperty(DefaultMetricsService.METRICS_REGISTRY);
+    jmxReporter = JmxReporter.forRegistry(registry).build();
+    jmxReporter.start();
+  }
+
+  @Override
+  public void stop() throws MetricsReporterException {
+    jmxReporter.stop();
+  }
+
+  @Override
+  public String getName() {
+    return NAME;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/resources/META-INF/services/org.apache.hadoop.gateway.services.metrics.InstrumentationProviderDescriptor
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/resources/META-INF/services/org.apache.hadoop.gateway.services.metrics.InstrumentationProviderDescriptor b/gateway-server/src/main/resources/META-INF/services/org.apache.hadoop.gateway.services.metrics.InstrumentationProviderDescriptor
new file mode 100644
index 0000000..bbae0e0
--- /dev/null
+++ b/gateway-server/src/main/resources/META-INF/services/org.apache.hadoop.gateway.services.metrics.InstrumentationProviderDescriptor
@@ -0,0 +1,20 @@
+##########################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##########################################################################
+
+org.apache.hadoop.gateway.services.metrics.impl.instr.InstrHttpClientProviderDescriptor
+org.apache.hadoop.gateway.services.metrics.impl.instr.InstrGatewayFilterProviderDescriptor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/main/resources/META-INF/services/org.apache.hadoop.gateway.services.metrics.MetricsReporter
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/resources/META-INF/services/org.apache.hadoop.gateway.services.metrics.MetricsReporter b/gateway-server/src/main/resources/META-INF/services/org.apache.hadoop.gateway.services.metrics.MetricsReporter
new file mode 100644
index 0000000..8792644
--- /dev/null
+++ b/gateway-server/src/main/resources/META-INF/services/org.apache.hadoop.gateway.services.metrics.MetricsReporter
@@ -0,0 +1,20 @@
+##########################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##########################################################################
+
+org.apache.hadoop.gateway.services.metrics.impl.reporters.JmxMetricsReporter
+org.apache.hadoop.gateway.services.metrics.impl.reporters.GraphiteMetricsReporter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java b/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java
index f1529ad..9cf7a39 100644
--- a/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java
+++ b/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java
@@ -180,4 +180,15 @@ public class GatewayConfigImplTest {
     assertThat( config.getGlobalRulesServices(), is(hasItems("ONE","TWO","THREE")) );
   }
 
+  @Test( timeout = TestUtils.SHORT_TIMEOUT )
+  public void testMetricsSettings() {
+    GatewayConfigImpl config = new GatewayConfigImpl();
+    //test defaults
+    assertThat(config.isMetricsEnabled(), is(true));
+    assertThat(config.isJmxMetricsReportingEnabled(), is(true));
+    assertThat(config.isGraphiteMetricsReportingEnabled(), is(false));
+    assertThat(config.getGraphiteHost(), is("localhost"));
+    assertThat(config.getGraphitePort(), is(32772));
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-server/src/test/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsServiceTest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsServiceTest.java b/gateway-server/src/test/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsServiceTest.java
new file mode 100644
index 0000000..6e9b4a9
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/hadoop/gateway/services/metrics/impl/DefaultMetricsServiceTest.java
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics.impl;
+
+import com.codahale.metrics.MetricRegistry;
+import org.apache.hadoop.gateway.config.impl.GatewayConfigImpl;
+import org.apache.hadoop.gateway.services.metrics.InstrumentationProvider;
+import org.apache.hadoop.gateway.services.metrics.MetricsReporter;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+public class DefaultMetricsServiceTest {
+
+  @Test
+  public void lifecycle() throws Exception {
+    DefaultMetricsService service = new DefaultMetricsService();
+    service.init(new GatewayConfigImpl(), null);
+    Assert.assertNotNull(service.getContext());
+    Assert.assertNotNull(service.getMetricRegistry());
+    Assert.assertNotNull(service.getMetricsReporters());
+    Assert.assertNotNull(service.getInstrumentationProviders());
+    service.start();
+    Assert.assertNotNull(service.getContext().getMetricsService());
+    MetricRegistry metricRegistry = (MetricRegistry) service.getContext().getProperty(DefaultMetricsService.METRICS_REGISTRY);
+    Assert.assertNotNull(metricRegistry);
+    service.stop();
+  }
+
+  @Test
+  public void instrumentationProvidersLoading() throws Exception {
+    DefaultMetricsService service = new DefaultMetricsService();
+    service.init(new GatewayConfigImpl(), null);
+    Map<Class<?>, InstrumentationProvider> map = service.getInstrumentationProviders();
+    Assert.assertTrue(map.entrySet().size() >= 2);
+    Assert.assertNotNull(service.getInstrumented(HttpClientBuilder.class));
+
+  }
+
+  @Test
+  public void reportersLoading() throws Exception {
+    DefaultMetricsService service = new DefaultMetricsService();
+    GatewayConfigImpl config = new GatewayConfigImpl();
+    config.set(GatewayConfigImpl.JMX_METRICS_REPORTING_ENABLED, "false");
+    service.init(config, null);
+    List<MetricsReporter> reporters = service.getMetricsReporters();
+    Assert.assertTrue(reporters.size() >= 2);
+    for (MetricsReporter reporter : reporters) {
+      Assert.assertFalse(reporter.isEnabled());
+    }
+    config.set(GatewayConfigImpl.JMX_METRICS_REPORTING_ENABLED, "true");
+    config.set(GatewayConfigImpl.GRAPHITE_METRICS_REPORTING_ENABLED, "true");
+    service.init(config, null);
+    reporters = service.getMetricsReporters();
+    for (MetricsReporter reporter : reporters) {
+      Assert.assertTrue(reporter.isEnabled());
+    }
+    service.start();
+    service.stop();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-spi/pom.xml b/gateway-spi/pom.xml
index 47fabe8..e5d1295 100644
--- a/gateway-spi/pom.xml
+++ b/gateway-spi/pom.xml
@@ -116,6 +116,15 @@
         </dependency>
 
         <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-httpclient</artifactId>
+        </dependency>
+
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
index 3e538fd..1d877fd 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
@@ -202,4 +202,16 @@ public interface GatewayConfig {
    */
   int getWebsocketIdleTimeout();
 
+  boolean isMetricsEnabled();
+
+  boolean isJmxMetricsReportingEnabled();
+
+  boolean isGraphiteMetricsReportingEnabled();
+
+  String getGraphiteHost();
+
+  int getGraphitePort();
+
+  int getGraphiteReportingFrequency();
+
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java
index 92652e2..6f75f9e 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java
@@ -18,6 +18,8 @@
 package org.apache.hadoop.gateway.dispatch;
 
 import org.apache.hadoop.gateway.config.GatewayConfig;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.metrics.MetricsService;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.ProtocolException;
@@ -56,8 +58,16 @@ public class DefaultHttpClientFactory implements HttpClientFactory {
 
   @Override
   public HttpClient createHttpClient(FilterConfig filterConfig) {
-    HttpClientBuilder builder = HttpClients.custom();
-
+    HttpClientBuilder builder = null;
+    GatewayConfig gatewayConfig = (GatewayConfig) filterConfig.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+    if (gatewayConfig != null && gatewayConfig.isMetricsEnabled()) {
+      GatewayServices services = (GatewayServices) filterConfig.getServletContext()
+          .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+      MetricsService metricsService = services.getService(GatewayServices.METRICS_SERVICE);
+      builder = metricsService.getInstrumented(HttpClientBuilder.class);
+    } else {
+      builder = HttpClients.custom();
+    }
     if ( "true".equals(System.getProperty(GatewayConfig.HADOOP_KERBEROS_SECURED)) ) {
       CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
       credentialsProvider.setCredentials(AuthScope.ANY, new UseJaasCredentials());

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/GatewayServices.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/GatewayServices.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/GatewayServices.java
index cc4f312..2e6227c 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/GatewayServices.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/GatewayServices.java
@@ -37,6 +37,7 @@ public interface GatewayServices extends Service, ProviderDeploymentContributor
   public static final String SERVER_INFO_SERVICE = "ServerInfoService";
   public static final String TOPOLOGY_SERVICE = "TopologyService";
   public static final String SERVICE_DEFINITION_REGISTRY = "ServiceDefinitionRegistry";
+  public static final String METRICS_SERVICE = "MetricsService";
 
   public abstract Collection<String> getServiceNames();
 

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/InstrumentationProvider.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/InstrumentationProvider.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/InstrumentationProvider.java
new file mode 100644
index 0000000..f45b9fd
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/InstrumentationProvider.java
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics;
+
+public interface InstrumentationProvider<T> {
+
+  T getInstrumented(MetricsContext metricsContext);
+
+  T getInstrumented(T instanceClass, MetricsContext metricsContext);
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/InstrumentationProviderDescriptor.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/InstrumentationProviderDescriptor.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/InstrumentationProviderDescriptor.java
new file mode 100644
index 0000000..50acaee
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/InstrumentationProviderDescriptor.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics;
+
+import java.util.Map;
+
+public interface InstrumentationProviderDescriptor {
+
+  Map<Class<?>, InstrumentationProvider> providesInstrumentation();
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsContext.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsContext.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsContext.java
new file mode 100644
index 0000000..f3efc65
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsContext.java
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics;
+
+public interface MetricsContext {
+
+  MetricsService getMetricsService();
+
+  void setProperty(String name, Object value);
+
+  Object getProperty(String name);
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsReporter.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsReporter.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsReporter.java
new file mode 100644
index 0000000..bda3817
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsReporter.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics;
+
+import org.apache.hadoop.gateway.config.GatewayConfig;
+
+public interface MetricsReporter {
+
+  String getName();
+
+  void init(GatewayConfig config) throws MetricsReporterException;
+
+  void start(MetricsContext metricsContext) throws MetricsReporterException;
+
+  void stop() throws MetricsReporterException;
+
+  boolean isEnabled();
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsReporterException.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsReporterException.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsReporterException.java
new file mode 100644
index 0000000..eb625bb
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsReporterException.java
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics;
+
+public class MetricsReporterException extends Exception {
+
+  public MetricsReporterException(String message) {
+    super(message);
+  }
+
+  public MetricsReporterException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsService.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsService.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsService.java
new file mode 100644
index 0000000..0f5e533
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/metrics/MetricsService.java
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.services.metrics;
+
+import org.apache.hadoop.gateway.services.Service;
+
+public interface MetricsService extends Service {
+
+  <T> T getInstrumented(T instanceClass);
+
+  <T> T getInstrumented(Class<T> clazz);
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
----------------------------------------------------------------------
diff --git a/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java b/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
index 695ad02..5c633d0 100644
--- a/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
+++ b/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
@@ -424,4 +424,34 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
   public int getWebsocketIdleTimeout() {
     return DEFAULT_WEBSOCKET_IDLE_TIMEOUT;
   }
+
+  @Override
+  public boolean isMetricsEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isJmxMetricsReportingEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isGraphiteMetricsReportingEnabled() {
+    return false;
+  }
+
+  @Override
+  public String getGraphiteHost() {
+    return null;
+  }
+
+  @Override
+  public int getGraphitePort() {
+    return 0;
+  }
+
+  @Override
+  public int getGraphiteReportingFrequency() {
+    return 0;
+  }
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
index 11b6eb5..f5c7149 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
@@ -482,4 +482,34 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
   public int getWebsocketIdleTimeout() {
     return DEFAULT_WEBSOCKET_IDLE_TIMEOUT;
   }
+
+  @Override
+  public boolean isMetricsEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isJmxMetricsReportingEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isGraphiteMetricsReportingEnabled() {
+    return false;
+  }
+
+  @Override
+  public String getGraphiteHost() {
+    return null;
+  }
+
+  @Override
+  public int getGraphitePort() {
+    return 0;
+  }
+
+  @Override
+  public int getGraphiteReportingFrequency() {
+    return 0;
+  }
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/f345f889/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ffd665a..3b088ca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -107,6 +107,7 @@
         <failsafe-version>2.19.1</failsafe-version>
         <apacheds-version>2.0.0-M16</apacheds-version>
         <javax-websocket-version>1.1</javax-websocket-version>
+        <metrics-version>3.1.2</metrics-version>
     </properties>
 
     <licenses>
@@ -1147,6 +1148,27 @@
                 <version>${jetty-version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>io.dropwizard.metrics</groupId>
+                <artifactId>metrics-core</artifactId>
+                <version>${metrics-version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.dropwizard.metrics</groupId>
+                <artifactId>metrics-httpclient</artifactId>
+                <version>${metrics-version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.dropwizard.metrics</groupId>
+                <artifactId>metrics-graphite</artifactId>
+                <version>${metrics-version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.dropwizard.metrics</groupId>
+                <artifactId>metrics-jetty9</artifactId>
+                <version>${metrics-version}</version>
+            </dependency>
+
             <!-- ********** ********** ********** ********** ********** ********** -->
             <!-- ********** Test Dependencies                           ********** -->
             <!-- ********** ********** ********** ********** ********** ********** -->
@@ -1258,4 +1280,4 @@
         </dependencies>
     </dependencyManagement>
 
-</project>
+</project>
\ No newline at end of file