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 // 17 // 18 19 #include "test/cpp/qps/report.h" 20 21 #include <grpcpp/client_context.h> 22 23 #include <fstream> 24 25 #include "absl/log/log.h" 26 #include "src/core/util/crash.h" 27 #include "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h" 28 #include "test/cpp/qps/driver.h" 29 #include "test/cpp/qps/parse_json.h" 30 #include "test/cpp/qps/stats.h" 31 32 namespace grpc { 33 namespace testing { 34 add(std::unique_ptr<Reporter> reporter)35void CompositeReporter::add(std::unique_ptr<Reporter> reporter) { 36 reporters_.emplace_back(std::move(reporter)); 37 } 38 ReportQPS(const ScenarioResult & result)39void CompositeReporter::ReportQPS(const ScenarioResult& result) { 40 for (size_t i = 0; i < reporters_.size(); ++i) { 41 reporters_[i]->ReportQPS(result); 42 } 43 } 44 ReportQPSPerCore(const ScenarioResult & result)45void CompositeReporter::ReportQPSPerCore(const ScenarioResult& result) { 46 for (size_t i = 0; i < reporters_.size(); ++i) { 47 reporters_[i]->ReportQPSPerCore(result); 48 } 49 } 50 ReportLatency(const ScenarioResult & result)51void CompositeReporter::ReportLatency(const ScenarioResult& result) { 52 for (size_t i = 0; i < reporters_.size(); ++i) { 53 reporters_[i]->ReportLatency(result); 54 } 55 } 56 ReportTimes(const ScenarioResult & result)57void CompositeReporter::ReportTimes(const ScenarioResult& result) { 58 for (size_t i = 0; i < reporters_.size(); ++i) { 59 reporters_[i]->ReportTimes(result); 60 } 61 } 62 ReportCpuUsage(const ScenarioResult & result)63void CompositeReporter::ReportCpuUsage(const ScenarioResult& result) { 64 for (size_t i = 0; i < reporters_.size(); ++i) { 65 reporters_[i]->ReportCpuUsage(result); 66 } 67 } 68 ReportPollCount(const ScenarioResult & result)69void CompositeReporter::ReportPollCount(const ScenarioResult& result) { 70 for (size_t i = 0; i < reporters_.size(); ++i) { 71 reporters_[i]->ReportPollCount(result); 72 } 73 } 74 ReportQueriesPerCpuSec(const ScenarioResult & result)75void CompositeReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) { 76 for (size_t i = 0; i < reporters_.size(); ++i) { 77 reporters_[i]->ReportQueriesPerCpuSec(result); 78 } 79 } 80 ReportQPS(const ScenarioResult & result)81void GprLogReporter::ReportQPS(const ScenarioResult& result) { 82 LOG(INFO) << "QPS: " << result.summary().qps(); 83 if (result.summary().failed_requests_per_second() > 0) { 84 LOG(INFO) << "failed requests/second: " 85 << result.summary().failed_requests_per_second(); 86 LOG(INFO) << "successful requests/second: " 87 << result.summary().successful_requests_per_second(); 88 } 89 } 90 ReportQPSPerCore(const ScenarioResult & result)91void GprLogReporter::ReportQPSPerCore(const ScenarioResult& result) { 92 LOG(INFO) << "QPS: " << result.summary().qps() << " (" 93 << result.summary().qps_per_server_core() << "/server core)"; 94 } 95 ReportLatency(const ScenarioResult & result)96void GprLogReporter::ReportLatency(const ScenarioResult& result) { 97 LOG(INFO) << "Latencies (50/90/95/99/99.9%-ile): " 98 << result.summary().latency_50() / 1000 << "/" 99 << result.summary().latency_90() / 1000 << "/" 100 << result.summary().latency_95() / 1000 << "/" 101 << result.summary().latency_99() / 1000 << "/" 102 << result.summary().latency_999() / 1000 << " us"; 103 } 104 ReportTimes(const ScenarioResult & result)105void GprLogReporter::ReportTimes(const ScenarioResult& result) { 106 LOG(INFO) << "Server system time: " << result.summary().server_system_time(); 107 LOG(INFO) << "Server user time: " << result.summary().server_user_time(); 108 LOG(INFO) << "Client system time: " << result.summary().client_system_time(); 109 LOG(INFO) << "Client user time: " << result.summary().client_user_time(); 110 } 111 ReportCpuUsage(const ScenarioResult & result)112void GprLogReporter::ReportCpuUsage(const ScenarioResult& result) { 113 LOG(INFO) << "Server CPU usage: " << result.summary().server_cpu_usage(); 114 } 115 ReportPollCount(const ScenarioResult & result)116void GprLogReporter::ReportPollCount(const ScenarioResult& result) { 117 LOG(INFO) << "Client Polls per Request: " 118 << result.summary().client_polls_per_request(); 119 LOG(INFO) << "Server Polls per Request: " 120 << result.summary().server_polls_per_request(); 121 } 122 ReportQueriesPerCpuSec(const ScenarioResult & result)123void GprLogReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) { 124 LOG(INFO) << "Server Queries/CPU-sec: " 125 << result.summary().server_queries_per_cpu_sec(); 126 LOG(INFO) << "Client Queries/CPU-sec: " 127 << result.summary().client_queries_per_cpu_sec(); 128 } 129 ReportQPS(const ScenarioResult & result)130void JsonReporter::ReportQPS(const ScenarioResult& result) { 131 std::string json_string = 132 SerializeJson(result, "type.googleapis.com/grpc.testing.ScenarioResult"); 133 std::ofstream output_file(report_file_); 134 output_file << json_string; 135 output_file.close(); 136 } 137 ReportQPSPerCore(const ScenarioResult &)138void JsonReporter::ReportQPSPerCore(const ScenarioResult& /*result*/) { 139 // NOP - all reporting is handled by ReportQPS. 140 } 141 ReportLatency(const ScenarioResult &)142void JsonReporter::ReportLatency(const ScenarioResult& /*result*/) { 143 // NOP - all reporting is handled by ReportQPS. 144 } 145 ReportTimes(const ScenarioResult &)146void JsonReporter::ReportTimes(const ScenarioResult& /*result*/) { 147 // NOP - all reporting is handled by ReportQPS. 148 } 149 ReportCpuUsage(const ScenarioResult &)150void JsonReporter::ReportCpuUsage(const ScenarioResult& /*result*/) { 151 // NOP - all reporting is handled by ReportQPS. 152 } 153 ReportPollCount(const ScenarioResult &)154void JsonReporter::ReportPollCount(const ScenarioResult& /*result*/) { 155 // NOP - all reporting is handled by ReportQPS. 156 } 157 ReportQueriesPerCpuSec(const ScenarioResult &)158void JsonReporter::ReportQueriesPerCpuSec(const ScenarioResult& /*result*/) { 159 // NOP - all reporting is handled by ReportQPS. 160 } 161 ReportQPS(const ScenarioResult & result)162void RpcReporter::ReportQPS(const ScenarioResult& result) { 163 grpc::ClientContext context; 164 grpc::Status status; 165 Void phony; 166 167 LOG(INFO) << "RPC reporter sending scenario result to server"; 168 status = stub_->ReportScenario(&context, result, &phony); 169 170 if (status.ok()) { 171 LOG(INFO) << "RpcReporter report RPC success!"; 172 } else { 173 LOG(ERROR) << "RpcReporter report RPC: code: " << status.error_code() 174 << ". message: " << status.error_message(); 175 } 176 } 177 ReportQPSPerCore(const ScenarioResult &)178void RpcReporter::ReportQPSPerCore(const ScenarioResult& /*result*/) { 179 // NOP - all reporting is handled by ReportQPS. 180 } 181 ReportLatency(const ScenarioResult &)182void RpcReporter::ReportLatency(const ScenarioResult& /*result*/) { 183 // NOP - all reporting is handled by ReportQPS. 184 } 185 ReportTimes(const ScenarioResult &)186void RpcReporter::ReportTimes(const ScenarioResult& /*result*/) { 187 // NOP - all reporting is handled by ReportQPS. 188 } 189 ReportCpuUsage(const ScenarioResult &)190void RpcReporter::ReportCpuUsage(const ScenarioResult& /*result*/) { 191 // NOP - all reporting is handled by ReportQPS. 192 } 193 ReportPollCount(const ScenarioResult &)194void RpcReporter::ReportPollCount(const ScenarioResult& /*result*/) { 195 // NOP - all reporting is handled by ReportQPS. 196 } 197 ReportQueriesPerCpuSec(const ScenarioResult &)198void RpcReporter::ReportQueriesPerCpuSec(const ScenarioResult& /*result*/) { 199 // NOP - all reporting is handled by ReportQPS. 200 } 201 202 } // namespace testing 203 } // namespace grpc 204