Home | History | Annotate | Download | only in util
      1 /*
      2  *
      3  * Copyright 2015 gRPC authors.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *is % allowed in string
     17  */
     18 
     19 #include "test/cpp/util/metrics_server.h"
     20 
     21 #include <grpc/support/log.h>
     22 #include <grpcpp/server.h>
     23 #include <grpcpp/server_builder.h>
     24 
     25 #include "src/proto/grpc/testing/metrics.grpc.pb.h"
     26 #include "src/proto/grpc/testing/metrics.pb.h"
     27 
     28 namespace grpc {
     29 namespace testing {
     30 
     31 QpsGauge::QpsGauge()
     32     : start_time_(gpr_now(GPR_CLOCK_REALTIME)), num_queries_(0) {}
     33 
     34 void QpsGauge::Reset() {
     35   std::lock_guard<std::mutex> lock(num_queries_mu_);
     36   num_queries_ = 0;
     37   start_time_ = gpr_now(GPR_CLOCK_REALTIME);
     38 }
     39 
     40 void QpsGauge::Incr() {
     41   std::lock_guard<std::mutex> lock(num_queries_mu_);
     42   num_queries_++;
     43 }
     44 
     45 long QpsGauge::Get() {
     46   std::lock_guard<std::mutex> lock(num_queries_mu_);
     47   gpr_timespec time_diff =
     48       gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start_time_);
     49   long duration_secs = time_diff.tv_sec > 0 ? time_diff.tv_sec : 1;
     50   return num_queries_ / duration_secs;
     51 }
     52 
     53 grpc::Status MetricsServiceImpl::GetAllGauges(
     54     ServerContext* context, const EmptyMessage* request,
     55     ServerWriter<GaugeResponse>* writer) {
     56   gpr_log(GPR_DEBUG, "GetAllGauges called");
     57 
     58   std::lock_guard<std::mutex> lock(mu_);
     59   for (auto it = qps_gauges_.begin(); it != qps_gauges_.end(); it++) {
     60     GaugeResponse resp;
     61     resp.set_name(it->first);                // Gauge name
     62     resp.set_long_value(it->second->Get());  // Gauge value
     63     writer->Write(resp);
     64   }
     65 
     66   return Status::OK;
     67 }
     68 
     69 grpc::Status MetricsServiceImpl::GetGauge(ServerContext* context,
     70                                           const GaugeRequest* request,
     71                                           GaugeResponse* response) {
     72   std::lock_guard<std::mutex> lock(mu_);
     73 
     74   const auto it = qps_gauges_.find(request->name());
     75   if (it != qps_gauges_.end()) {
     76     response->set_name(it->first);
     77     response->set_long_value(it->second->Get());
     78   }
     79 
     80   return Status::OK;
     81 }
     82 
     83 std::shared_ptr<QpsGauge> MetricsServiceImpl::CreateQpsGauge(
     84     const grpc::string& name, bool* already_present) {
     85   std::lock_guard<std::mutex> lock(mu_);
     86 
     87   std::shared_ptr<QpsGauge> qps_gauge(new QpsGauge());
     88   const auto p = qps_gauges_.insert(std::make_pair(name, qps_gauge));
     89 
     90   // p.first is an iterator pointing to <name, shared_ptr<QpsGauge>> pair.
     91   // p.second is a boolean which is set to 'true' if the QpsGauge is
     92   // successfully inserted in the guages_ map and 'false' if it is already
     93   // present in the map
     94   *already_present = !p.second;
     95   return p.first->second;
     96 }
     97 
     98 // Starts the metrics server and returns the grpc::Server instance. Call Wait()
     99 // on the returned server instance.
    100 std::unique_ptr<grpc::Server> MetricsServiceImpl::StartServer(int port) {
    101   gpr_log(GPR_INFO, "Building metrics server..");
    102 
    103   const grpc::string address = "0.0.0.0:" + grpc::to_string(port);
    104 
    105   ServerBuilder builder;
    106   builder.AddListeningPort(address, grpc::InsecureServerCredentials());
    107   builder.RegisterService(this);
    108 
    109   std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
    110   gpr_log(GPR_INFO, "Metrics server %s started. Ready to receive requests..",
    111           address.c_str());
    112 
    113   return server;
    114 }
    115 
    116 }  // namespace testing
    117 }  // namespace grpc
    118