helix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From h...@apache.org
Subject [helix] branch master updated: Add metric annotations to each resource method (#1379)
Date Tue, 22 Sep 2020 00:20:47 GMT
This is an automated email from the ASF dual-hosted git repository.

hzlu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/helix.git


The following commit(s) were added to refs/heads/master by this push:
     new 257c65b  Add metric annotations to each resource method (#1379)
257c65b is described below

commit 257c65b4fa6ea0aeac7496fa47b54f0f3b4c96ca
Author: Huizhi Lu <ihuizhi.lu@gmail.com>
AuthorDate: Mon Sep 21 17:20:37 2020 -0700

    Add metric annotations to each resource method (#1379)
    
    To enable availability monitoring for helix rest, we want request latency and response metrics. And make sure metrics are not consuming too much memory, we want to categorize the resource methods into "read" and "write". GET verb is read, and POST, DELETE, UPDATE are writes.
    This commit only adds @Timed and @ResponseMetered annotations to each rest method and categorize them "read" or "write".
---
 helix-rest/pom.xml                                 |  5 ++
 .../apache/helix/rest/common/HttpConstants.java    |  6 ++
 .../server/resources/helix/ClusterAccessor.java    | 67 ++++++++++++++++++++++
 .../server/resources/helix/InstancesAccessor.java  |  7 +++
 .../rest/server/resources/helix/JobAccessor.java   | 19 ++++++
 .../server/resources/helix/MetadataAccessor.java   |  5 ++
 .../resources/helix/PerInstanceAccessor.java       | 35 +++++++++++
 .../resources/helix/PropertyStoreAccessor.java     |  9 +++
 .../server/resources/helix/ResourceAccessor.java   | 27 +++++++++
 .../rest/server/resources/helix/TaskAccessor.java  |  7 +++
 .../server/resources/helix/WorkflowAccessor.java   | 23 ++++++++
 .../resources/metadata/NamespacesAccessor.java     |  5 ++
 .../MetadataStoreDirectoryAccessor.java            | 23 ++++++++
 .../resources/zookeeper/ZooKeeperAccessor.java     |  7 +++
 pom.xml                                            |  1 +
 15 files changed, 246 insertions(+)

diff --git a/helix-rest/pom.xml b/helix-rest/pom.xml
index 6f0e142..1a9c151 100644
--- a/helix-rest/pom.xml
+++ b/helix-rest/pom.xml
@@ -149,6 +149,11 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>io.dropwizard.metrics</groupId>
+      <artifactId>metrics-jersey2</artifactId>
+      <version>${metrics-jersey2.version}</version>
+    </dependency>
+    <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/common/HttpConstants.java b/helix-rest/src/main/java/org/apache/helix/rest/common/HttpConstants.java
index d6eec6d..a22b822 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/common/HttpConstants.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/common/HttpConstants.java
@@ -29,4 +29,10 @@ public class HttpConstants {
 
   public static final String HTTP_PROTOCOL_PREFIX = "http://";
   public static final int DEFAULT_HTTP_REQUEST_TIMEOUT = 60 * 1000;
+
+  /** REST request categorized as read. Can be used to categorize metric names */
+  public static final String READ_REQUEST = "read";
+
+  /** REST request categorized as write. Can be used to categorize metric names */
+  public static final String WRITE_REQUEST = "write";
 }
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ClusterAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ClusterAccessor.java
index d19f17e..6efcb41 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ClusterAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ClusterAccessor.java
@@ -34,6 +34,8 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ImmutableMap;
@@ -57,6 +59,7 @@ import org.apache.helix.model.Message;
 import org.apache.helix.model.RESTConfig;
 import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.model.builder.HelixConfigScopeBuilder;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.rest.server.json.cluster.ClusterTopology;
 import org.apache.helix.rest.server.service.ClusterService;
 import org.apache.helix.rest.server.service.ClusterServiceImpl;
@@ -86,6 +89,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     clusterName
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   public Response getClusters() {
     HelixAdmin helixAdmin = getHelixAdmin();
@@ -97,6 +102,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return JSONRepresentation(dataMap);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}")
   public Response getClusterInfo(@PathParam("clusterId") String clusterId) {
@@ -133,6 +140,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return JSONRepresentation(clusterInfo);
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("{clusterId}")
   public Response createCluster(@PathParam("clusterId") String clusterId,
@@ -167,6 +176,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return created();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("{clusterId}")
   public Response deleteCluster(@PathParam("clusterId") String clusterId) {
@@ -186,6 +197,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{clusterId}")
   public Response updateCluster(@PathParam("clusterId") String clusterId,
@@ -276,6 +289,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/configs")
   public Response getClusterConfig(@PathParam("clusterId") String clusterId) {
@@ -298,6 +313,8 @@ public class ClusterAccessor extends AbstractHelixResource {
   }
 
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("{clusterId}/customized-state-config")
   public Response addCustomizedStateConfig(@PathParam("clusterId") String clusterId,
@@ -327,6 +344,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("{clusterId}/customized-state-config")
   public Response removeCustomizedStateConfig(@PathParam("clusterId") String clusterId) {
@@ -347,6 +366,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/customized-state-config")
   public Response getCustomizedStateConfig(@PathParam("clusterId") String clusterId) {
@@ -365,6 +386,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return notFound();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{clusterId}/customized-state-config")
   public Response updateCustomizedStateConfig(@PathParam("clusterId") String clusterId,
@@ -405,6 +428,8 @@ public class ClusterAccessor extends AbstractHelixResource {
   }
 
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/topology")
   public Response getClusterTopology(@PathParam("clusterId") String clusterId) throws IOException {
@@ -417,6 +442,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK(objectMapper.writeValueAsString(clusterTopology));
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{clusterId}/configs")
   public Response updateClusterConfig(@PathParam("clusterId") String clusterId,
@@ -469,6 +496,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/controller")
   public Response getClusterController(@PathParam("clusterId") String clusterId) {
@@ -487,6 +516,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return JSONRepresentation(controllerInfo);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/controller/history")
   public Response getClusterControllerLeadershipHistory(@PathParam("clusterId") String clusterId) {
@@ -494,6 +525,8 @@ public class ClusterAccessor extends AbstractHelixResource {
         getControllerHistory(clusterId, ControllerHistory.HistoryType.CONTROLLER_LEADERSHIP));
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/controller/maintenanceHistory")
   public Response getClusterMaintenanceHistory(@PathParam("clusterId") String clusterId) {
@@ -501,6 +534,8 @@ public class ClusterAccessor extends AbstractHelixResource {
         getControllerHistory(clusterId, ControllerHistory.HistoryType.MAINTENANCE));
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/controller/maintenanceSignal")
   public Response getClusterMaintenanceSignal(@PathParam("clusterId") String clusterId) {
@@ -515,6 +550,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return notFound(String.format("Cluster %s is not in maintenance mode!", clusterId));
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/controller/messages")
   public Response getClusterControllerMessages(@PathParam("clusterId") String clusterId) {
@@ -531,6 +568,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return JSONRepresentation(controllerMessages);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/controller/messages/{messageId}")
   public Response getClusterControllerMessages(@PathParam("clusterId") String clusterId,
@@ -541,6 +580,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return JSONRepresentation(message.getRecord());
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/statemodeldefs")
   public Response getClusterStateModelDefinitions(@PathParam("clusterId") String clusterId) {
@@ -555,6 +596,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return JSONRepresentation(clusterStateModelDefs);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/statemodeldefs/{statemodel}")
   public Response getClusterStateModelDefinition(@PathParam("clusterId") String clusterId,
@@ -569,6 +612,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return JSONRepresentation(stateModelDef.getRecord());
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("{clusterId}/statemodeldefs/{statemodel}")
   public Response createClusterStateModelDefinition(@PathParam("clusterId") String clusterId,
@@ -592,6 +637,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{clusterId}/statemodeldefs/{statemodel}")
   public Response setClusterStateModelDefinition(@PathParam("clusterId") String clusterId,
@@ -619,6 +666,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("{clusterId}/statemodeldefs/{statemodel}")
   public Response removeClusterStateModelDefinition(@PathParam("clusterId") String clusterId,
@@ -643,6 +692,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("{clusterId}/restconfig")
   public Response createRESTConfig(@PathParam("clusterId") String clusterId,
@@ -673,6 +724,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{clusterId}/restconfig")
   public Response updateRESTConfig(@PathParam("clusterId") String clusterId,
@@ -720,6 +773,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/restconfig")
   public Response getRESTConfig(@PathParam("clusterId") String clusterId) {
@@ -740,6 +795,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return JSONRepresentation(config.getRecord());
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("{clusterId}/restconfig")
   public Response deleteRESTConfig(@PathParam("clusterId") String clusterId) {
@@ -756,6 +813,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/maintenance")
   public Response getClusterMaintenanceMode(@PathParam("clusterId") String clusterId) {
@@ -768,6 +827,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return ZKUtil.isClusterSetup(cluster, zkClient);
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("{clusterId}/cloudconfig")
   public Response addCloudConfig(@PathParam("clusterId") String clusterId, String content) {
@@ -800,6 +861,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{clusterId}/cloudconfig")
   public Response getCloudConfig(@PathParam("clusterId") String clusterId) {
@@ -819,6 +882,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return notFound();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("{clusterId}/cloudconfig")
   public Response deleteCloudConfig(@PathParam("clusterId") String clusterId) {
@@ -827,6 +892,8 @@ public class ClusterAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{clusterId}/cloudconfig")
   public Response updateCloudConfig(@PathParam("clusterId") String clusterId,
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/InstancesAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/InstancesAccessor.java
index c60c753..04c24f3 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/InstancesAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/InstancesAccessor.java
@@ -35,6 +35,8 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
@@ -47,6 +49,7 @@ import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.InstanceConfig;
 import org.apache.helix.rest.common.HelixDataAccessorWrapper;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.rest.server.json.cluster.ClusterTopology;
 import org.apache.helix.rest.server.json.instance.StoppableCheck;
 import org.apache.helix.rest.server.resources.exceptions.HelixHealthException;
@@ -80,6 +83,8 @@ public class InstancesAccessor extends AbstractHelixResource {
     zone_based
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   public Response getAllInstances(@PathParam("clusterId") String clusterId,
       @DefaultValue("getAllInstances") @QueryParam("command") String command) {
@@ -142,6 +147,8 @@ public class InstancesAccessor extends AbstractHelixResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   public Response instancesOperations(@PathParam("clusterId") String clusterId,
       @QueryParam("skipZKRead") String skipZKRead, @QueryParam("command") String command, String content) {
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/JobAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/JobAccessor.java
index b817813..d6dc610 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/JobAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/JobAccessor.java
@@ -34,11 +34,14 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.apache.helix.HelixException;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.task.JobConfig;
 import org.apache.helix.task.JobContext;
 import org.apache.helix.task.TaskConfig;
@@ -60,6 +63,8 @@ public class JobAccessor extends AbstractHelixResource {
     TASK_COMMAND
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   public Response getJobs(@PathParam("clusterId") String clusterId,
       @PathParam("workflowName") String workflowName) {
@@ -81,6 +86,8 @@ public class JobAccessor extends AbstractHelixResource {
     return JSONRepresentation(root);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{jobName}")
   public Response getJob(@PathParam("clusterId") String clusterId,
@@ -107,6 +114,8 @@ public class JobAccessor extends AbstractHelixResource {
     return JSONRepresentation(jobMap);
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("{jobName}")
   public Response addJob(@PathParam("clusterId") String clusterId,
@@ -129,6 +138,8 @@ public class JobAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("{jobName}")
   public Response deleteJob(@PathParam("clusterId") String clusterId,
@@ -146,6 +157,8 @@ public class JobAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{jobName}/configs")
   public Response getJobConfig(@PathParam("clusterId") String clusterId,
@@ -159,6 +172,8 @@ public class JobAccessor extends AbstractHelixResource {
     return badRequest("Job config for " + jobName + " does not exists");
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{jobName}/context")
   public Response getJobContext(@PathParam("clusterId") String clusterId,
@@ -173,6 +188,8 @@ public class JobAccessor extends AbstractHelixResource {
     return badRequest("Job context for " + jobName + " does not exists");
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{jobName}/userContent")
   public Response getJobUserContent(@PathParam("clusterId") String clusterId,
@@ -194,6 +211,8 @@ public class JobAccessor extends AbstractHelixResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{jobName}/userContent")
   public Response updateJobUserContent(
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/MetadataAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/MetadataAccessor.java
index 007c4c6..40b61d9 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/MetadataAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/MetadataAccessor.java
@@ -23,13 +23,18 @@ import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import org.apache.helix.rest.common.ContextPropertyKeys;
 import org.apache.helix.rest.common.HelixRestNamespace;
 import org.apache.helix.rest.common.HelixRestUtils;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.rest.server.resources.AbstractResource;
 
 @Path("")
 public class MetadataAccessor extends AbstractResource {
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   public Response getMetadata() {
     if (HelixRestUtils.isDefaultServlet(_servletRequest.getServletPath())) {
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java
index 0cfefe1..474e4fa 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java
@@ -35,6 +35,8 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -55,6 +57,7 @@ import org.apache.helix.model.Message;
 import org.apache.helix.model.ParticipantHistory;
 import org.apache.helix.model.builder.HelixConfigScopeBuilder;
 import org.apache.helix.rest.common.HelixDataAccessorWrapper;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.rest.server.json.instance.InstanceInfo;
 import org.apache.helix.rest.server.json.instance.StoppableCheck;
 import org.apache.helix.rest.server.service.InstanceService;
@@ -83,6 +86,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     instanceTags
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   public Response getInstanceById(@PathParam("clusterId") String clusterId,
       @PathParam("instanceName") String instanceName, @QueryParam("skipZKRead") String skipZKRead,
@@ -129,6 +134,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("stoppable")
   @Consumes(MediaType.APPLICATION_JSON)
@@ -151,6 +158,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return OK(objectMapper.writeValueAsString(stoppableCheck));
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   public Response addInstance(@PathParam("clusterId") String clusterId,
       @PathParam("instanceName") String instanceName, String content) {
@@ -173,6 +182,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   public Response updateInstance(@PathParam("clusterId") String clusterId,
       @PathParam("instanceName") String instanceName, @QueryParam("command") String command,
@@ -256,6 +267,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   public Response deleteInstance(@PathParam("clusterId") String clusterId,
       @PathParam("instanceName") String instanceName) {
@@ -270,6 +283,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("configs")
   public Response getInstanceConfig(@PathParam("clusterId") String clusterId,
@@ -285,6 +300,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return notFound();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("configs")
   public Response updateInstanceConfig(@PathParam("clusterId") String clusterId,
@@ -348,6 +365,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("resources")
   public Response getResourcesOnInstance(@PathParam("clusterId") String clusterId,
@@ -375,6 +394,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return JSONRepresentation(root);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET @Path("resources/{resourceName}")
   public Response getResourceOnInstance(@PathParam("clusterId") String clusterId,
       @PathParam("instanceName") String instanceName,
@@ -396,6 +417,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return notFound();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("errors")
   public Response getErrorsOnInstance(@PathParam("clusterId") String clusterId,
@@ -433,6 +456,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return JSONRepresentation(root);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("errors/{sessionId}/{resourceName}/{partitionName}")
   public Response getErrorsOnInstance(@PathParam("clusterId") String clusterId,
@@ -449,6 +474,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return notFound();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("history")
   public Response getHistoryOnInstance(@PathParam("clusterId") String clusterId,
@@ -462,6 +489,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return notFound();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("messages")
   public Response getMessagesOnInstance(@PathParam("clusterId") String clusterId,
@@ -506,6 +535,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return JSONRepresentation(root);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("messages/{messageId}")
   public Response getMessageOnInstance(@PathParam("clusterId") String clusterId,
@@ -520,6 +551,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return notFound();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("healthreports")
   public Response getHealthReportsOnInstance(@PathParam("clusterId") String clusterId,
@@ -540,6 +573,8 @@ public class PerInstanceAccessor extends AbstractHelixResource {
     return JSONRepresentation(root);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("healthreports/{reportName}")
   public Response getHealthReportsOnInstance(
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PropertyStoreAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PropertyStoreAccessor.java
index 1c9629f..78ed112 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PropertyStoreAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PropertyStoreAccessor.java
@@ -30,11 +30,14 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.apache.helix.AccessOption;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.PropertyPathBuilder;
 import org.apache.helix.msdcommon.util.ZkValidationUtil;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.zookeeper.datamodel.serializer.ZNRecordSerializer;
 import org.slf4j.Logger;
@@ -56,6 +59,8 @@ public class PropertyStoreAccessor extends AbstractHelixResource {
    * @return If the payload is ZNRecord format, return ZnRecord json response;
    *         Otherwise, return json object {<PATH>: raw string}
    */
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{path: .+}")
   public Response getPropertyByPath(@PathParam("clusterId") String clusterId,
@@ -94,6 +99,8 @@ public class PropertyStoreAccessor extends AbstractHelixResource {
    * @param content
    * @return Response
    */
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("{path: .+}")
   public Response putPropertyByPath(@PathParam("clusterId") String clusterId,
@@ -141,6 +148,8 @@ public class PropertyStoreAccessor extends AbstractHelixResource {
    * @param path
    * @return
    */
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("{path: .+}")
   public Response deletePropertyByPath(@PathParam("clusterId") String clusterId,
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ResourceAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ResourceAccessor.java
index 2b69e45..bca0d3b 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ResourceAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ResourceAccessor.java
@@ -37,6 +37,8 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
@@ -51,6 +53,7 @@ import org.apache.helix.model.IdealState;
 import org.apache.helix.model.ResourceConfig;
 import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.model.builder.HelixConfigScopeBuilder;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.zookeeper.api.client.RealmAwareZkClient;
 import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
@@ -74,6 +77,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     UNHEALTHY
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   public Response getResources(@PathParam("clusterId") String clusterId) {
     ObjectNode root = JsonNodeFactory.instance.objectNode();
@@ -105,6 +110,8 @@ public class ResourceAccessor extends AbstractHelixResource {
    * @param clusterId
    * @return JSON result
    */
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("health")
   public Response getResourceHealth(@PathParam("clusterId") String clusterId) {
@@ -151,6 +158,8 @@ public class ResourceAccessor extends AbstractHelixResource {
    * @return JSON result
    * @throws IOException
    */
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{resourceName}/health")
   public Response getPartitionHealth(@PathParam("clusterId") String clusterId,
@@ -159,6 +168,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     return JSONRepresentation(computePartitionHealth(clusterId, resourceName));
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{resourceName}")
   public Response getResource(@PathParam("clusterId") String clusterId,
@@ -214,6 +225,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("{resourceName}")
   public Response addResource(@PathParam("clusterId") String clusterId,
@@ -302,6 +315,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{resourceName}")
   public Response updateResource(@PathParam("clusterId") String clusterId,
@@ -350,6 +365,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("{resourceName}")
   public Response deleteResource(@PathParam("clusterId") String clusterId,
@@ -364,6 +381,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{resourceName}/configs")
   public Response getResourceConfig(@PathParam("clusterId") String clusterId,
@@ -377,6 +396,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     return notFound();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{resourceName}/configs")
   public Response updateResourceConfig(@PathParam("clusterId") String clusterId,
@@ -426,6 +447,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{resourceName}/idealState")
   public Response getResourceIdealState(@PathParam("clusterId") String clusterId,
@@ -439,6 +462,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     return notFound();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{resourceName}/idealState")
   public Response updateResourceIdealState(@PathParam("clusterId") String clusterId,
@@ -487,6 +512,8 @@ public class ResourceAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{resourceName}/externalView")
   public Response getResourceExternalView(@PathParam("clusterId") String clusterId,
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/TaskAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/TaskAccessor.java
index 9f9e33b..a8a7b74 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/TaskAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/TaskAccessor.java
@@ -29,7 +29,10 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.core.type.TypeReference;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.task.TaskDriver;
 import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
 import org.slf4j.Logger;
@@ -39,6 +42,8 @@ import org.slf4j.LoggerFactory;
 public class TaskAccessor extends AbstractHelixResource {
   private static Logger _logger = LoggerFactory.getLogger(TaskAccessor.class.getName());
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{taskPartitionId}/userContent")
   public Response getTaskUserContent(
@@ -66,6 +71,8 @@ public class TaskAccessor extends AbstractHelixResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{taskPartitionId}/userContent")
   public Response updateTaskUserContent(
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/WorkflowAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/WorkflowAccessor.java
index 10c2cde..c2929a2 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/WorkflowAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/WorkflowAccessor.java
@@ -36,6 +36,8 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ArrayNode;
@@ -44,6 +46,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.fasterxml.jackson.databind.node.TextNode;
 import com.fasterxml.jackson.databind.type.TypeFactory;
 import org.apache.helix.HelixException;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.task.JobConfig;
 import org.apache.helix.task.JobDag;
 import org.apache.helix.task.JobQueue;
@@ -75,6 +78,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     clean
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   public Response getWorkflows(@PathParam("clusterId") String clusterId) {
     TaskDriver taskDriver = getTaskDriver(clusterId);
@@ -85,6 +90,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     return JSONRepresentation(dataMap);
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{workflowId}")
   public Response getWorkflow(@PathParam("clusterId") String clusterId,
@@ -120,6 +127,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     return JSONRepresentation(root);
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("{workflowId}")
   public Response createWorkflow(@PathParam("clusterId") String clusterId,
@@ -176,6 +185,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("{workflowId}")
   public Response deleteWorkflow(@PathParam("clusterId") String clusterId,
@@ -192,6 +203,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{workflowId}")
   public Response updateWorkflow(@PathParam("clusterId") String clusterId,
@@ -223,6 +236,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{workflowId}/configs")
   public Response getWorkflowConfig(@PathParam("clusterId") String clusterId,
@@ -237,6 +252,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     return JSONRepresentation(workflowConfigNode);
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{workflowId}/configs")
   public Response updateWorkflowConfig(@PathParam("clusterId") String clusterId,
@@ -265,6 +282,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     return OK();
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{workflowId}/userContent")
   public Response getWorkflowUserContent(
@@ -289,6 +308,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @POST
   @Path("{workflowId}/userContent")
   public Response updateWorkflowUserContent(
@@ -330,6 +351,8 @@ public class WorkflowAccessor extends AbstractHelixResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("{workflowId}/context")
   public Response getWorkflowContext(@PathParam("clusterId") String clusterId,
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/metadata/NamespacesAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/metadata/NamespacesAccessor.java
index 98f458b..9ae0c19 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/metadata/NamespacesAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/metadata/NamespacesAccessor.java
@@ -26,13 +26,18 @@ import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import org.apache.helix.rest.common.ContextPropertyKeys;
 import org.apache.helix.rest.common.HelixRestNamespace;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.rest.server.resources.AbstractResource;
 
 
 @Path("/namespaces")
 public class NamespacesAccessor extends AbstractResource {
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   public Response getHelixRestNamespaces() {
     @SuppressWarnings("unchecked")
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/metadatastore/MetadataStoreDirectoryAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/metadatastore/MetadataStoreDirectoryAccessor.java
index a72795d..781e723 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/metadatastore/MetadataStoreDirectoryAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/metadatastore/MetadataStoreDirectoryAccessor.java
@@ -37,6 +37,8 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonMappingException;
@@ -46,6 +48,7 @@ import org.apache.helix.msdcommon.exception.InvalidRoutingDataException;
 import org.apache.helix.rest.common.ContextPropertyKeys;
 import org.apache.helix.rest.common.HelixRestNamespace;
 import org.apache.helix.rest.common.HelixRestUtils;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.rest.metadatastore.MetadataStoreDirectory;
 import org.apache.helix.rest.metadatastore.ZkMetadataStoreDirectory;
 import org.apache.helix.rest.metadatastore.datamodel.MetadataStoreShardingKey;
@@ -80,6 +83,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
    *
    * @return Json response of all namespaces.
    */
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("/metadata-store-namespaces")
   public Response getAllNamespaces() {
@@ -97,6 +102,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
    *
    * @return Json representation of all realms.
    */
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("/metadata-store-realms")
   public Response getAllMetadataStoreRealms(@QueryParam("sharding-key") String shardingKey) {
@@ -120,6 +127,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("/metadata-store-realms/{realm}")
   public Response addMetadataStoreRealm(@PathParam("realm") String realm) {
@@ -134,6 +143,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
     return created();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("/metadata-store-realms/{realm}")
   public Response deleteMetadataStoreRealm(@PathParam("realm") String realm) {
@@ -173,6 +184,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
    * @param prefix Query param in endpoint path: prefix substring of sharding key.
    * @return Json representation for the sharding keys.
    */
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("/sharding-keys")
   public Response getShardingKeys(@QueryParam("prefix") String prefix) {
@@ -206,6 +219,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
    *   } ]
    * }
    */
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("/routing-data")
   public Response getRoutingData() {
@@ -227,6 +242,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
     return JSONRepresentation(responseMap);
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("/routing-data")
   @Consumes(MediaType.APPLICATION_JSON)
@@ -258,6 +275,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
    * @param prefix Query param in endpoint path: prefix substring of sharding key.
    * @return All path-based sharding keys in the queried realm.
    */
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   @Path("/metadata-store-realms/{realm}/sharding-keys")
   public Response getRealmShardingKeys(@PathParam("realm") String realm,
@@ -276,6 +295,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @PUT
   @Path("/metadata-store-realms/{realm}/sharding-keys/{sharding-key: .+}")
   public Response addShardingKey(@PathParam("realm") String realm,
@@ -294,6 +315,8 @@ public class MetadataStoreDirectoryAccessor extends AbstractResource {
     return created();
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   @Path("/metadata-store-realms/{realm}/sharding-keys/{sharding-key: .+}")
   public Response deleteShardingKey(@PathParam("realm") String realm,
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/zookeeper/ZooKeeperAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/zookeeper/ZooKeeperAccessor.java
index ab13cdc..4450017 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/zookeeper/ZooKeeperAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/zookeeper/ZooKeeperAccessor.java
@@ -29,6 +29,8 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 
+import com.codahale.metrics.annotation.ResponseMetered;
+import com.codahale.metrics.annotation.Timed;
 import com.google.common.base.Enums;
 import com.google.common.collect.ImmutableMap;
 import org.apache.helix.AccessOption;
@@ -36,6 +38,7 @@ import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.manager.zk.ZKUtil;
 import org.apache.helix.msdcommon.util.ZkValidationUtil;
 import org.apache.helix.rest.common.ContextPropertyKeys;
+import org.apache.helix.rest.common.HttpConstants;
 import org.apache.helix.rest.server.ServerContext;
 import org.apache.helix.rest.server.resources.AbstractResource;
 import org.apache.zookeeper.data.Stat;
@@ -60,6 +63,8 @@ public class ZooKeeperAccessor extends AbstractResource {
     getStat
   }
 
+  @ResponseMetered(name = HttpConstants.READ_REQUEST)
+  @Timed(name = HttpConstants.READ_REQUEST)
   @GET
   public Response get(@PathParam("path") String path, @QueryParam("command") String commandStr) {
     ZooKeeperCommand cmd = getZooKeeperCommandIfPresent(commandStr);
@@ -97,6 +102,8 @@ public class ZooKeeperAccessor extends AbstractResource {
     }
   }
 
+  @ResponseMetered(name = HttpConstants.WRITE_REQUEST)
+  @Timed(name = HttpConstants.WRITE_REQUEST)
   @DELETE
   public Response delete(@PathParam("path") String path) {
     // Lazily initialize ZkBaseDataAccessor
diff --git a/pom.xml b/pom.xml
index 8166e03..ab7b331 100644
--- a/pom.xml
+++ b/pom.xml
@@ -440,6 +440,7 @@
     <SKIP_INTEGRATION_TESTS>true</SKIP_INTEGRATION_TESTS>
     <!-- Configuration for unit/integration tests section 1 of 3 (properties) ENDS HERE.-->
 
+    <metrics-jersey2.version>4.1.12.1</metrics-jersey2.version>
   </properties>
 
   <distributionManagement>


Mime
View raw message