1313// limitations under the License.
1414
1515#include " google/cloud/bigtable/internal/operation_context.h"
16+ #include " google/cloud/bigtable/internal/metrics.h"
1617#include " absl/strings/match.h"
18+ #include " absl/strings/str_split.h"
19+ #ifdef GOOGLE_CLOUD_CPP_BIGTABLE_WITH_OTEL_METRICS
20+ #include < opentelemetry/context/runtime_context.h>
21+ #endif
1722
1823namespace google {
1924namespace cloud {
2025namespace bigtable_internal {
2126GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
2227
23- void OperationContext::PreCall (grpc::ClientContext& context) {
24- for (auto const & h : cookies_) {
25- context.AddMetadata (h.first , h.second );
28+ #ifdef GOOGLE_CLOUD_CPP_BIGTABLE_WITH_OTEL_METRICS
29+ namespace {
30+ std::vector<std::shared_ptr<Metric>> CloneMetrics (
31+ ResourceLabels const & resource_labels, DataLabels const & data_labels,
32+ std::vector<std::shared_ptr<Metric const >> const & metrics) {
33+ std::vector<std::shared_ptr<Metric>> v;
34+ v.reserve (metrics.size ());
35+ for (auto const & m : metrics) {
36+ v.emplace_back (m->clone (resource_labels, data_labels));
2637 }
27- context.AddMetadata (" bigtable-attempt" , std::to_string (attempt_number_++));
28- }
29-
30- void OperationContext::PostCall (grpc::ClientContext const & context) {
31- ProcessMetadata (context.GetServerInitialMetadata ());
32- ProcessMetadata (context.GetServerTrailingMetadata ());
38+ return v;
3339}
40+ } // namespace
41+ #endif
3442
3543void OperationContext::ProcessMetadata (
3644 std::multimap<grpc::string_ref, grpc::string_ref> const & metadata) {
@@ -43,6 +51,102 @@ void OperationContext::ProcessMetadata(
4351 }
4452}
4553
54+ #ifdef GOOGLE_CLOUD_CPP_BIGTABLE_WITH_OTEL_METRICS
55+
56+ OperationContext::OperationContext (
57+ ResourceLabels const & resource_labels, DataLabels const & data_labels,
58+ std::vector<std::shared_ptr<Metric const >> const & metrics,
59+ std::shared_ptr<Clock> clock)
60+ : cloned_metrics_(CloneMetrics(resource_labels, data_labels, metrics)),
61+ clock_(std::move(clock)) {}
62+
63+ void OperationContext::PreCall (grpc::ClientContext& client_context) {
64+ auto otel_context = opentelemetry::context::RuntimeContext::GetCurrent ();
65+ auto attempt_start = clock_->Now ();
66+ if (attempt_number_ == 0 ) {
67+ operation_start_ = attempt_start;
68+ }
69+ for (auto & m : cloned_metrics_) {
70+ m->PreCall (otel_context,
71+ PreCallParams{attempt_start, attempt_number_ == 0 });
72+ }
73+
74+ for (auto const & h : cookies_) {
75+ client_context.AddMetadata (h.first , h.second );
76+ }
77+ client_context.AddMetadata (" bigtable-attempt" ,
78+ std::to_string (attempt_number_++));
79+ }
80+
81+ void OperationContext::PostCall (grpc::ClientContext const & client_context,
82+ google::cloud::Status const & status) {
83+ ProcessMetadata (client_context.GetServerInitialMetadata ());
84+ ProcessMetadata (client_context.GetServerTrailingMetadata ());
85+ auto attempt_end = clock_->Now ();
86+ auto otel_context = opentelemetry::context::RuntimeContext::GetCurrent ();
87+ for (auto & m : cloned_metrics_) {
88+ m->PostCall (otel_context, client_context,
89+ PostCallParams{attempt_end, status});
90+ }
91+ }
92+
93+ void OperationContext::OnDone (Status const & s) {
94+ auto operation_end = clock_->Now ();
95+ auto otel_context = opentelemetry::context::RuntimeContext::GetCurrent ();
96+ for (auto & m : cloned_metrics_) {
97+ m->OnDone (otel_context, OnDoneParams{operation_end, s});
98+ }
99+ }
100+
101+ void OperationContext::ElementRequest (grpc::ClientContext const &) {
102+ auto element_request = clock_->Now ();
103+ auto otel_context = opentelemetry::context::RuntimeContext::GetCurrent ();
104+ for (auto & m : cloned_metrics_) {
105+ m->ElementRequest (otel_context, ElementRequestParams{element_request});
106+ }
107+ }
108+
109+ void OperationContext::ElementDelivery (grpc::ClientContext const &) {
110+ auto otel_context = opentelemetry::context::RuntimeContext::GetCurrent ();
111+ auto first_response = clock_->Now ();
112+ for (auto & m : cloned_metrics_) {
113+ m->ElementDelivery (otel_context,
114+ ElementDeliveryParams{first_response, first_response_});
115+ }
116+ if (first_response_) {
117+ first_response_ = false ;
118+ }
119+ }
120+
121+ #else // GOOGLE_CLOUD_CPP_BIGTABLE_WITH_OTEL_METRICS
122+
123+ OperationContext::OperationContext (
124+ ResourceLabels const &, DataLabels const &,
125+ std::vector<std::shared_ptr<Metric const >> const &, std::shared_ptr<Clock>) {
126+ }
127+
128+ void OperationContext::PreCall (grpc::ClientContext& client_context) {
129+ for (auto const & h : cookies_) {
130+ client_context.AddMetadata (h.first , h.second );
131+ }
132+ client_context.AddMetadata (" bigtable-attempt" ,
133+ std::to_string (attempt_number_++));
134+ }
135+
136+ void OperationContext::PostCall (grpc::ClientContext const & client_context,
137+ google::cloud::Status const &) {
138+ ProcessMetadata (client_context.GetServerInitialMetadata ());
139+ ProcessMetadata (client_context.GetServerTrailingMetadata ());
140+ }
141+
142+ void OperationContext::OnDone (Status const &) {}
143+
144+ void OperationContext::ElementRequest (grpc::ClientContext const &) {}
145+
146+ void OperationContext::ElementDelivery (grpc::ClientContext const &) {}
147+
148+ #endif // GOOGLE_CLOUD_CPP_BIGTABLE_WITH_OTEL_METRICS
149+
46150GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
47151} // namespace bigtable_internal
48152} // namespace cloud
0 commit comments