LCOV - code coverage report
Current view: top level - source/common/grpc - context_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 29 63 46.0 %
Date: 2024-01-05 06:35:25 Functions: 5 10 50.0 %

          Line data    Source code
       1             : #include "source/common/grpc/context_impl.h"
       2             : 
       3             : #include <cstdint>
       4             : #include <memory>
       5             : #include <string>
       6             : #include <tuple>
       7             : #include <utility>
       8             : 
       9             : #include "source/common/grpc/common.h"
      10             : #include "source/common/stats/utility.h"
      11             : 
      12             : #include "absl/strings/str_replace.h"
      13             : 
      14             : namespace Envoy {
      15             : namespace Grpc {
      16             : 
      17             : ContextImpl::ContextImpl(Stats::SymbolTable& symbol_table)
      18             :     : stat_name_pool_(symbol_table), grpc_(stat_name_pool_.add("grpc")),
      19             :       grpc_web_(stat_name_pool_.add("grpc-web")), success_(stat_name_pool_.add("success")),
      20             :       failure_(stat_name_pool_.add("failure")), total_(stat_name_pool_.add("total")),
      21             :       zero_(stat_name_pool_.add("0")),
      22             :       request_message_count_(stat_name_pool_.add("request_message_count")),
      23             :       response_message_count_(stat_name_pool_.add("response_message_count")),
      24         481 :       upstream_rq_time_(stat_name_pool_.add("upstream_rq_time")), stat_names_(symbol_table) {}
      25             : 
      26             : // Gets the stat prefix and underlying storage, depending on whether request_names is empty
      27             : Stats::ElementVec ContextImpl::statElements(Protocol protocol,
      28             :                                             const absl::optional<RequestStatNames>& request_names,
      29           3 :                                             Stats::Element suffix) {
      30           3 :   const Stats::StatName protocolName = protocolStatName(protocol);
      31           3 :   if (request_names) {
      32           0 :     return Stats::ElementVec{protocolName, request_names->service_, request_names->method_, suffix};
      33           0 :   }
      34           3 :   return Stats::ElementVec{protocolName, suffix};
      35           3 : }
      36             : 
      37             : void ContextImpl::chargeStat(const Upstream::ClusterInfo& cluster, Protocol protocol,
      38             :                              const absl::optional<RequestStatNames>& request_names,
      39           2 :                              const Http::HeaderEntry* grpc_status) {
      40           2 :   if (!grpc_status) {
      41           1 :     return;
      42           1 :   }
      43             : 
      44           1 :   absl::string_view status_str = grpc_status->value().getStringView();
      45           1 :   auto iter = stat_names_.status_names_.find(status_str);
      46           1 :   Stats::ElementVec elements =
      47           1 :       statElements(protocol, request_names,
      48           1 :                    (iter != stat_names_.status_names_.end()) ? Stats::Element(iter->second)
      49           1 :                                                              : Stats::DynamicName(status_str));
      50           1 :   Stats::Utility::counterFromElements(cluster.statsScope(), elements).inc();
      51           1 :   chargeStat(cluster, protocol, request_names, (status_str == "0"));
      52           1 : }
      53             : 
      54             : void ContextImpl::chargeStat(const Upstream::ClusterInfo& cluster, Protocol protocol,
      55           1 :                              const absl::optional<RequestStatNames>& request_names, bool success) {
      56           1 :   Stats::ElementVec elements = statElements(protocol, request_names, successStatName(success));
      57           1 :   Stats::Utility::counterFromElements(cluster.statsScope(), elements).inc();
      58           1 :   elements.back() = total_;
      59           1 :   Stats::Utility::counterFromElements(cluster.statsScope(), elements).inc();
      60           1 : }
      61             : 
      62             : void ContextImpl::chargeStat(const Upstream::ClusterInfo& cluster,
      63           0 :                              const absl::optional<RequestStatNames>& request_names, bool success) {
      64           0 :   chargeStat(cluster, Protocol::Grpc, request_names, success);
      65           0 : }
      66             : 
      67             : void ContextImpl::chargeRequestMessageStat(const Upstream::ClusterInfo& cluster,
      68             :                                            const absl::optional<RequestStatNames>& request_names,
      69           0 :                                            uint64_t amount) {
      70           0 :   Stats::ElementVec elements = statElements(Protocol::Grpc, request_names, request_message_count_);
      71           0 :   Stats::Utility::counterFromElements(cluster.statsScope(), elements).add(amount);
      72           0 : }
      73             : 
      74             : void ContextImpl::chargeResponseMessageStat(const Upstream::ClusterInfo& cluster,
      75             :                                             const absl::optional<RequestStatNames>& request_names,
      76           1 :                                             uint64_t amount) {
      77           1 :   Stats::ElementVec elements = statElements(Protocol::Grpc, request_names, response_message_count_);
      78           1 :   Stats::Utility::counterFromElements(cluster.statsScope(), elements).add(amount);
      79           1 : }
      80             : 
      81             : void ContextImpl::chargeUpstreamStat(const Upstream::ClusterInfo& cluster,
      82             :                                      const absl::optional<RequestStatNames>& request_names,
      83           0 :                                      std::chrono::milliseconds duration) {
      84           0 :   Stats::ElementVec elements = statElements(Protocol::Grpc, request_names, upstream_rq_time_);
      85           0 :   Stats::Utility::histogramFromElements(cluster.statsScope(), elements,
      86           0 :                                         Stats::Histogram::Unit::Milliseconds)
      87           0 :       .recordValue(duration.count());
      88           0 : }
      89             : 
      90             : absl::optional<ContextImpl::RequestStatNames>
      91           0 : ContextImpl::resolveDynamicServiceAndMethod(const Http::HeaderEntry* path) {
      92           0 :   absl::optional<Common::RequestNames> request_names = Common::resolveServiceAndMethod(path);
      93             : 
      94           0 :   if (!request_names) {
      95           0 :     return {};
      96           0 :   }
      97             : 
      98             :   // service/method will live until the request is finished to emit resulting stats (e.g. request
      99             :   // status) values in request_names_ might get changed, for example by routing rules (i.e.
     100             :   // "prefix_rewrite"), so we copy them here to preserve the initial value and get a proper stat
     101           0 :   Stats::Element service = Stats::DynamicSavedName(request_names->service_);
     102           0 :   Stats::Element method = Stats::DynamicSavedName(request_names->method_);
     103           0 :   return RequestStatNames{service, method};
     104           0 : }
     105             : 
     106             : absl::optional<ContextImpl::RequestStatNames>
     107           0 : ContextImpl::resolveDynamicServiceAndMethodWithDotReplaced(const Http::HeaderEntry* path) {
     108           0 :   absl::optional<Common::RequestNames> request_names = Common::resolveServiceAndMethod(path);
     109           0 :   if (!request_names) {
     110           0 :     return {};
     111           0 :   }
     112           0 :   Stats::Element service =
     113           0 :       Stats::DynamicSavedName(absl::StrReplaceAll(request_names->service_, {{".", "_"}}));
     114           0 :   Stats::Element method = Stats::DynamicSavedName(request_names->method_);
     115           0 :   return RequestStatNames{service, method};
     116           0 : }
     117             : 
     118             : } // namespace Grpc
     119             : } // namespace Envoy

Generated by: LCOV version 1.15