1818#include " google/cloud/bigtable/internal/data_connection_impl.h"
1919#include " google/cloud/bigtable/options.h"
2020#include " google/cloud/bigtable/version.h"
21+ #include " absl/strings/str_join.h"
22+ #include " absl/strings/str_split.h"
2123#include < opentelemetry/metrics/meter.h>
2224#include < opentelemetry/semconv/incubating/cloud_attributes.h>
2325#include < opentelemetry/semconv/incubating/faas_attributes.h>
@@ -66,8 +68,8 @@ LabelMap BaseLabels(ClientResourceLabels const& r) {
6668 return {{" project_id" , r.project_id }, {" instance" , r.instance },
6769 {" app_profile" , r.app_profile }, {" client_name" , r.client_name },
6870 {" client_uid" , r.client_uid }, {" client_project" , r.client_project },
69- {" location " , r.location }, {" cloud_platform" , r.cloud_platform },
70- {" host_id" , r.host_id }, {" hostname " , r.hostname }};
71+ {" region " , r.region }, {" cloud_platform" , r.cloud_platform },
72+ {" host_id" , r.host_id }, {" host_name " , r.host_name }};
7173}
7274} // namespace
7375
@@ -154,23 +156,35 @@ ClientResourceLabels MakeClientResourceLabels(
154156 client_project = project_id;
155157 }
156158
159+ std::string region = by_name (sc::cloud::kCloudRegion );
160+ if (region.empty ()) {
161+ std::string zone = by_name (sc::cloud::kCloudAvailabilityZone );
162+ std::vector<std::string_view> parts = absl::StrSplit (zone, ' -' );
163+ if (parts.size () >= 3 && parts.back ().size () == 1 ) {
164+ parts.pop_back ();
165+ region = absl::StrJoin (parts, " -" );
166+ } else {
167+ region = std::move (zone);
168+ }
169+ }
170+ if (region.empty ()) {
171+ region = " global" ;
172+ }
173+
157174 ClientResourceLabels labels;
158175 labels.project_id = std::move (project_id);
159176 labels.instance = std::move (instance);
160177 labels.app_profile = std::move (app_profile);
161178 labels.client_name = " cpp.Bigtable/" + bigtable::version_string ();
162179 labels.client_uid = client_uid;
163180 labels.client_project = std::move (client_project);
164- labels.location = by_name (sc::cloud::kCloudAvailabilityZone );
165- if (labels.location .empty ()) {
166- labels.location = by_name (sc::cloud::kCloudRegion , " global" );
167- }
181+ labels.region = std::move (region);
168182 labels.cloud_platform = by_name (sc::cloud::kCloudPlatform , " unknown" );
169183 labels.host_id = by_name (" faas.id" );
170184 if (labels.host_id .empty ()) {
171185 labels.host_id = by_name (sc::host::kHostId , " unknown" );
172186 }
173- labels.hostname = by_name (sc::host::kHostName );
187+ labels.host_name = by_name (sc::host::kHostName );
174188 return labels;
175189}
176190
@@ -193,9 +207,16 @@ void OutstandingRpcs::StubSelection(
193207 StubSelectionParams const & p) {
194208 ClientOutstandingRpcLabels data_labels{p.transport_type ,
195209 p.channel_pool_lb_policy , p.streaming };
196- outstanding_rpcs_->Record (static_cast <double >(p.outstanding_rpcs ),
197- IntoLabelMap (resource_labels_, data_labels, {}),
198- context);
210+ // `channel_pool_lb_policy` is filtered out because the Cloud Monitoring
211+ // metric descriptor for
212+ // `bigtable.googleapis.com/internal/client/connection_pool/outstanding_rpcs`
213+ // does not recognize this label.
214+ static auto const * const kFilteredDataLabels =
215+ new std::set<std::string>{" channel_pool_lb_policy" };
216+ outstanding_rpcs_->Record (
217+ static_cast <double >(p.outstanding_rpcs ),
218+ IntoLabelMap (resource_labels_, data_labels, *kFilteredDataLabels ),
219+ context);
199220}
200221
201222std::unique_ptr<ClientSchemaMetric> OutstandingRpcs::clone (
@@ -205,41 +226,92 @@ std::unique_ptr<ClientSchemaMetric> OutstandingRpcs::clone(
205226 return m;
206227}
207228
229+ #if OPENTELEMETRY_ABI_VERSION_NO >= 2
208230DirectAccessCompatibility::DirectAccessCompatibility (
209231 std::string const & instrumentation_scope,
210232 opentelemetry::nostd::shared_ptr<
211- opentelemetry::metrics::MeterProvider> const & provider)
212- : gauge_(
213- #if OPENTELEMETRY_ABI_VERSION_NO >= 2
214- provider
215- ->GetMeter (instrumentation_scope,
216- kMeterInstrumentationScopeVersion )
217- ->CreateInt64Gauge(
218- " direct_access/compatible" ,
219- " Compatibility check result for Bigtable DirectPath." , " 1" )
220- #else
221- provider
222- ->GetMeter (instrumentation_scope,
223- kMeterInstrumentationScopeVersion )
224- ->CreateDoubleHistogram(
225- " direct_access/compatible" ,
226- " Compatibility check result for Bigtable DirectPath." , " 1" )
227- #endif
228- ) {
229- }
233+ opentelemetry::metrics::MeterProvider> const & provider,
234+ ClientResourceLabels resource_labels)
235+ : resource_labels_(std::move(resource_labels)),
236+ gauge_(provider
237+ ->GetMeter (instrumentation_scope,
238+ kMeterInstrumentationScopeVersion )
239+ ->CreateInt64Gauge(
240+ " direct_access/compatible" ,
241+ " Compatibility check result for Bigtable DirectPath." ,
242+ " 1" )) {}
230243
231244void DirectAccessCompatibility::Record (
232245 opentelemetry::context::Context const & context, std::int64_t value,
233246 DirectAccessCompatibilityLabels const & data_labels) {
234- #if OPENTELEMETRY_ABI_VERSION_NO >= 2
235- gauge_->Record (value, IntoLabelMap (resource_labels_, data_labels, {}),
236- context);
247+ if (gauge_ == nullptr ) return ;
248+ LabelMap const labels = IntoLabelMap (resource_labels_, data_labels, {});
249+ gauge_->Record (value, labels, context);
250+ }
237251#else
238- gauge_->Record (static_cast <double >(value),
239- IntoLabelMap (resource_labels_, data_labels, {}), context);
240- #endif
252+ void DirectAccessCompatibility::ObserveCallback (
253+ opentelemetry::metrics::ObserverResult observer_result, void * state_ptr) {
254+ auto * state = static_cast <State*>(state_ptr);
255+ if (state == nullptr ) return ;
256+ std::lock_guard<std::mutex> lk (state->mu );
257+ if (!state->has_value ) return ;
258+
259+ if (opentelemetry::nostd::holds_alternative<opentelemetry::nostd::shared_ptr<
260+ opentelemetry::metrics::ObserverResultT<std::int64_t > > >(
261+ observer_result)) {
262+ auto observer = opentelemetry::nostd::get<opentelemetry::nostd::shared_ptr<
263+ opentelemetry::metrics::ObserverResultT<std::int64_t > > >(
264+ observer_result);
265+ observer->Observe (state->value , state->labels );
266+ }
267+ }
268+
269+ DirectAccessCompatibility::DirectAccessCompatibility (
270+ std::string const & instrumentation_scope,
271+ opentelemetry::nostd::shared_ptr<
272+ opentelemetry::metrics::MeterProvider> const & provider,
273+ ClientResourceLabels resource_labels)
274+ : resource_labels_(std::move(resource_labels)),
275+ state_(std::make_shared<State>()),
276+ gauge_(provider
277+ ->GetMeter (instrumentation_scope,
278+ kMeterInstrumentationScopeVersion )
279+ ->CreateInt64ObservableGauge(
280+ " direct_access/compatible" ,
281+ " Compatibility check result for Bigtable DirectPath." ,
282+ " 1" )) {
283+ if (gauge_ != nullptr ) {
284+ gauge_->AddCallback (ObserveCallback, state_.get ());
285+ }
286+ }
287+
288+ DirectAccessCompatibility::~DirectAccessCompatibility () {
289+ if (gauge_ != nullptr ) {
290+ gauge_->RemoveCallback (ObserveCallback, state_.get ());
291+ }
292+ }
293+
294+ DirectAccessCompatibility::DirectAccessCompatibility (
295+ DirectAccessCompatibility const & other)
296+ : resource_labels_(other.resource_labels_),
297+ state_(std::make_shared<State>()),
298+ gauge_(other.gauge_) {
299+ if (gauge_ != nullptr ) {
300+ gauge_->AddCallback (ObserveCallback, state_.get ());
301+ }
241302}
242303
304+ void DirectAccessCompatibility::Record (
305+ opentelemetry::context::Context const &, std::int64_t value,
306+ DirectAccessCompatibilityLabels const & data_labels) {
307+ LabelMap labels = IntoLabelMap (resource_labels_, data_labels, {});
308+ std::lock_guard<std::mutex> lk (state_->mu );
309+ state_->value = value;
310+ state_->labels = std::move (labels);
311+ state_->has_value = true ;
312+ }
313+ #endif
314+
243315std::unique_ptr<ClientSchemaMetric> DirectAccessCompatibility::clone (
244316 ClientResourceLabels const & resource_labels) const {
245317 auto m = std::make_unique<DirectAccessCompatibility>(*this );
0 commit comments