Simplify QPS Metrics collection
diff --git a/test/cpp/util/metrics_server.cc b/test/cpp/util/metrics_server.cc
index d9b44a6..cc6b39b 100644
--- a/test/cpp/util/metrics_server.cc
+++ b/test/cpp/util/metrics_server.cc
@@ -42,16 +42,26 @@
 namespace grpc {
 namespace testing {
 
-Gauge::Gauge(long initial_val) : val_(initial_val) {}
+QpsGauge::QpsGauge()
+    : start_time_(gpr_now(GPR_CLOCK_REALTIME)), num_queries_(0) {}
 
-void Gauge::Set(long new_val) {
-  std::lock_guard<std::mutex> lock(val_mu_);
-  val_ = new_val;
+void QpsGauge::Reset() {
+  std::lock_guard<std::mutex> lock(num_queries_mu_);
+  num_queries_ = 0;
+  start_time_ = gpr_now(GPR_CLOCK_REALTIME);
 }
 
-long Gauge::Get() {
-  std::lock_guard<std::mutex> lock(val_mu_);
-  return val_;
+void QpsGauge::Incr() {
+  std::lock_guard<std::mutex> lock(num_queries_mu_);
+  num_queries_++;
+}
+
+long QpsGauge::Get() {
+  std::lock_guard<std::mutex> lock(num_queries_mu_);
+  gpr_timespec time_diff =
+      gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start_time_);
+  long duration_secs = time_diff.tv_sec > 0 ? time_diff.tv_sec : 1;
+  return num_queries_ / duration_secs;
 }
 
 grpc::Status MetricsServiceImpl::GetAllGauges(
@@ -60,7 +70,7 @@
   gpr_log(GPR_DEBUG, "GetAllGauges called");
 
   std::lock_guard<std::mutex> lock(mu_);
-  for (auto it = gauges_.begin(); it != gauges_.end(); it++) {
+  for (auto it = qps_gauges_.begin(); it != qps_gauges_.end(); it++) {
     GaugeResponse resp;
     resp.set_name(it->first);                // Gauge name
     resp.set_long_value(it->second->Get());  // Gauge value
@@ -75,8 +85,8 @@
                                           GaugeResponse* response) {
   std::lock_guard<std::mutex> lock(mu_);
 
-  const auto it = gauges_.find(request->name());
-  if (it != gauges_.end()) {
+  const auto it = qps_gauges_.find(request->name());
+  if (it != qps_gauges_.end()) {
     response->set_name(it->first);
     response->set_long_value(it->second->Get());
   }
@@ -84,16 +94,17 @@
   return Status::OK;
 }
 
-std::shared_ptr<Gauge> MetricsServiceImpl::CreateGauge(const grpc::string& name,
-                                                       bool* already_present) {
+std::shared_ptr<QpsGauge> MetricsServiceImpl::CreateQpsGauge(
+    const grpc::string& name, bool* already_present) {
   std::lock_guard<std::mutex> lock(mu_);
 
-  std::shared_ptr<Gauge> gauge(new Gauge(0));
-  const auto p = gauges_.emplace(name, gauge);
+  std::shared_ptr<QpsGauge> qps_gauge(new QpsGauge());
+  const auto p = qps_gauges_.emplace(name, qps_gauge);
 
-  // p.first is an iterator pointing to <name, shared_ptr<Gauge>> pair. p.second
-  // is a boolean which is set to 'true' if the Gauge is inserted in the guages_
-  // map and 'false' if it is already present in the map
+  // p.first is an iterator pointing to <name, shared_ptr<QpsGauge>> pair.
+  // p.second is a boolean which is set to 'true' if the QpsGauge is
+  // successfully inserted in the guages_ map and 'false' if it is already
+  // present in the map
   *already_present = !p.second;
   return p.first->second;
 }
diff --git a/test/cpp/util/metrics_server.h b/test/cpp/util/metrics_server.h
index ce05e0b..b04879c 100644
--- a/test/cpp/util/metrics_server.h
+++ b/test/cpp/util/metrics_server.h
@@ -36,6 +36,7 @@
 #include <map>
 #include <mutex>
 
+#include "grpc/support/time.h"
 #include "src/proto/grpc/testing/metrics.grpc.pb.h"
 #include "src/proto/grpc/testing/metrics.pb.h"
 
@@ -48,10 +49,13 @@
  * Example:
  *    MetricsServiceImpl metricsImpl;
  *    ..
- *    // Create Gauge(s). Note: Gauges can be created even after calling
+ *    // Create QpsGauge(s). Note: QpsGauges can be created even after calling
  *    // 'StartServer'.
- *    Gauge gauge1 = metricsImpl.CreateGauge("foo",is_present);
- *    // gauge1 can now be used anywhere in the program to set values.
+ *    QpsGauge qps_gauge1 = metricsImpl.CreateQpsGauge("foo", is_present);
+ *    // qps_gauge1 can now be used anywhere in the program by first making a
+ *    // one-time call qps_gauge1.Reset() and then calling qps_gauge1.Incr()
+ *    // every time to increment a query counter
+ *
  *    ...
  *    // Create the metrics server
  *    std::unique_ptr<grpc::Server> server = metricsImpl.StartServer(port);
@@ -60,17 +64,24 @@
 namespace grpc {
 namespace testing {
 
-// TODO(sreek): Add support for other types of Gauges like Double, String in
-// future
-class Gauge {
+class QpsGauge {
  public:
-  Gauge(long initial_val);
-  void Set(long new_val);
+  QpsGauge();
+
+  // Initialize the internal timer and reset the query count to 0
+  void Reset();
+
+  // Increment the query count by 1
+  void Incr();
+
+  // Return the current qps (i.e query count divided by the time since this
+  // QpsGauge object created (or Reset() was called))
   long Get();
 
  private:
-  long val_;
-  std::mutex val_mu_;
+  gpr_timespec start_time_;
+  long num_queries_;
+  std::mutex num_queries_mu_;
 };
 
 class MetricsServiceImpl GRPC_FINAL : public MetricsService::Service {
@@ -81,17 +92,17 @@
   grpc::Status GetGauge(ServerContext* context, const GaugeRequest* request,
                         GaugeResponse* response) GRPC_OVERRIDE;
 
-  // Create a Gauge with name 'name'. is_present is set to true if the Gauge
+  // Create a QpsGauge with name 'name'. is_present is set to true if the Gauge
   // is already present in the map.
-  // NOTE: CreateGauge can be called anytime (i.e before or after calling
+  // NOTE: CreateQpsGauge can be called anytime (i.e before or after calling
   // StartServer).
-  std::shared_ptr<Gauge> CreateGauge(const grpc::string& name,
+  std::shared_ptr<QpsGauge> CreateQpsGauge(const grpc::string& name,
                                      bool* already_present);
 
   std::unique_ptr<grpc::Server> StartServer(int port);
 
  private:
-  std::map<string, std::shared_ptr<Gauge>> gauges_;
+  std::map<string, std::shared_ptr<QpsGauge>> qps_gauges_;
   std::mutex mu_;
 };