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_;
};