1 /*
2 *
3 * Copyright 2018 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 <grpc/support/port_platform.h>
20
21 #include "src/core/ext/xds/xds_client_stats.h"
22
23 #include <string.h>
24
25 #include <grpc/support/atm.h>
26 #include <grpc/support/string_util.h>
27
28 #include "src/core/ext/xds/xds_client.h"
29
30 namespace grpc_core {
31
32 namespace {
33
GetAndResetCounter(Atomic<uint64_t> * from)34 uint64_t GetAndResetCounter(Atomic<uint64_t>* from) {
35 return from->Exchange(0, MemoryOrder::RELAXED);
36 }
37
38 } // namespace
39
40 //
41 // XdsClusterDropStats
42 //
43
XdsClusterDropStats(RefCountedPtr<XdsClient> xds_client,absl::string_view lrs_server_name,absl::string_view cluster_name,absl::string_view eds_service_name)44 XdsClusterDropStats::XdsClusterDropStats(RefCountedPtr<XdsClient> xds_client,
45 absl::string_view lrs_server_name,
46 absl::string_view cluster_name,
47 absl::string_view eds_service_name)
48 : RefCounted(GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
49 ? "XdsClusterDropStats"
50 : nullptr),
51 xds_client_(std::move(xds_client)),
52 lrs_server_name_(lrs_server_name),
53 cluster_name_(cluster_name),
54 eds_service_name_(eds_service_name) {
55 if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
56 gpr_log(GPR_INFO, "[xds_client %p] created drop stats %p for {%s, %s, %s}",
57 xds_client_.get(), this, std::string(lrs_server_name_).c_str(),
58 std::string(cluster_name_).c_str(),
59 std::string(eds_service_name_).c_str());
60 }
61 }
62
~XdsClusterDropStats()63 XdsClusterDropStats::~XdsClusterDropStats() {
64 if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
65 gpr_log(GPR_INFO,
66 "[xds_client %p] destroying drop stats %p for {%s, %s, %s}",
67 xds_client_.get(), this, std::string(lrs_server_name_).c_str(),
68 std::string(cluster_name_).c_str(),
69 std::string(eds_service_name_).c_str());
70 }
71 xds_client_->RemoveClusterDropStats(lrs_server_name_, cluster_name_,
72 eds_service_name_, this);
73 xds_client_.reset(DEBUG_LOCATION, "DropStats");
74 }
75
GetSnapshotAndReset()76 XdsClusterDropStats::Snapshot XdsClusterDropStats::GetSnapshotAndReset() {
77 Snapshot snapshot;
78 snapshot.uncategorized_drops = GetAndResetCounter(&uncategorized_drops_);
79 MutexLock lock(&mu_);
80 snapshot.categorized_drops = std::move(categorized_drops_);
81 return snapshot;
82 }
83
AddUncategorizedDrops()84 void XdsClusterDropStats::AddUncategorizedDrops() {
85 uncategorized_drops_.FetchAdd(1);
86 }
87
AddCallDropped(const std::string & category)88 void XdsClusterDropStats::AddCallDropped(const std::string& category) {
89 MutexLock lock(&mu_);
90 ++categorized_drops_[category];
91 }
92
93 //
94 // XdsClusterLocalityStats
95 //
96
XdsClusterLocalityStats(RefCountedPtr<XdsClient> xds_client,absl::string_view lrs_server_name,absl::string_view cluster_name,absl::string_view eds_service_name,RefCountedPtr<XdsLocalityName> name)97 XdsClusterLocalityStats::XdsClusterLocalityStats(
98 RefCountedPtr<XdsClient> xds_client, absl::string_view lrs_server_name,
99 absl::string_view cluster_name, absl::string_view eds_service_name,
100 RefCountedPtr<XdsLocalityName> name)
101 : RefCounted(GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
102 ? "XdsClusterLocalityStats"
103 : nullptr),
104 xds_client_(std::move(xds_client)),
105 lrs_server_name_(lrs_server_name),
106 cluster_name_(cluster_name),
107 eds_service_name_(eds_service_name),
108 name_(std::move(name)) {
109 if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
110 gpr_log(GPR_INFO,
111 "[xds_client %p] created locality stats %p for {%s, %s, %s, %s}",
112 xds_client_.get(), this, std::string(lrs_server_name_).c_str(),
113 std::string(cluster_name_).c_str(),
114 std::string(eds_service_name_).c_str(),
115 name_->AsHumanReadableString().c_str());
116 }
117 }
118
~XdsClusterLocalityStats()119 XdsClusterLocalityStats::~XdsClusterLocalityStats() {
120 if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
121 gpr_log(GPR_INFO,
122 "[xds_client %p] destroying locality stats %p for {%s, %s, %s, %s}",
123 xds_client_.get(), this, std::string(lrs_server_name_).c_str(),
124 std::string(cluster_name_).c_str(),
125 std::string(eds_service_name_).c_str(),
126 name_->AsHumanReadableString().c_str());
127 }
128 xds_client_->RemoveClusterLocalityStats(lrs_server_name_, cluster_name_,
129 eds_service_name_, name_, this);
130 xds_client_.reset(DEBUG_LOCATION, "LocalityStats");
131 }
132
133 XdsClusterLocalityStats::Snapshot
GetSnapshotAndReset()134 XdsClusterLocalityStats::GetSnapshotAndReset() {
135 Snapshot snapshot = {GetAndResetCounter(&total_successful_requests_),
136 // Don't reset total_requests_in_progress because it's
137 // not related to a single reporting interval.
138 total_requests_in_progress_.Load(MemoryOrder::RELAXED),
139 GetAndResetCounter(&total_error_requests_),
140 GetAndResetCounter(&total_issued_requests_)};
141 MutexLock lock(&backend_metrics_mu_);
142 snapshot.backend_metrics = std::move(backend_metrics_);
143 return snapshot;
144 }
145
AddCallStarted()146 void XdsClusterLocalityStats::AddCallStarted() {
147 total_issued_requests_.FetchAdd(1, MemoryOrder::RELAXED);
148 total_requests_in_progress_.FetchAdd(1, MemoryOrder::RELAXED);
149 }
150
AddCallFinished(bool fail)151 void XdsClusterLocalityStats::AddCallFinished(bool fail) {
152 Atomic<uint64_t>& to_increment =
153 fail ? total_error_requests_ : total_successful_requests_;
154 to_increment.FetchAdd(1, MemoryOrder::RELAXED);
155 total_requests_in_progress_.FetchAdd(-1, MemoryOrder::ACQ_REL);
156 }
157
158 } // namespace grpc_core
159