/proc/self/cwd/source/common/grpc/context_impl.cc
Line | Count | Source (jump to first uncovered line) |
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 | 26.5k | 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 | 52 | Stats::Element suffix) { |
30 | 52 | const Stats::StatName protocolName = protocolStatName(protocol); |
31 | 52 | if (request_names) { |
32 | 52 | return Stats::ElementVec{protocolName, request_names->service_, request_names->method_, suffix}; |
33 | 52 | } |
34 | 0 | return Stats::ElementVec{protocolName, suffix}; |
35 | 52 | } |
36 | | |
37 | | void ContextImpl::chargeStat(const Upstream::ClusterInfo& cluster, Protocol protocol, |
38 | | const absl::optional<RequestStatNames>& request_names, |
39 | 1 | const Http::HeaderEntry* grpc_status) { |
40 | 1 | if (!grpc_status) { |
41 | 1 | return; |
42 | 1 | } |
43 | | |
44 | 0 | absl::string_view status_str = grpc_status->value().getStringView(); |
45 | 0 | auto iter = stat_names_.status_names_.find(status_str); |
46 | 0 | Stats::ElementVec elements = |
47 | 0 | statElements(protocol, request_names, |
48 | 0 | (iter != stat_names_.status_names_.end()) ? Stats::Element(iter->second) |
49 | 0 | : Stats::DynamicName(status_str)); |
50 | 0 | Stats::Utility::counterFromElements(cluster.statsScope(), elements).inc(); |
51 | 0 | chargeStat(cluster, protocol, request_names, (status_str == "0")); |
52 | 0 | } |
53 | | |
54 | | void ContextImpl::chargeStat(const Upstream::ClusterInfo& cluster, Protocol protocol, |
55 | 0 | const absl::optional<RequestStatNames>& request_names, bool success) { |
56 | 0 | Stats::ElementVec elements = statElements(protocol, request_names, successStatName(success)); |
57 | 0 | Stats::Utility::counterFromElements(cluster.statsScope(), elements).inc(); |
58 | 0 | elements.back() = total_; |
59 | 0 | Stats::Utility::counterFromElements(cluster.statsScope(), elements).inc(); |
60 | 0 | } |
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 | 26 | uint64_t amount) { |
70 | 26 | Stats::ElementVec elements = statElements(Protocol::Grpc, request_names, request_message_count_); |
71 | 26 | Stats::Utility::counterFromElements(cluster.statsScope(), elements).add(amount); |
72 | 26 | } |
73 | | |
74 | | void ContextImpl::chargeResponseMessageStat(const Upstream::ClusterInfo& cluster, |
75 | | const absl::optional<RequestStatNames>& request_names, |
76 | 26 | uint64_t amount) { |
77 | 26 | Stats::ElementVec elements = statElements(Protocol::Grpc, request_names, response_message_count_); |
78 | 26 | Stats::Utility::counterFromElements(cluster.statsScope(), elements).add(amount); |
79 | 26 | } |
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 | 1 | ContextImpl::resolveDynamicServiceAndMethodWithDotReplaced(const Http::HeaderEntry* path) { |
108 | 1 | absl::optional<Common::RequestNames> request_names = Common::resolveServiceAndMethod(path); |
109 | 1 | if (!request_names) { |
110 | 0 | return {}; |
111 | 0 | } |
112 | 1 | Stats::Element service = |
113 | 1 | Stats::DynamicSavedName(absl::StrReplaceAll(request_names->service_, {{".", "_"}})); |
114 | 1 | Stats::Element method = Stats::DynamicSavedName(request_names->method_); |
115 | 1 | return RequestStatNames{service, method}; |
116 | 1 | } |
117 | | |
118 | | } // namespace Grpc |
119 | | } // namespace Envoy |