From c6b38cd63349329d47f20d5c798d66073cf20b40 Mon Sep 17 00:00:00 2001 From: Dimitris Christodoulou Date: Wed, 14 Jan 2026 16:49:37 +0000 Subject: [PATCH] RCBC-527: Include child spans created by the C++ core --- ext/rcb_analytics.cxx | 204 ++++++-- ext/rcb_buckets.cxx | 55 +- ext/rcb_collections.cxx | 48 +- ext/rcb_crud.cxx | 156 ++++-- ext/rcb_observability.cxx | 81 +-- ext/rcb_observability.hxx | 14 + ext/rcb_query.cxx | 102 +++- ext/rcb_search.cxx | 123 +++-- ext/rcb_users.cxx | 95 +++- ext/rcb_views.cxx | 46 +- lib/couchbase/binary_collection.rb | 59 ++- lib/couchbase/bucket.rb | 4 +- lib/couchbase/cluster.rb | 13 +- lib/couchbase/collection.rb | 52 +- .../management/analytics_index_manager.rb | 56 +- lib/couchbase/management/bucket_manager.rb | 20 +- .../management/collection_manager.rb | 16 +- .../collection_query_index_manager.rb | 25 +- .../management/query_index_manager.rb | 12 +- .../management/scope_search_index_manager.rb | 50 +- .../management/search_index_manager.rb | 58 +- lib/couchbase/management/user_manager.rb | 42 +- .../management/view_index_manager.rb | 24 +- lib/couchbase/scope.rb | 10 +- lib/couchbase/utils/observability.rb | 5 +- test/query_index_manager_test.rb | 24 +- test/tracing_test.rb | 494 +++++++++++++++++- test/utils/tracing.rb | 139 ++++- 28 files changed, 1543 insertions(+), 484 deletions(-) diff --git a/ext/rcb_analytics.cxx b/ext/rcb_analytics.cxx index a6f6bcc1..22d68b99 100644 --- a/ext/rcb_analytics.cxx +++ b/ext/rcb_analytics.cxx @@ -44,6 +44,7 @@ #include #include "rcb_backend.hxx" +#include "rcb_observability.hxx" #include "rcb_utils.hxx" namespace couchbase::ruby @@ -51,19 +52,23 @@ namespace couchbase::ruby namespace { VALUE -cb_Backend_analytics_get_pending_mutations(VALUE self, VALUE options) +cb_Backend_analytics_get_pending_mutations(VALUE self, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::analytics_get_pending_mutations_request req{}; cb_extract_timeout(req, options); + + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, "unable to get pending mutations for the analytics service"); @@ -91,19 +96,23 @@ cb_Backend_analytics_get_pending_mutations(VALUE self, VALUE options) } VALUE -cb_Backend_analytics_dataset_get_all(VALUE self, VALUE options) +cb_Backend_analytics_dataset_get_all(VALUE self, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::analytics_dataset_get_all_request req{}; cb_extract_timeout(req, options); + + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, "unable to fetch all datasets"); @@ -135,7 +144,10 @@ cb_Backend_analytics_dataset_get_all(VALUE self, VALUE options) } VALUE -cb_Backend_analytics_dataset_drop(VALUE self, VALUE dataset_name, VALUE options) +cb_Backend_analytics_dataset_drop(VALUE self, + VALUE dataset_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -151,13 +163,19 @@ cb_Backend_analytics_dataset_drop(VALUE self, VALUE dataset_name, VALUE options) req.dataverse_name = cb_string_new(dataverse_name); } cb_extract_option_bool(req.ignore_if_does_not_exist, options, "ignore_if_does_not_exist"); + + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error( resp.ctx, @@ -186,7 +204,8 @@ VALUE cb_Backend_analytics_dataset_create(VALUE self, VALUE dataset_name, VALUE bucket_name, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -201,13 +220,17 @@ cb_Backend_analytics_dataset_create(VALUE self, cb_extract_option_string(req.condition, options, "condition"); cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); cb_extract_option_bool(req.ignore_if_exists, options, "ignore_if_exists"); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error( resp.ctx, @@ -233,7 +256,10 @@ cb_Backend_analytics_dataset_create(VALUE self, } VALUE -cb_Backend_analytics_dataverse_drop(VALUE self, VALUE dataverse_name, VALUE options) +cb_Backend_analytics_dataverse_drop(VALUE self, + VALUE dataverse_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -244,12 +270,15 @@ cb_Backend_analytics_dataverse_drop(VALUE self, VALUE dataverse_name, VALUE opti cb_extract_timeout(req, options); req.dataverse_name = cb_string_new(dataverse_name); cb_extract_option_bool(req.ignore_if_does_not_exist, options, "ignore_if_does_not_exist"); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to drop dataverse `{}`", req.dataverse_name)); } else { @@ -272,7 +301,10 @@ cb_Backend_analytics_dataverse_drop(VALUE self, VALUE dataverse_name, VALUE opti } VALUE -cb_Backend_analytics_dataverse_create(VALUE self, VALUE dataverse_name, VALUE options) +cb_Backend_analytics_dataverse_create(VALUE self, + VALUE dataverse_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -286,12 +318,15 @@ cb_Backend_analytics_dataverse_create(VALUE self, VALUE dataverse_name, VALUE op cb_extract_timeout(req, options); req.dataverse_name = cb_string_new(dataverse_name); cb_extract_option_bool(req.ignore_if_exists, options, "ignore_if_exists"); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to create dataverse `{}`", req.dataverse_name)); @@ -315,19 +350,21 @@ cb_Backend_analytics_dataverse_create(VALUE self, VALUE dataverse_name, VALUE op } VALUE -cb_Backend_analytics_index_get_all(VALUE self, VALUE options) +cb_Backend_analytics_index_get_all(VALUE self, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::analytics_index_get_all_request req{}; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, "unable to fetch all indexes"); @@ -363,7 +400,8 @@ cb_Backend_analytics_index_create(VALUE self, VALUE index_name, VALUE dataset_name, VALUE fields, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -389,12 +427,17 @@ cb_Backend_analytics_index_create(VALUE self, cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); cb_extract_option_bool(req.ignore_if_exists, options, "ignore_if_exists"); + + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to create index `{}` on `{}`.`{}`", @@ -423,7 +466,11 @@ cb_Backend_analytics_index_create(VALUE self, } VALUE -cb_Backend_analytics_index_drop(VALUE self, VALUE index_name, VALUE dataset_name, VALUE options) +cb_Backend_analytics_index_drop(VALUE self, + VALUE index_name, + VALUE dataset_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -437,12 +484,15 @@ cb_Backend_analytics_index_drop(VALUE self, VALUE index_name, VALUE dataset_name req.dataset_name = cb_string_new(dataset_name); cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); cb_extract_option_bool(req.ignore_if_does_not_exist, options, "ignore_if_does_not_exist"); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to drop index `{}`.`{}`.`{}`", @@ -471,7 +521,7 @@ cb_Backend_analytics_index_drop(VALUE self, VALUE index_name, VALUE dataset_name } VALUE -cb_Backend_analytics_link_connect(VALUE self, VALUE options) +cb_Backend_analytics_link_connect(VALUE self, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -481,13 +531,17 @@ cb_Backend_analytics_link_connect(VALUE self, VALUE options) cb_extract_option_string(req.link_name, options, "link_name"); cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); cb_extract_option_bool(req.force, options, "force"); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error( resp.ctx, @@ -513,7 +567,7 @@ cb_Backend_analytics_link_connect(VALUE self, VALUE options) } VALUE -cb_Backend_analytics_link_disconnect(VALUE self, VALUE options) +cb_Backend_analytics_link_disconnect(VALUE self, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -522,12 +576,17 @@ cb_Backend_analytics_link_disconnect(VALUE self, VALUE options) cb_extract_timeout(req, options); cb_extract_option_string(req.link_name, options, "link_name"); cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error( resp.ctx, @@ -603,7 +662,7 @@ cb_fill_link(core::management::analytics::s3_external_link& dst, VALUE src) } VALUE -cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) +cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -621,13 +680,18 @@ cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to create couchbase_remote link `{}` on `{}`", @@ -651,13 +715,18 @@ cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to create azure_blob_external link `{}` on `{}`", @@ -682,13 +751,18 @@ cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to create s3_external link `{}` on `{}`", @@ -717,7 +791,10 @@ cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) } VALUE -cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) +cb_Backend_analytics_link_replace(VALUE self, + VALUE link, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -736,13 +813,18 @@ cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to replace couchbase_remote link `{}` on `{}`", @@ -767,13 +849,18 @@ cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to replace azure_blob_external link `{}` on `{}`", @@ -798,13 +885,18 @@ cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to replace s3_external link `{}` on `{}`", @@ -833,7 +925,11 @@ cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) } VALUE -cb_Backend_analytics_link_drop(VALUE self, VALUE link, VALUE dataverse, VALUE options) +cb_Backend_analytics_link_drop(VALUE self, + VALUE link, + VALUE dataverse, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -850,13 +946,18 @@ cb_Backend_analytics_link_drop(VALUE self, VALUE link, VALUE dataverse, VALUE op req.link_name = cb_string_new(link); req.dataverse_name = cb_string_new(dataverse); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + + if (resp.ctx.ec) { if (resp.errors.empty()) { cb_throw_error( resp.ctx, @@ -883,7 +984,7 @@ cb_Backend_analytics_link_drop(VALUE self, VALUE link, VALUE dataverse, VALUE op } VALUE -cb_Backend_analytics_link_get_all(VALUE self, VALUE options) +cb_Backend_analytics_link_get_all(VALUE self, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -899,12 +1000,15 @@ cb_Backend_analytics_link_get_all(VALUE self, VALUE options) cb_extract_option_string(req.link_name, options, "link_name"); cb_extract_option_string(req.dataverse_name, options, "dataverse"); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.errors.empty()) { @@ -1029,7 +1133,10 @@ cb_for_each_named_param_analytics(VALUE key, VALUE value, VALUE arg) } VALUE -cb_Backend_document_analytics(VALUE self, VALUE statement, VALUE options) +cb_Backend_document_analytics(VALUE self, + VALUE statement, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1103,12 +1210,15 @@ cb_Backend_document_analytics(VALUE self, VALUE statement, VALUE options) rb_hash_foreach(raw_params, cb_for_each_named_param_analytics, reinterpret_cast(&req)); } + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.meta.errors.empty()) { const auto& first_error = resp.meta.errors.front(); @@ -1171,25 +1281,25 @@ cb_Backend_document_analytics(VALUE self, VALUE statement, VALUE options) void init_analytics(VALUE cBackend) { - rb_define_method(cBackend, "document_analytics", cb_Backend_document_analytics, 2); + rb_define_method(cBackend, "document_analytics", cb_Backend_document_analytics, 3); // Management APIs rb_define_method( - cBackend, "analytics_get_pending_mutations", cb_Backend_analytics_get_pending_mutations, 1); - rb_define_method(cBackend, "analytics_dataverse_drop", cb_Backend_analytics_dataverse_drop, 2); + cBackend, "analytics_get_pending_mutations", cb_Backend_analytics_get_pending_mutations, 2); + rb_define_method(cBackend, "analytics_dataverse_drop", cb_Backend_analytics_dataverse_drop, 3); rb_define_method( - cBackend, "analytics_dataverse_create", cb_Backend_analytics_dataverse_create, 2); - rb_define_method(cBackend, "analytics_dataset_create", cb_Backend_analytics_dataset_create, 3); - rb_define_method(cBackend, "analytics_dataset_drop", cb_Backend_analytics_dataset_drop, 2); - rb_define_method(cBackend, "analytics_dataset_get_all", cb_Backend_analytics_dataset_get_all, 1); - rb_define_method(cBackend, "analytics_index_get_all", cb_Backend_analytics_index_get_all, 1); - rb_define_method(cBackend, "analytics_index_create", cb_Backend_analytics_index_create, 4); - rb_define_method(cBackend, "analytics_index_drop", cb_Backend_analytics_index_drop, 3); - rb_define_method(cBackend, "analytics_link_connect", cb_Backend_analytics_link_connect, 1); - rb_define_method(cBackend, "analytics_link_disconnect", cb_Backend_analytics_link_disconnect, 1); - rb_define_method(cBackend, "analytics_link_create", cb_Backend_analytics_link_create, 2); - rb_define_method(cBackend, "analytics_link_replace", cb_Backend_analytics_link_replace, 2); - rb_define_method(cBackend, "analytics_link_drop", cb_Backend_analytics_link_drop, 3); - rb_define_method(cBackend, "analytics_link_get_all", cb_Backend_analytics_link_get_all, 1); + cBackend, "analytics_dataverse_create", cb_Backend_analytics_dataverse_create, 3); + rb_define_method(cBackend, "analytics_dataset_create", cb_Backend_analytics_dataset_create, 4); + rb_define_method(cBackend, "analytics_dataset_drop", cb_Backend_analytics_dataset_drop, 3); + rb_define_method(cBackend, "analytics_dataset_get_all", cb_Backend_analytics_dataset_get_all, 2); + rb_define_method(cBackend, "analytics_index_get_all", cb_Backend_analytics_index_get_all, 2); + rb_define_method(cBackend, "analytics_index_create", cb_Backend_analytics_index_create, 5); + rb_define_method(cBackend, "analytics_index_drop", cb_Backend_analytics_index_drop, 4); + rb_define_method(cBackend, "analytics_link_connect", cb_Backend_analytics_link_connect, 2); + rb_define_method(cBackend, "analytics_link_disconnect", cb_Backend_analytics_link_disconnect, 2); + rb_define_method(cBackend, "analytics_link_create", cb_Backend_analytics_link_create, 3); + rb_define_method(cBackend, "analytics_link_replace", cb_Backend_analytics_link_replace, 3); + rb_define_method(cBackend, "analytics_link_drop", cb_Backend_analytics_link_drop, 4); + rb_define_method(cBackend, "analytics_link_get_all", cb_Backend_analytics_link_get_all, 2); } } // namespace couchbase::ruby diff --git a/ext/rcb_buckets.cxx b/ext/rcb_buckets.cxx index cb9ff6f8..c078c698 100644 --- a/ext/rcb_buckets.cxx +++ b/ext/rcb_buckets.cxx @@ -32,6 +32,7 @@ #include #include "rcb_backend.hxx" +#include "rcb_observability.hxx" #include "rcb_utils.hxx" namespace couchbase::ruby @@ -273,7 +274,10 @@ cb_generate_bucket_settings(VALUE bucket, } VALUE -cb_Backend_bucket_create(VALUE self, VALUE bucket_settings, VALUE options) +cb_Backend_bucket_create(VALUE self, + VALUE bucket_settings, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -286,12 +290,15 @@ cb_Backend_bucket_create(VALUE self, VALUE bucket_settings, VALUE options) core::operations::management::bucket_create_request req{}; cb_extract_timeout(req, options); cb_generate_bucket_settings(bucket_settings, req.bucket, true); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format("unable to create bucket \"{}\" on the cluster ({})", req.bucket.name, @@ -309,7 +316,10 @@ cb_Backend_bucket_create(VALUE self, VALUE bucket_settings, VALUE options) } VALUE -cb_Backend_bucket_update(VALUE self, VALUE bucket_settings, VALUE options) +cb_Backend_bucket_update(VALUE self, + VALUE bucket_settings, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -321,12 +331,15 @@ cb_Backend_bucket_update(VALUE self, VALUE bucket_settings, VALUE options) core::operations::management::bucket_update_request req{}; cb_extract_timeout(req, options); cb_generate_bucket_settings(bucket_settings, req.bucket, false); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format("unable to update bucket \"{}\" on the cluster ({})", req.bucket.name, @@ -343,7 +356,7 @@ cb_Backend_bucket_update(VALUE self, VALUE bucket_settings, VALUE options) } VALUE -cb_Backend_bucket_drop(VALUE self, VALUE bucket_name, VALUE options) +cb_Backend_bucket_drop(VALUE self, VALUE bucket_name, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -355,12 +368,15 @@ cb_Backend_bucket_drop(VALUE self, VALUE bucket_name, VALUE options) try { core::operations::management::bucket_drop_request req{ cb_string_new(bucket_name) }; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format("unable to remove bucket \"{}\" on the cluster", req.name)); } @@ -375,7 +391,7 @@ cb_Backend_bucket_drop(VALUE self, VALUE bucket_name, VALUE options) } VALUE -cb_Backend_bucket_flush(VALUE self, VALUE bucket_name, VALUE options) +cb_Backend_bucket_flush(VALUE self, VALUE bucket_name, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -387,12 +403,15 @@ cb_Backend_bucket_flush(VALUE self, VALUE bucket_name, VALUE options) try { core::operations::management::bucket_flush_request req{ cb_string_new(bucket_name) }; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format("unable to flush bucket \"{}\" on the cluster", req.name)); } @@ -562,7 +581,7 @@ cb_extract_bucket_settings(const core::management::cluster::bucket_settings& ent } VALUE -cb_Backend_bucket_get_all(VALUE self, VALUE options) +cb_Backend_bucket_get_all(VALUE self, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -573,12 +592,14 @@ cb_Backend_bucket_get_all(VALUE self, VALUE options) try { core::operations::management::bucket_get_all_request req{}; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, "unable to get list of the buckets of the cluster"); } @@ -601,7 +622,7 @@ cb_Backend_bucket_get_all(VALUE self, VALUE options) } VALUE -cb_Backend_bucket_get(VALUE self, VALUE bucket_name, VALUE options) +cb_Backend_bucket_get(VALUE self, VALUE bucket_name, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -613,12 +634,14 @@ cb_Backend_bucket_get(VALUE self, VALUE bucket_name, VALUE options) try { core::operations::management::bucket_get_request req{ cb_string_new(bucket_name) }; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format("unable to locate bucket \"{}\" on the cluster", req.name)); @@ -640,11 +663,11 @@ cb_Backend_bucket_get(VALUE self, VALUE bucket_name, VALUE options) void init_buckets(VALUE cBackend) { - rb_define_method(cBackend, "bucket_create", cb_Backend_bucket_create, 2); - rb_define_method(cBackend, "bucket_update", cb_Backend_bucket_update, 2); - rb_define_method(cBackend, "bucket_drop", cb_Backend_bucket_drop, 2); - rb_define_method(cBackend, "bucket_flush", cb_Backend_bucket_flush, 2); - rb_define_method(cBackend, "bucket_get_all", cb_Backend_bucket_get_all, 1); - rb_define_method(cBackend, "bucket_get", cb_Backend_bucket_get, 2); + rb_define_method(cBackend, "bucket_create", cb_Backend_bucket_create, 3); + rb_define_method(cBackend, "bucket_update", cb_Backend_bucket_update, 3); + rb_define_method(cBackend, "bucket_drop", cb_Backend_bucket_drop, 3); + rb_define_method(cBackend, "bucket_flush", cb_Backend_bucket_flush, 3); + rb_define_method(cBackend, "bucket_get_all", cb_Backend_bucket_get_all, 2); + rb_define_method(cBackend, "bucket_get", cb_Backend_bucket_get, 3); } } // namespace couchbase::ruby diff --git a/ext/rcb_collections.cxx b/ext/rcb_collections.cxx index d18bff0b..b4960ae9 100644 --- a/ext/rcb_collections.cxx +++ b/ext/rcb_collections.cxx @@ -31,6 +31,7 @@ #include #include "rcb_backend.hxx" +#include "rcb_observability.hxx" #include "rcb_utils.hxx" namespace couchbase::ruby @@ -38,7 +39,7 @@ namespace couchbase::ruby namespace { VALUE -cb_Backend_scope_get_all(VALUE self, VALUE bucket_name, VALUE options) +cb_Backend_scope_get_all(VALUE self, VALUE bucket_name, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -50,12 +51,14 @@ cb_Backend_scope_get_all(VALUE self, VALUE bucket_name, VALUE options) try { core::operations::management::scope_get_all_request req{ cb_string_new(bucket_name) }; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error( resp.ctx, @@ -97,7 +100,11 @@ cb_Backend_scope_get_all(VALUE self, VALUE bucket_name, VALUE options) } VALUE -cb_Backend_scope_create(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE options) +cb_Backend_scope_create(VALUE self, + VALUE bucket_name, + VALUE scope_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -111,12 +118,14 @@ cb_Backend_scope_create(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE o core::operations::management::scope_create_request req{ cb_string_new(bucket_name), cb_string_new(scope_name) }; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(options, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, @@ -135,7 +144,11 @@ cb_Backend_scope_create(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE o } VALUE -cb_Backend_scope_drop(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE options) +cb_Backend_scope_drop(VALUE self, + VALUE bucket_name, + VALUE scope_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -149,12 +162,14 @@ cb_Backend_scope_drop(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE opt core::operations::management::scope_drop_request req{ cb_string_new(bucket_name), cb_string_new(scope_name) }; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(options, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to drop the scope "{}" on the bucket "{}")", @@ -177,7 +192,8 @@ cb_Backend_collection_create(VALUE self, VALUE scope_name, VALUE collection_name, VALUE settings, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -220,6 +236,7 @@ cb_Backend_collection_create(VALUE self, req.history = RTEST(history); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -227,6 +244,7 @@ cb_Backend_collection_create(VALUE self, promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable create the collection "{}.{}" on the bucket "{}")", @@ -250,7 +268,8 @@ cb_Backend_collection_update(VALUE self, VALUE scope_name, VALUE collection_name, VALUE settings, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -293,6 +312,7 @@ cb_Backend_collection_update(VALUE self, req.history = RTEST(history); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -300,6 +320,7 @@ cb_Backend_collection_update(VALUE self, promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable update the collection "{}.{}" on the bucket "{}")", @@ -322,7 +343,8 @@ cb_Backend_collection_drop(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE collection_name, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -338,6 +360,7 @@ cb_Backend_collection_drop(VALUE self, cb_string_new(scope_name), cb_string_new(collection_name) }; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -345,6 +368,7 @@ cb_Backend_collection_drop(VALUE self, promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to drop the collection "{}.{}" on the bucket "{}")", @@ -367,11 +391,11 @@ cb_Backend_collection_drop(VALUE self, void init_collections(VALUE cBackend) { - rb_define_method(cBackend, "scope_get_all", cb_Backend_scope_get_all, 2); - rb_define_method(cBackend, "scope_create", cb_Backend_scope_create, 3); - rb_define_method(cBackend, "scope_drop", cb_Backend_scope_drop, 3); - rb_define_method(cBackend, "collection_create", cb_Backend_collection_create, 5); - rb_define_method(cBackend, "collection_update", cb_Backend_collection_update, 5); - rb_define_method(cBackend, "collection_drop", cb_Backend_collection_drop, 4); + rb_define_method(cBackend, "scope_get_all", cb_Backend_scope_get_all, 3); + rb_define_method(cBackend, "scope_create", cb_Backend_scope_create, 4); + rb_define_method(cBackend, "scope_drop", cb_Backend_scope_drop, 4); + rb_define_method(cBackend, "collection_create", cb_Backend_collection_create, 6); + rb_define_method(cBackend, "collection_update", cb_Backend_collection_update, 6); + rb_define_method(cBackend, "collection_drop", cb_Backend_collection_drop, 5); } } // namespace couchbase::ruby diff --git a/ext/rcb_crud.cxx b/ext/rcb_crud.cxx index 6cc8a26d..e55fba8f 100644 --- a/ext/rcb_crud.cxx +++ b/ext/rcb_crud.cxx @@ -107,7 +107,9 @@ cb_Backend_document_get(VALUE self, core::operations::get_request req{ doc_id }; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { @@ -139,7 +141,8 @@ cb_Backend_document_get_any_replica(VALUE self, VALUE scope, VALUE collection, VALUE id, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -160,12 +163,15 @@ cb_Backend_document_get_any_replica(VALUE self, cb_extract_timeout(req, options); cb_extract_read_preference(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to get replica of the document"); } @@ -191,7 +197,8 @@ cb_Backend_document_get_all_replicas(VALUE self, VALUE scope, VALUE collection, VALUE id, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -212,12 +219,15 @@ cb_Backend_document_get_all_replicas(VALUE self, cb_extract_timeout(req, options); cb_extract_read_preference(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to get all replicas for the document"); } @@ -324,7 +334,8 @@ cb_Backend_document_get_and_lock(VALUE self, VALUE collection, VALUE id, VALUE lock_time, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -349,12 +360,15 @@ cb_Backend_document_get_and_lock(VALUE self, cb_extract_timeout(req, options); req.lock_time = NUM2UINT(lock_time); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable lock and fetch"); } @@ -380,7 +394,8 @@ cb_Backend_document_get_and_touch(VALUE self, VALUE collection, VALUE id, VALUE expiry, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -405,12 +420,15 @@ cb_Backend_document_get_and_touch(VALUE self, auto [type, duration] = unpack_expiry(expiry, false); req.expiry = static_cast(duration.count()); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable fetch and touch"); } @@ -436,7 +454,8 @@ cb_Backend_document_touch(VALUE self, VALUE collection, VALUE id, VALUE expiry, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -461,12 +480,15 @@ cb_Backend_document_touch(VALUE self, auto [type, duration] = unpack_expiry(expiry, false); req.expiry = static_cast(duration.count()); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to touch"); } @@ -489,7 +511,8 @@ cb_Backend_document_exists(VALUE self, VALUE scope, VALUE collection, VALUE id, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -512,12 +535,15 @@ cb_Backend_document_exists(VALUE self, core::operations::exists_request req{ doc_id }; cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec() && resp.ctx.ec() != couchbase::errc::key_value::document_not_found) { cb_throw_error(resp.ctx, "unable to exists"); } @@ -547,7 +573,8 @@ cb_Backend_document_unlock(VALUE self, VALUE collection, VALUE id, VALUE cas, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -571,12 +598,15 @@ cb_Backend_document_unlock(VALUE self, cb_extract_timeout(req, options); cb_extract_cas(req.cas, cas); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to unlock"); } @@ -601,7 +631,8 @@ cb_Backend_document_upsert(VALUE self, VALUE id, VALUE content, VALUE flags, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -631,6 +662,8 @@ cb_Backend_document_upsert(VALUE self, cb_extract_durability_level(req, options); cb_extract_preserve_expiry(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); @@ -652,6 +685,7 @@ cb_Backend_document_upsert(VALUE self, } auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to upsert"); } @@ -674,7 +708,8 @@ cb_Backend_document_append(VALUE self, VALUE collection, VALUE id, VALUE content, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -700,6 +735,8 @@ cb_Backend_document_append(VALUE self, cb_extract_timeout(req, options); cb_extract_durability_level(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); @@ -721,6 +758,7 @@ cb_Backend_document_append(VALUE self, } auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to append"); } @@ -743,7 +781,8 @@ cb_Backend_document_prepend(VALUE self, VALUE collection, VALUE id, VALUE content, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -769,6 +808,8 @@ cb_Backend_document_prepend(VALUE self, cb_extract_timeout(req, options); cb_extract_durability_level(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); @@ -790,6 +831,7 @@ cb_Backend_document_prepend(VALUE self, } auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to prepend"); } @@ -812,7 +854,8 @@ cb_Backend_document_replace(VALUE self, VALUE id, VALUE content, VALUE flags, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -843,6 +886,8 @@ cb_Backend_document_replace(VALUE self, cb_extract_preserve_expiry(req, options); cb_extract_cas(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); @@ -864,6 +909,7 @@ cb_Backend_document_replace(VALUE self, } auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to replace"); } @@ -886,7 +932,8 @@ cb_Backend_document_insert(VALUE self, VALUE id, VALUE content, VALUE flags, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -915,6 +962,8 @@ cb_Backend_document_insert(VALUE self, cb_extract_expiry(req, options); cb_extract_durability_level(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); @@ -934,8 +983,8 @@ cb_Backend_document_insert(VALUE self, promise.set_value(std::forward(resp)); }); } - auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to insert"); } @@ -956,7 +1005,8 @@ cb_Backend_document_remove(VALUE self, VALUE scope, VALUE collection, VALUE id, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -981,6 +1031,8 @@ cb_Backend_document_remove(VALUE self, cb_extract_durability_level(req, options); cb_extract_cas(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); @@ -1002,6 +1054,7 @@ cb_Backend_document_remove(VALUE self, } auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to remove"); } @@ -1021,7 +1074,8 @@ cb_Backend_document_increment(VALUE self, VALUE scope, VALUE collection, VALUE id, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1049,6 +1103,8 @@ cb_Backend_document_increment(VALUE self, cb_extract_option_uint64(req.initial_value, options, "initial_value"); cb_extract_durability_level(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); @@ -1070,6 +1126,7 @@ cb_Backend_document_increment(VALUE self, } auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to increment"); } @@ -1093,7 +1150,8 @@ cb_Backend_document_decrement(VALUE self, VALUE scope, VALUE collection, VALUE id, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1121,6 +1179,8 @@ cb_Backend_document_decrement(VALUE self, cb_extract_option_uint64(req.initial_value, options, "initial_value"); cb_extract_durability_level(req, options); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); @@ -1142,6 +1202,7 @@ cb_Backend_document_decrement(VALUE self, } auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to decrement"); } @@ -1166,7 +1227,8 @@ cb_Backend_document_lookup_in(VALUE self, VALUE collection, VALUE id, VALUE specs, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1231,12 +1293,15 @@ cb_Backend_document_lookup_in(VALUE self, core::impl::subdoc::build_lookup_in_path_flags(xattr, false) }); } + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to perform lookup_in operation"); } @@ -1292,7 +1357,8 @@ cb_Backend_document_lookup_in_any_replica(VALUE self, VALUE collection, VALUE id, VALUE specs, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1357,12 +1423,15 @@ cb_Backend_document_lookup_in_any_replica(VALUE self, core::impl::subdoc::build_lookup_in_path_flags(xattr, false) }); } + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to perform lookup_in_any_replica operation"); } @@ -1421,7 +1490,8 @@ cb_Backend_document_lookup_in_all_replicas(VALUE self, VALUE collection, VALUE id, VALUE specs, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1486,12 +1556,16 @@ cb_Backend_document_lookup_in_all_replicas(VALUE self, {}, core::impl::subdoc::build_lookup_in_path_flags(xattr, false) }); } + + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to perform lookup_in_all_replicas operation"); } @@ -1559,7 +1633,8 @@ cb_Backend_document_mutate_in(VALUE self, VALUE collection, VALUE id, VALUE specs, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1694,6 +1769,8 @@ cb_Backend_document_mutate_in(VALUE self, } req.specs = cxx_specs.specs(); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); @@ -1715,6 +1792,7 @@ cb_Backend_document_mutate_in(VALUE self, } auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts()); if (resp.ctx.ec()) { cb_throw_error(resp.ctx, "unable to mutate_in"); } @@ -1756,27 +1834,27 @@ void init_crud(VALUE cBackend) { rb_define_method(cBackend, "document_get", cb_Backend_document_get, 6); - rb_define_method(cBackend, "document_get_any_replica", cb_Backend_document_get_any_replica, 5); - rb_define_method(cBackend, "document_get_all_replicas", cb_Backend_document_get_all_replicas, 5); + rb_define_method(cBackend, "document_get_any_replica", cb_Backend_document_get_any_replica, 6); + rb_define_method(cBackend, "document_get_all_replicas", cb_Backend_document_get_all_replicas, 6); rb_define_method(cBackend, "document_get_projected", cb_Backend_document_get_projected, 6); - rb_define_method(cBackend, "document_get_and_lock", cb_Backend_document_get_and_lock, 6); - rb_define_method(cBackend, "document_get_and_touch", cb_Backend_document_get_and_touch, 6); - rb_define_method(cBackend, "document_insert", cb_Backend_document_insert, 7); - rb_define_method(cBackend, "document_replace", cb_Backend_document_replace, 7); - rb_define_method(cBackend, "document_upsert", cb_Backend_document_upsert, 7); - rb_define_method(cBackend, "document_append", cb_Backend_document_append, 6); - rb_define_method(cBackend, "document_prepend", cb_Backend_document_prepend, 6); - rb_define_method(cBackend, "document_remove", cb_Backend_document_remove, 5); - rb_define_method(cBackend, "document_lookup_in", cb_Backend_document_lookup_in, 6); + rb_define_method(cBackend, "document_get_and_lock", cb_Backend_document_get_and_lock, 7); + rb_define_method(cBackend, "document_get_and_touch", cb_Backend_document_get_and_touch, 7); + rb_define_method(cBackend, "document_insert", cb_Backend_document_insert, 8); + rb_define_method(cBackend, "document_replace", cb_Backend_document_replace, 8); + rb_define_method(cBackend, "document_upsert", cb_Backend_document_upsert, 8); + rb_define_method(cBackend, "document_append", cb_Backend_document_append, 7); + rb_define_method(cBackend, "document_prepend", cb_Backend_document_prepend, 7); + rb_define_method(cBackend, "document_remove", cb_Backend_document_remove, 6); + rb_define_method(cBackend, "document_lookup_in", cb_Backend_document_lookup_in, 7); rb_define_method( - cBackend, "document_lookup_in_any_replica", cb_Backend_document_lookup_in_any_replica, 6); + cBackend, "document_lookup_in_any_replica", cb_Backend_document_lookup_in_any_replica, 7); rb_define_method( - cBackend, "document_lookup_in_all_replicas", cb_Backend_document_lookup_in_all_replicas, 6); - rb_define_method(cBackend, "document_mutate_in", cb_Backend_document_mutate_in, 6); - rb_define_method(cBackend, "document_touch", cb_Backend_document_touch, 6); - rb_define_method(cBackend, "document_exists", cb_Backend_document_exists, 5); - rb_define_method(cBackend, "document_unlock", cb_Backend_document_unlock, 6); - rb_define_method(cBackend, "document_increment", cb_Backend_document_increment, 5); - rb_define_method(cBackend, "document_decrement", cb_Backend_document_decrement, 5); + cBackend, "document_lookup_in_all_replicas", cb_Backend_document_lookup_in_all_replicas, 7); + rb_define_method(cBackend, "document_mutate_in", cb_Backend_document_mutate_in, 7); + rb_define_method(cBackend, "document_touch", cb_Backend_document_touch, 7); + rb_define_method(cBackend, "document_exists", cb_Backend_document_exists, 6); + rb_define_method(cBackend, "document_unlock", cb_Backend_document_unlock, 7); + rb_define_method(cBackend, "document_increment", cb_Backend_document_increment, 6); + rb_define_method(cBackend, "document_decrement", cb_Backend_document_decrement, 6); } } // namespace couchbase::ruby diff --git a/ext/rcb_observability.cxx b/ext/rcb_observability.cxx index 6cff7c42..fa770d91 100644 --- a/ext/rcb_observability.cxx +++ b/ext/rcb_observability.cxx @@ -15,10 +15,9 @@ * limitations under the License. */ +#include "rcb_observability.hxx" #include "rcb_utils.hxx" -#include - #include #include @@ -26,6 +25,52 @@ namespace couchbase::ruby { +namespace +{ +VALUE +core_span_to_rb_hash(std::shared_ptr core_span) +{ + VALUE res = rb_hash_new(); + + static VALUE sym_name = rb_id2sym(rb_intern("name")); + static VALUE sym_attributes = rb_id2sym(rb_intern("attributes")); + static VALUE sym_start_timestamp = rb_id2sym(rb_intern("start_timestamp")); + static VALUE sym_end_timestamp = rb_id2sym(rb_intern("end_timestamp")); + static VALUE sym_children = rb_id2sym(rb_intern("children")); + + VALUE attributes = rb_hash_new(); + + for (const auto& [key, value] : core_span->uint_tags()) { + rb_hash_aset(attributes, cb_str_new(key), ULL2NUM(value)); + } + + for (const auto& [key, value] : core_span->string_tags()) { + rb_hash_aset(attributes, cb_str_new(key), cb_str_new(value)); + } + + rb_hash_aset(res, sym_name, cb_str_new(core_span->name())); + rb_hash_aset(res, sym_attributes, attributes); + rb_hash_aset(res, + sym_start_timestamp, + LL2NUM(std::chrono::duration_cast( + core_span->start_time().time_since_epoch()) + .count())); + rb_hash_aset(res, + sym_end_timestamp, + LL2NUM(std::chrono::duration_cast( + core_span->end_time().time_since_epoch()) + .count())); + + VALUE children = rb_ary_new_capa(static_cast(core_span->children().size())); + for (const auto& child : core_span->children()) { + rb_ary_push(children, core_span_to_rb_hash(child)); + } + rb_hash_aset(res, sym_children, children); + + return res; +} +} // namespace + void cb_add_core_spans(VALUE observability_handler, std::shared_ptr parent_span, @@ -35,37 +80,7 @@ cb_add_core_spans(VALUE observability_handler, VALUE spans = rb_ary_new_capa(static_cast(children.size())); for (const auto& child : parent_span->children()) { - VALUE span = rb_hash_new(); - - static VALUE sym_name = rb_id2sym(rb_intern("name")); - static VALUE sym_attributes = rb_id2sym(rb_intern("attributes")); - static VALUE sym_start_timestamp = rb_id2sym(rb_intern("start_timestamp")); - static VALUE sym_end_timestamp = rb_id2sym(rb_intern("end_timestamp")); - - VALUE attributes = rb_hash_new(); - - for (const auto& [key, value] : child->uint_tags()) { - rb_hash_aset(attributes, cb_str_new(key), ULL2NUM(value)); - } - - for (const auto& [key, value] : child->string_tags()) { - rb_hash_aset(attributes, cb_str_new(key), cb_str_new(value)); - } - - rb_hash_aset(span, sym_name, cb_str_new(child->name())); - rb_hash_aset(span, sym_attributes, attributes); - rb_hash_aset(span, - sym_start_timestamp, - LL2NUM(std::chrono::duration_cast( - child->start_time().time_since_epoch()) - .count())); - rb_hash_aset(span, - sym_end_timestamp, - LL2NUM(std::chrono::duration_cast( - child->end_time().time_since_epoch()) - .count())); - - rb_ary_push(spans, span); + rb_ary_push(spans, core_span_to_rb_hash(child)); } static ID add_backend_spans_func = rb_intern("add_spans_from_backend"); diff --git a/ext/rcb_observability.hxx b/ext/rcb_observability.hxx index 7572ed35..56466da2 100644 --- a/ext/rcb_observability.hxx +++ b/ext/rcb_observability.hxx @@ -15,8 +15,13 @@ * limitations under the License. */ +#ifndef COUCHBASE_RUBY_RCB_OBSERVABILITY_HXX +#define COUCHBASE_RUBY_RCB_OBSERVABILITY_HXX + #include +#include + #include namespace couchbase::ruby @@ -36,4 +41,13 @@ void cb_add_core_spans(VALUE observability_handler, std::shared_ptr parent_span, std::size_t retry_attempts); + +inline void +cb_add_core_spans(VALUE observability_handler, + std::shared_ptr parent_span) +{ + cb_add_core_spans(observability_handler, std::move(parent_span), 0); +} } // namespace couchbase::ruby + +#endif // COUCHBASE_RUBY_RCB_OBSERVABILITY_HXX diff --git a/ext/rcb_query.cxx b/ext/rcb_query.cxx index e1cdca85..5535f177 100644 --- a/ext/rcb_query.cxx +++ b/ext/rcb_query.cxx @@ -30,6 +30,7 @@ #include #include "rcb_backend.hxx" +#include "rcb_observability.hxx" #include "rcb_utils.hxx" namespace couchbase::ruby @@ -37,7 +38,10 @@ namespace couchbase::ruby namespace { VALUE -cb_Backend_query_index_get_all(VALUE self, VALUE bucket_name, VALUE options) +cb_Backend_query_index_get_all(VALUE self, + VALUE bucket_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -60,12 +64,14 @@ cb_Backend_query_index_get_all(VALUE self, VALUE bucket_name, VALUE options) req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error( resp.ctx, @@ -120,7 +126,8 @@ cb_Backend_query_index_create(VALUE self, VALUE bucket_name, VALUE index_name, VALUE keys, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -173,6 +180,7 @@ cb_Backend_query_index_create(VALUE self, req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -180,6 +188,7 @@ cb_Backend_query_index_create(VALUE self, promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -219,7 +228,11 @@ cb_Backend_query_index_create(VALUE self, } VALUE -cb_Backend_query_index_drop(VALUE self, VALUE bucket_name, VALUE index_name, VALUE options) +cb_Backend_query_index_drop(VALUE self, + VALUE bucket_name, + VALUE index_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -252,6 +265,7 @@ cb_Backend_query_index_drop(VALUE self, VALUE bucket_name, VALUE index_name, VAL req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -259,6 +273,7 @@ cb_Backend_query_index_drop(VALUE self, VALUE bucket_name, VALUE index_name, VAL promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -298,7 +313,10 @@ cb_Backend_query_index_drop(VALUE self, VALUE bucket_name, VALUE index_name, VAL } VALUE -cb_Backend_query_index_create_primary(VALUE self, VALUE bucket_name, VALUE options) +cb_Backend_query_index_create_primary(VALUE self, + VALUE bucket_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -342,6 +360,7 @@ cb_Backend_query_index_create_primary(VALUE self, VALUE bucket_name, VALUE optio req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -349,6 +368,7 @@ cb_Backend_query_index_create_primary(VALUE self, VALUE bucket_name, VALUE optio promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -387,7 +407,10 @@ cb_Backend_query_index_create_primary(VALUE self, VALUE bucket_name, VALUE optio } VALUE -cb_Backend_query_index_drop_primary(VALUE self, VALUE bucket_name, VALUE options) +cb_Backend_query_index_drop_primary(VALUE self, + VALUE bucket_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -424,6 +447,7 @@ cb_Backend_query_index_drop_primary(VALUE self, VALUE bucket_name, VALUE options req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -431,6 +455,7 @@ cb_Backend_query_index_drop_primary(VALUE self, VALUE bucket_name, VALUE options promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -468,7 +493,10 @@ cb_Backend_query_index_drop_primary(VALUE self, VALUE bucket_name, VALUE options } VALUE -cb_Backend_query_index_build_deferred(VALUE self, VALUE bucket_name, VALUE options) +cb_Backend_query_index_build_deferred(VALUE self, + VALUE bucket_name, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -492,6 +520,7 @@ cb_Backend_query_index_build_deferred(VALUE self, VALUE bucket_name, VALUE optio req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -500,6 +529,7 @@ cb_Backend_query_index_build_deferred(VALUE self, VALUE bucket_name, VALUE optio promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -568,7 +598,7 @@ cb_for_each_raw_param(VALUE key, VALUE value, VALUE arg) } VALUE -cb_Backend_document_query(VALUE self, VALUE statement, VALUE options) +cb_Backend_document_query(VALUE self, VALUE statement, VALUE options, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -679,6 +709,7 @@ cb_Backend_document_query(VALUE self, VALUE statement, VALUE options) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) rb_hash_foreach(raw_params, cb_for_each_raw_param, reinterpret_cast(&req)); } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -686,6 +717,7 @@ cb_Backend_document_query(VALUE self, VALUE statement, VALUE options) promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.meta.errors && !resp.meta.errors->empty()) { const auto& first_error = resp.meta.errors->front(); @@ -757,7 +789,8 @@ cb_Backend_collection_query_index_get_all(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE collection_name, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -774,12 +807,14 @@ cb_Backend_collection_query_index_get_all(VALUE self, req.scope_name = cb_string_new(scope_name); req.collection_name = cb_string_new(collection_name); cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format("unable to get list of the indexes of the collection \"{}\"", @@ -836,7 +871,8 @@ cb_Backend_collection_query_index_create(VALUE self, VALUE collection_name, VALUE index_name, VALUE keys, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); @@ -892,6 +928,7 @@ cb_Backend_collection_query_index_create(VALUE self, req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -899,6 +936,7 @@ cb_Backend_collection_query_index_create(VALUE self, promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -943,7 +981,8 @@ cb_Backend_collection_query_index_drop(VALUE self, VALUE scope_name, VALUE collection_name, VALUE index_name, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -979,6 +1018,7 @@ cb_Backend_collection_query_index_drop(VALUE self, req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -986,6 +1026,7 @@ cb_Backend_collection_query_index_drop(VALUE self, promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -1030,7 +1071,8 @@ cb_Backend_collection_query_index_create_primary(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE collection_name, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1078,6 +1120,7 @@ cb_Backend_collection_query_index_create_primary(VALUE self, req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -1085,6 +1128,7 @@ cb_Backend_collection_query_index_create_primary(VALUE self, promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -1127,7 +1171,8 @@ cb_Backend_collection_query_index_drop_primary(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE collection_name, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1168,6 +1213,7 @@ cb_Backend_collection_query_index_drop_primary(VALUE self, req.collection_name = cb_string_new(collection_name); } } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -1175,6 +1221,7 @@ cb_Backend_collection_query_index_drop_primary(VALUE self, promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -1217,7 +1264,8 @@ cb_Backend_collection_query_index_build_deferred(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE collection_name, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1234,6 +1282,7 @@ cb_Backend_collection_query_index_build_deferred(VALUE self, req.bucket_name = cb_string_new(bucket_name); req.scope_name = cb_string_new(scope_name); req.collection_name = cb_string_new(collection_name); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); @@ -1241,6 +1290,7 @@ cb_Backend_collection_query_index_build_deferred(VALUE self, promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (!resp.errors.empty()) { const auto& first_error = resp.errors.front(); @@ -1283,34 +1333,34 @@ cb_Backend_collection_query_index_build_deferred(VALUE self, void init_query(VALUE cBackend) { - rb_define_method(cBackend, "document_query", cb_Backend_document_query, 2); + rb_define_method(cBackend, "document_query", cb_Backend_document_query, 3); - rb_define_method(cBackend, "query_index_get_all", cb_Backend_query_index_get_all, 2); - rb_define_method(cBackend, "query_index_create", cb_Backend_query_index_create, 4); + rb_define_method(cBackend, "query_index_get_all", cb_Backend_query_index_get_all, 3); + rb_define_method(cBackend, "query_index_create", cb_Backend_query_index_create, 5); rb_define_method( - cBackend, "query_index_create_primary", cb_Backend_query_index_create_primary, 2); - rb_define_method(cBackend, "query_index_drop", cb_Backend_query_index_drop, 3); - rb_define_method(cBackend, "query_index_drop_primary", cb_Backend_query_index_drop_primary, 2); + cBackend, "query_index_create_primary", cb_Backend_query_index_create_primary, 3); + rb_define_method(cBackend, "query_index_drop", cb_Backend_query_index_drop, 4); + rb_define_method(cBackend, "query_index_drop_primary", cb_Backend_query_index_drop_primary, 3); rb_define_method( - cBackend, "query_index_build_deferred", cb_Backend_query_index_build_deferred, 2); + cBackend, "query_index_build_deferred", cb_Backend_query_index_build_deferred, 3); rb_define_method( - cBackend, "collection_query_index_get_all", cb_Backend_collection_query_index_get_all, 4); + cBackend, "collection_query_index_get_all", cb_Backend_collection_query_index_get_all, 5); rb_define_method( - cBackend, "collection_query_index_create", cb_Backend_collection_query_index_create, 6); + cBackend, "collection_query_index_create", cb_Backend_collection_query_index_create, 7); rb_define_method(cBackend, "collection_query_index_create_primary", cb_Backend_collection_query_index_create_primary, - 4); + 5); rb_define_method( - cBackend, "collection_query_index_drop", cb_Backend_collection_query_index_drop, 5); + cBackend, "collection_query_index_drop", cb_Backend_collection_query_index_drop, 6); rb_define_method(cBackend, "collection_query_index_drop_primary", cb_Backend_collection_query_index_drop_primary, - 4); + 5); rb_define_method(cBackend, "collection_query_index_build_deferred", cb_Backend_collection_query_index_build_deferred, - 4); + 5); } } // namespace couchbase::ruby diff --git a/ext/rcb_search.cxx b/ext/rcb_search.cxx index 03c76a76..da545216 100644 --- a/ext/rcb_search.cxx +++ b/ext/rcb_search.cxx @@ -39,6 +39,7 @@ #include #include "rcb_backend.hxx" +#include "rcb_observability.hxx" #include "rcb_utils.hxx" namespace couchbase::ruby @@ -71,7 +72,11 @@ cb_extract_search_index(VALUE index, const core::management::search::index& idx) } VALUE -cb_Backend_search_index_get_all(VALUE self, VALUE bucket, VALUE scope, VALUE options) +cb_Backend_search_index_get_all(VALUE self, + VALUE bucket, + VALUE scope, + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -87,12 +92,14 @@ cb_Backend_search_index_get_all(VALUE self, VALUE bucket, VALUE scope, VALUE opt } cb_extract_timeout(req, options); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, "unable to get list of the search indexes"); } @@ -117,7 +124,12 @@ cb_Backend_search_index_get_all(VALUE self, VALUE bucket, VALUE scope, VALUE opt } VALUE -cb_Backend_search_index_get(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, VALUE timeout) +cb_Backend_search_index_get(VALUE self, + VALUE bucket, + VALUE scope, + VALUE index_name, + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -135,12 +147,14 @@ cb_Backend_search_index_get(VALUE self, VALUE bucket, VALUE scope, VALUE index_n } cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error(resp.ctx, fmt::format("unable to get search index \"{}\"", req.index_name)); @@ -167,7 +181,8 @@ cb_Backend_search_index_upsert(VALUE self, VALUE bucket, VALUE scope, VALUE index_definition, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -233,12 +248,15 @@ cb_Backend_search_index_upsert(VALUE self, req.index.plan_params_json = cb_string_new(plan_params); } + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error(resp.ctx, @@ -262,7 +280,12 @@ cb_Backend_search_index_upsert(VALUE self, } VALUE -cb_Backend_search_index_drop(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, VALUE timeout) +cb_Backend_search_index_drop(VALUE self, + VALUE bucket, + VALUE scope, + VALUE index_name, + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -280,12 +303,14 @@ cb_Backend_search_index_drop(VALUE self, VALUE bucket, VALUE scope, VALUE index_ } cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error(resp.ctx, @@ -313,7 +338,8 @@ cb_Backend_search_index_get_documents_count(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -331,12 +357,14 @@ cb_Backend_search_index_get_documents_count(VALUE self, } cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error( @@ -366,7 +394,10 @@ cb_Backend_search_index_get_documents_count(VALUE self, } VALUE -cb_Backend_search_index_get_stats(VALUE self, VALUE index_name, VALUE timeout) +cb_Backend_search_index_get_stats(VALUE self, + VALUE index_name, + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -376,12 +407,14 @@ cb_Backend_search_index_get_stats(VALUE self, VALUE index_name, VALUE timeout) core::operations::management::search_index_get_stats_request req{}; cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error( @@ -404,19 +437,21 @@ cb_Backend_search_index_get_stats(VALUE self, VALUE index_name, VALUE timeout) } VALUE -cb_Backend_search_get_stats(VALUE self, VALUE timeout) +cb_Backend_search_get_stats(VALUE self, VALUE timeout, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::search_get_stats_request req{}; cb_extract_timeout(req, timeout); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, "unable to get stats for the search service"); } @@ -435,7 +470,8 @@ cb_Backend_search_index_pause_ingest(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -454,12 +490,14 @@ cb_Backend_search_index_pause_ingest(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.pause = true; + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error( @@ -489,7 +527,8 @@ cb_Backend_search_index_resume_ingest(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -508,12 +547,14 @@ cb_Backend_search_index_resume_ingest(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.pause = false; + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error( @@ -543,7 +584,8 @@ cb_Backend_search_index_allow_querying(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -562,12 +604,14 @@ cb_Backend_search_index_allow_querying(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.allow = true; + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error( @@ -597,7 +641,8 @@ cb_Backend_search_index_disallow_querying(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -616,12 +661,14 @@ cb_Backend_search_index_disallow_querying(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.allow = false; + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error( @@ -651,7 +698,8 @@ cb_Backend_search_index_freeze_plan(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -670,12 +718,14 @@ cb_Backend_search_index_freeze_plan(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.freeze = true; + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error(resp.ctx, @@ -704,7 +754,8 @@ cb_Backend_search_index_unfreeze_plan(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -723,12 +774,14 @@ cb_Backend_search_index_unfreeze_plan(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.freeze = false; + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error( @@ -759,7 +812,8 @@ cb_Backend_search_index_analyze_document(VALUE self, VALUE scope, VALUE index_name, VALUE encoded_document, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -781,12 +835,15 @@ cb_Backend_search_index_analyze_document(VALUE self, req.index_name = cb_string_new(index_name); req.encoded_document = cb_string_new(encoded_document); + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error.empty()) { cb_throw_error( @@ -834,7 +891,8 @@ cb_Backend_document_search(VALUE self, VALUE index_name, VALUE query, VALUE search_request, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -1017,12 +1075,15 @@ cb_Backend_document_search(VALUE self, rb_hash_foreach(raw_params, cb_for_each_raw_param, reinterpret_cast(&req)); } + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format("unable to perform search query for index \"{}\": {}", @@ -1190,27 +1251,27 @@ cb_Backend_document_search(VALUE self, void init_search(VALUE cBackend) { - rb_define_method(cBackend, "document_search", cb_Backend_document_search, 6); - - rb_define_method(cBackend, "search_get_stats", cb_Backend_search_get_stats, 1); - rb_define_method(cBackend, "search_index_get_all", cb_Backend_search_index_get_all, 3); - rb_define_method(cBackend, "search_index_get", cb_Backend_search_index_get, 4); - rb_define_method(cBackend, "search_index_upsert", cb_Backend_search_index_upsert, 4); - rb_define_method(cBackend, "search_index_drop", cb_Backend_search_index_drop, 4); - rb_define_method(cBackend, "search_index_get_stats", cb_Backend_search_index_get_stats, 2); + rb_define_method(cBackend, "document_search", cb_Backend_document_search, 7); + + rb_define_method(cBackend, "search_get_stats", cb_Backend_search_get_stats, 2); + rb_define_method(cBackend, "search_index_get_all", cb_Backend_search_index_get_all, 4); + rb_define_method(cBackend, "search_index_get", cb_Backend_search_index_get, 5); + rb_define_method(cBackend, "search_index_upsert", cb_Backend_search_index_upsert, 5); + rb_define_method(cBackend, "search_index_drop", cb_Backend_search_index_drop, 5); + rb_define_method(cBackend, "search_index_get_stats", cb_Backend_search_index_get_stats, 3); rb_define_method( - cBackend, "search_index_get_documents_count", cb_Backend_search_index_get_documents_count, 4); - rb_define_method(cBackend, "search_index_pause_ingest", cb_Backend_search_index_pause_ingest, 4); + cBackend, "search_index_get_documents_count", cb_Backend_search_index_get_documents_count, 5); + rb_define_method(cBackend, "search_index_pause_ingest", cb_Backend_search_index_pause_ingest, 5); rb_define_method( - cBackend, "search_index_resume_ingest", cb_Backend_search_index_resume_ingest, 4); + cBackend, "search_index_resume_ingest", cb_Backend_search_index_resume_ingest, 5); rb_define_method( - cBackend, "search_index_allow_querying", cb_Backend_search_index_allow_querying, 4); + cBackend, "search_index_allow_querying", cb_Backend_search_index_allow_querying, 5); rb_define_method( - cBackend, "search_index_disallow_querying", cb_Backend_search_index_disallow_querying, 4); - rb_define_method(cBackend, "search_index_freeze_plan", cb_Backend_search_index_freeze_plan, 4); + cBackend, "search_index_disallow_querying", cb_Backend_search_index_disallow_querying, 5); + rb_define_method(cBackend, "search_index_freeze_plan", cb_Backend_search_index_freeze_plan, 5); rb_define_method( - cBackend, "search_index_unfreeze_plan", cb_Backend_search_index_unfreeze_plan, 4); + cBackend, "search_index_unfreeze_plan", cb_Backend_search_index_unfreeze_plan, 5); rb_define_method( - cBackend, "search_index_analyze_document", cb_Backend_search_index_analyze_document, 5); + cBackend, "search_index_analyze_document", cb_Backend_search_index_analyze_document, 6); } } // namespace couchbase::ruby diff --git a/ext/rcb_users.cxx b/ext/rcb_users.cxx index c5b3ae59..58a6e09e 100644 --- a/ext/rcb_users.cxx +++ b/ext/rcb_users.cxx @@ -37,6 +37,7 @@ #include #include "rcb_backend.hxx" +#include "rcb_observability.hxx" #include "rcb_utils.hxx" namespace couchbase::ruby @@ -61,7 +62,7 @@ cb_extract_role(const core::management::rbac::role_and_description& entry, VALUE } VALUE -cb_Backend_role_get_all(VALUE self, VALUE timeout) +cb_Backend_role_get_all(VALUE self, VALUE timeout, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -69,11 +70,13 @@ cb_Backend_role_get_all(VALUE self, VALUE timeout) core::operations::management::role_get_all_request req{}; cb_extract_timeout(req, timeout); std::promise promise; + auto parent_span = cb_create_parent_span(req, self); auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, "unable to fetch roles"); } @@ -172,7 +175,7 @@ cb_extract_user(const core::management::rbac::user_and_metadata& entry, VALUE us } VALUE -cb_Backend_user_get_all(VALUE self, VALUE domain, VALUE timeout) +cb_Backend_user_get_all(VALUE self, VALUE domain, VALUE timeout, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -189,12 +192,14 @@ cb_Backend_user_get_all(VALUE self, VALUE domain, VALUE timeout) throw ruby_exception(exc_invalid_argument(), rb_sprintf("unsupported authentication domain: %+" PRIsVALUE, domain)); } + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, "unable to fetch users"); } @@ -216,7 +221,11 @@ cb_Backend_user_get_all(VALUE self, VALUE domain, VALUE timeout) } VALUE -cb_Backend_user_get(VALUE self, VALUE domain, VALUE username, VALUE timeout) +cb_Backend_user_get(VALUE self, + VALUE domain, + VALUE username, + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -235,12 +244,14 @@ cb_Backend_user_get(VALUE self, VALUE domain, VALUE username, VALUE timeout) rb_sprintf("unsupported authentication domain: %+" PRIsVALUE, domain)); } req.username = cb_string_new(username); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to fetch user "{}")", req.username)); } @@ -258,7 +269,11 @@ cb_Backend_user_get(VALUE self, VALUE domain, VALUE username, VALUE timeout) } VALUE -cb_Backend_user_drop(VALUE self, VALUE domain, VALUE username, VALUE timeout) +cb_Backend_user_drop(VALUE self, + VALUE domain, + VALUE username, + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -277,12 +292,15 @@ cb_Backend_user_drop(VALUE self, VALUE domain, VALUE username, VALUE timeout) rb_sprintf("unsupported authentication domain: %+" PRIsVALUE, domain)); } req.username = cb_string_new(username); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to fetch user "{}")", req.username)); } @@ -297,7 +315,11 @@ cb_Backend_user_drop(VALUE self, VALUE domain, VALUE username, VALUE timeout) } VALUE -cb_Backend_user_upsert(VALUE self, VALUE domain, VALUE user, VALUE timeout) +cb_Backend_user_upsert(VALUE self, + VALUE domain, + VALUE user, + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -365,13 +387,17 @@ cb_Backend_user_upsert(VALUE self, VALUE domain, VALUE user, VALUE timeout) } } + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to upsert user "{}" ({}))", req.user.username, @@ -389,7 +415,10 @@ cb_Backend_user_upsert(VALUE self, VALUE domain, VALUE user, VALUE timeout) } VALUE -cb_Backend_change_password(VALUE self, VALUE new_password, VALUE timeout) +cb_Backend_change_password(VALUE self, + VALUE new_password, + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -399,12 +428,15 @@ cb_Backend_change_password(VALUE self, VALUE new_password, VALUE timeout) core::operations::management::change_password_request req{}; cb_extract_timeout(req, timeout); req.newPassword = cb_string_new(new_password); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, "unable to change password"); } @@ -449,19 +481,21 @@ cb_extract_group(const core::management::rbac::group& entry, VALUE group) } VALUE -cb_Backend_group_get_all(VALUE self, VALUE timeout) +cb_Backend_group_get_all(VALUE self, VALUE timeout, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::group_get_all_request req{}; cb_extract_timeout(req, timeout); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, "unable to fetch groups"); } @@ -483,7 +517,7 @@ cb_Backend_group_get_all(VALUE self, VALUE timeout) } VALUE -cb_Backend_group_get(VALUE self, VALUE name, VALUE timeout) +cb_Backend_group_get(VALUE self, VALUE name, VALUE timeout, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -493,12 +527,14 @@ cb_Backend_group_get(VALUE self, VALUE name, VALUE timeout) core::operations::management::group_get_request req{}; cb_extract_timeout(req, timeout); req.name = cb_string_new(name); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to fetch group "{}")", req.name)); } @@ -516,7 +552,7 @@ cb_Backend_group_get(VALUE self, VALUE name, VALUE timeout) } VALUE -cb_Backend_group_drop(VALUE self, VALUE name, VALUE timeout) +cb_Backend_group_drop(VALUE self, VALUE name, VALUE timeout, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -526,13 +562,16 @@ cb_Backend_group_drop(VALUE self, VALUE name, VALUE timeout) core::operations::management::group_drop_request req{}; cb_extract_timeout(req, timeout); req.name = cb_string_new(name); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to drop group "{}")", req.name)); } return Qtrue; @@ -546,7 +585,7 @@ cb_Backend_group_drop(VALUE self, VALUE name, VALUE timeout) } VALUE -cb_Backend_group_upsert(VALUE self, VALUE group, VALUE timeout) +cb_Backend_group_upsert(VALUE self, VALUE group, VALUE timeout, VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -596,12 +635,16 @@ cb_Backend_group_upsert(VALUE self, VALUE group, VALUE timeout) } } + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to upsert group "{}" ({}))", req.group.name, @@ -621,16 +664,16 @@ cb_Backend_group_upsert(VALUE self, VALUE group, VALUE timeout) void init_users(VALUE cBackend) { - rb_define_method(cBackend, "role_get_all", cb_Backend_role_get_all, 1); - rb_define_method(cBackend, "user_get_all", cb_Backend_user_get_all, 2); - rb_define_method(cBackend, "user_get", cb_Backend_user_get, 3); - rb_define_method(cBackend, "user_drop", cb_Backend_user_drop, 3); - rb_define_method(cBackend, "user_upsert", cb_Backend_user_upsert, 3); - rb_define_method(cBackend, "group_get_all", cb_Backend_group_get_all, 1); - rb_define_method(cBackend, "group_get", cb_Backend_group_get, 2); - rb_define_method(cBackend, "group_drop", cb_Backend_group_drop, 2); - rb_define_method(cBackend, "group_upsert", cb_Backend_group_upsert, 2); - - rb_define_method(cBackend, "change_password", cb_Backend_change_password, 2); + rb_define_method(cBackend, "role_get_all", cb_Backend_role_get_all, 2); + rb_define_method(cBackend, "user_get_all", cb_Backend_user_get_all, 3); + rb_define_method(cBackend, "user_get", cb_Backend_user_get, 4); + rb_define_method(cBackend, "user_drop", cb_Backend_user_drop, 4); + rb_define_method(cBackend, "user_upsert", cb_Backend_user_upsert, 4); + rb_define_method(cBackend, "group_get_all", cb_Backend_group_get_all, 2); + rb_define_method(cBackend, "group_get", cb_Backend_group_get, 3); + rb_define_method(cBackend, "group_drop", cb_Backend_group_drop, 3); + rb_define_method(cBackend, "group_upsert", cb_Backend_group_upsert, 3); + + rb_define_method(cBackend, "change_password", cb_Backend_change_password, 3); } } // namespace couchbase::ruby diff --git a/ext/rcb_views.cxx b/ext/rcb_views.cxx index fa92f87c..68090cbe 100644 --- a/ext/rcb_views.cxx +++ b/ext/rcb_views.cxx @@ -30,6 +30,7 @@ #include #include "rcb_backend.hxx" +#include "rcb_observability.hxx" #include "rcb_utils.hxx" namespace couchbase::ruby @@ -37,7 +38,11 @@ namespace couchbase::ruby namespace { VALUE -cb_Backend_view_index_get_all(VALUE self, VALUE bucket_name, VALUE name_space, VALUE timeout) +cb_Backend_view_index_get_all(VALUE self, + VALUE bucket_name, + VALUE name_space, + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -59,12 +64,14 @@ cb_Backend_view_index_get_all(VALUE self, VALUE bucket_name, VALUE name_space, V req.bucket_name = cb_string_new(bucket_name); req.ns = ns; cb_extract_timeout(req, timeout); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, "unable to get list of the design documents"); } @@ -112,7 +119,8 @@ cb_Backend_view_index_get(VALUE self, VALUE bucket_name, VALUE document_name, VALUE name_space, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -136,12 +144,14 @@ cb_Backend_view_index_get(VALUE self, req.document_name = cb_string_new(document_name); req.ns = ns; cb_extract_timeout(req, timeout); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to get design document "{}" ({}) on bucket "{}")", @@ -189,7 +199,8 @@ cb_Backend_view_index_drop(VALUE self, VALUE bucket_name, VALUE document_name, VALUE name_space, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -213,13 +224,16 @@ cb_Backend_view_index_drop(VALUE self, req.document_name = cb_string_new(document_name); req.ns = ns; cb_extract_timeout(req, timeout); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to drop design document "{}" ({}) on bucket "{}")", req.document_name, @@ -241,7 +255,8 @@ cb_Backend_view_index_upsert(VALUE self, VALUE bucket_name, VALUE document, VALUE name_space, - VALUE timeout) + VALUE timeout, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -289,13 +304,16 @@ cb_Backend_view_index_upsert(VALUE self, } cb_extract_timeout(req, timeout); + auto parent_span = cb_create_parent_span(req, self); std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); - if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); + if (resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to store design document "{}" ({}) on bucket "{}")", req.document.name, @@ -318,7 +336,8 @@ cb_Backend_document_view(VALUE self, VALUE design_document_name, VALUE view_name, VALUE name_space, - VALUE options) + VALUE options, + VALUE observability_handler) { auto cluster = cb_backend_to_core_api_cluster(self); @@ -422,12 +441,15 @@ cb_Backend_document_view(VALUE self, } } + auto parent_span = cb_create_parent_span(req, self); + std::promise promise; auto f = promise.get_future(); cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); + cb_add_core_spans(observability_handler, std::move(parent_span)); if (resp.ctx.ec) { if (resp.error) { cb_throw_error(resp.ctx, @@ -477,11 +499,11 @@ cb_Backend_document_view(VALUE self, void init_views(VALUE cBackend) { - rb_define_method(cBackend, "document_view", cb_Backend_document_view, 5); + rb_define_method(cBackend, "document_view", cb_Backend_document_view, 6); - rb_define_method(cBackend, "view_index_get_all", cb_Backend_view_index_get_all, 3); - rb_define_method(cBackend, "view_index_get", cb_Backend_view_index_get, 4); - rb_define_method(cBackend, "view_index_drop", cb_Backend_view_index_drop, 4); - rb_define_method(cBackend, "view_index_upsert", cb_Backend_view_index_upsert, 4); + rb_define_method(cBackend, "view_index_get_all", cb_Backend_view_index_get_all, 4); + rb_define_method(cBackend, "view_index_get", cb_Backend_view_index_get, 5); + rb_define_method(cBackend, "view_index_drop", cb_Backend_view_index_drop, 5); + rb_define_method(cBackend, "view_index_upsert", cb_Backend_view_index_upsert, 5); } } // namespace couchbase::ruby diff --git a/lib/couchbase/binary_collection.rb b/lib/couchbase/binary_collection.rb index c3e9ca6c..8f3d970e 100644 --- a/lib/couchbase/binary_collection.rb +++ b/lib/couchbase/binary_collection.rb @@ -23,9 +23,12 @@ class BinaryCollection alias inspect to_s # @param [Couchbase::Collection] collection parent collection + # + # @api private def initialize(collection) @collection = collection @backend = collection.instance_variable_get(:@backend) + @observability = collection.instance_variable_get(:@observability) end # Appends binary content to the document @@ -41,11 +44,14 @@ def initialize(collection) # # @return [Collection::MutationResult] def append(id, content, options = Options::Append::DEFAULT) - resp = @backend.document_append(@collection.bucket_name, @collection.scope_name, @collection.name, - id, content, options.to_backend) - Collection::MutationResult.new do |res| - res.cas = resp[:cas] - res.mutation_token = @collection.send(:extract_mutation_token, resp) + @observability.record_operation(Observability::OP_APPEND, options.parent_span, self, :kv) do |obs_handler| + obs_handler.add_durability_level(options.durability_level) + resp = @backend.document_append(@collection.bucket_name, @collection.scope_name, @collection.name, + id, content, options.to_backend, obs_handler) + Collection::MutationResult.new do |res| + res.cas = resp[:cas] + res.mutation_token = @collection.send(:extract_mutation_token, resp) + end end end @@ -62,11 +68,14 @@ def append(id, content, options = Options::Append::DEFAULT) # # @return [Collection::MutationResult] def prepend(id, content, options = Options::Prepend::DEFAULT) - resp = @backend.document_prepend(@collection.bucket_name, @collection.scope_name, @collection.name, - id, content, options.to_backend) - Collection::MutationResult.new do |res| - res.cas = resp[:cas] - res.mutation_token = @collection.send(:extract_mutation_token, resp) + @observability.record_operation(Observability::OP_PREPEND, options.parent_span, self, :kv) do |obs_handler| + obs_handler.add_durability_level(options.durability_level) + resp = @backend.document_prepend(@collection.bucket_name, @collection.scope_name, @collection.name, + id, content, options.to_backend, obs_handler) + Collection::MutationResult.new do |res| + res.cas = resp[:cas] + res.mutation_token = @collection.send(:extract_mutation_token, resp) + end end end @@ -83,12 +92,15 @@ def prepend(id, content, options = Options::Prepend::DEFAULT) # # @return [CounterResult] def increment(id, options = Options::Increment::DEFAULT) - resp = @backend.document_increment(@collection.bucket_name, @collection.scope_name, @collection.name, id, - options.to_backend) - CounterResult.new do |res| - res.cas = resp[:cas] - res.content = resp[:content] - res.mutation_token = @collection.send(:extract_mutation_token, resp) + @observability.record_operation(Observability::OP_INCREMENT, options.parent_span, self, :kv) do |obs_handler| + obs_handler.add_durability_level(options.durability_level) + resp = @backend.document_increment(@collection.bucket_name, @collection.scope_name, @collection.name, id, + options.to_backend, obs_handler) + CounterResult.new do |res| + res.cas = resp[:cas] + res.content = resp[:content] + res.mutation_token = @collection.send(:extract_mutation_token, resp) + end end end @@ -105,12 +117,15 @@ def increment(id, options = Options::Increment::DEFAULT) # # @return [CounterResult] def decrement(id, options = Options::Decrement::DEFAULT) - resp = @backend.document_decrement(@collection.bucket_name, @collection.scope_name, @collection.name, id, - options.to_backend) - CounterResult.new do |res| - res.cas = resp[:cas] - res.content = resp[:content] - res.mutation_token = @collection.send(:extract_mutation_token, resp) + @observability.record_operation(Observability::OP_DECREMENT, options.parent_span, self, :kv) do |obs_handler| + obs_handler.add_durability_level(options.durability_level) + resp = @backend.document_decrement(@collection.bucket_name, @collection.scope_name, @collection.name, id, + options.to_backend, obs_handler) + CounterResult.new do |res| + res.cas = resp[:cas] + res.content = resp[:content] + res.mutation_token = @collection.send(:extract_mutation_token, resp) + end end end diff --git a/lib/couchbase/bucket.rb b/lib/couchbase/bucket.rb index 4c0701df..a2b548f5 100644 --- a/lib/couchbase/bucket.rb +++ b/lib/couchbase/bucket.rb @@ -90,8 +90,8 @@ def default_collection # Views are not compatible with the Magma storage engine. Instead of views, use indexes and queries using the # Index Service (GSI) and the Query Service (SQL++). def view_query(design_document_name, view_name, options = Options::View::DEFAULT) - @observability.record_operation(Observability::OP_VIEW_QUERY, opts.parent_span, self, :views) do |_obs_handler| - resp = @backend.document_view(@name, design_document_name, view_name, options.namespace, options.to_backend) + @observability.record_operation(Observability::OP_VIEW_QUERY, options.parent_span, self, :views) do |obs_handler| + resp = @backend.document_view(@name, design_document_name, view_name, options.namespace, options.to_backend, obs_handler) ViewResult.new do |res| res.meta_data = ViewMetaData.new do |meta| meta.total_rows = resp[:meta][:total_rows] diff --git a/lib/couchbase/cluster.rb b/lib/couchbase/cluster.rb index e0b42b67..605d2499 100644 --- a/lib/couchbase/cluster.rb +++ b/lib/couchbase/cluster.rb @@ -143,7 +143,7 @@ def query(statement, options = Options::Query::DEFAULT) @observability.record_operation(Observability::OP_QUERY, options.parent_span, self, :query) do |obs_handler| obs_handler.add_query_statement(statement, options) - resp = @backend.document_query(statement, options.to_backend) + resp = @backend.document_query(statement, options.to_backend, obs_handler) QueryResult.new do |res| res.meta_data = QueryMetaData.new do |meta| @@ -185,7 +185,7 @@ def analytics_query(statement, options = Options::Analytics::DEFAULT) @observability.record_operation(Observability::OP_ANALYTICS_QUERY, options.parent_span, self, :analytics) do |obs_handler| obs_handler.add_query_statement(statement, options) - resp = @backend.document_analytics(statement, options.to_backend) + resp = @backend.document_analytics(statement, options.to_backend, obs_handler) AnalyticsResult.new do |res| res.transcoder = options.transcoder @@ -230,8 +230,8 @@ def analytics_query(statement, options = Options::Analytics::DEFAULT) # # @return [SearchResult] def search_query(index_name, query, options = Options::Search::DEFAULT) - @observability.record_operation(Observability::OP_SEARCH_QUERY, options.parent_span, self, :search) do |_obs_handler| - resp = @backend.document_search(nil, nil, index_name, JSON.generate(query), {}, options.to_backend) + @observability.record_operation(Observability::OP_SEARCH_QUERY, options.parent_span, self, :search) do |obs_handler| + resp = @backend.document_search(nil, nil, index_name, JSON.generate(query), {}, options.to_backend, obs_handler) convert_search_result(resp, options) end end @@ -244,9 +244,10 @@ def search_query(index_name, query, options = Options::Search::DEFAULT) # # @return [SearchResult] def search(index_name, search_request, options = Options::Search::DEFAULT) - @observability.record_operation(Observability::OP_SEARCH_QUERY, options.parent_span, self, :search) do |_obs_handler| + @observability.record_operation(Observability::OP_SEARCH_QUERY, options.parent_span, self, :search) do |obs_handler| encoded_query, encoded_req = search_request.to_backend - resp = @backend.document_search(nil, nil, index_name, encoded_query, encoded_req, options.to_backend(show_request: false)) + resp = @backend.document_search(nil, nil, index_name, encoded_query, encoded_req, options.to_backend(show_request: false), + obs_handler) convert_search_result(resp, options) end end diff --git a/lib/couchbase/collection.rb b/lib/couchbase/collection.rb index 41e29f38..7db357a5 100644 --- a/lib/couchbase/collection.rb +++ b/lib/couchbase/collection.rb @@ -33,6 +33,8 @@ class Collection # @param [String] scope_name name of the scope # @param [String] collection_name name of the collection # @param [Observability::Wrapper] observability wrapper containing tracer and meter + # + # @api private def initialize(backend, bucket_name, scope_name, collection_name, observability) @backend = backend @bucket_name = bucket_name @@ -143,10 +145,10 @@ def get_multi(ids, options = Options::GetMulti::DEFAULT) # # @return [GetResult] def get_and_lock(id, lock_time, options = Options::GetAndLock::DEFAULT) - @observability.record_operation(Observability::OP_GET_AND_LOCK, options.parent_span, self, :kv) do |_obs_handler| + @observability.record_operation(Observability::OP_GET_AND_LOCK, options.parent_span, self, :kv) do |obs_handler| resp = @backend.document_get_and_lock(bucket_name, @scope_name, @name, id, lock_time.respond_to?(:in_seconds) ? lock_time.in_seconds : lock_time, - options.to_backend) + options.to_backend, obs_handler) GetResult.new do |res| res.transcoder = options.transcoder res.cas = resp[:cas] @@ -167,10 +169,10 @@ def get_and_lock(id, lock_time, options = Options::GetAndLock::DEFAULT) # # @return [GetResult] def get_and_touch(id, expiry, options = Options::GetAndTouch::DEFAULT) - @observability.record_operation(Observability::OP_GET_AND_TOUCH, options.parent_span, self, :kv) do |_obs_handler| + @observability.record_operation(Observability::OP_GET_AND_TOUCH, options.parent_span, self, :kv) do |obs_handler| resp = @backend.document_get_and_touch(bucket_name, @scope_name, @name, id, Utils::Time.extract_expiry_time(expiry), - options.to_backend) + options.to_backend, obs_handler) GetResult.new do |res| res.transcoder = options.transcoder res.cas = resp[:cas] @@ -187,8 +189,8 @@ def get_and_touch(id, expiry, options = Options::GetAndTouch::DEFAULT) # # @return [Array] def get_all_replicas(id, options = Options::GetAllReplicas::DEFAULT) - @observability.record_operation(Observability::OP_GET_ALL_REPLICAS, options.parent_span, self, :kv) do |_obs_handler| - resp = @backend.document_get_all_replicas(@bucket_name, @scope_name, @name, id, options.to_backend) + @observability.record_operation(Observability::OP_GET_ALL_REPLICAS, options.parent_span, self, :kv) do |obs_handler| + resp = @backend.document_get_all_replicas(@bucket_name, @scope_name, @name, id, options.to_backend, obs_handler) resp.map do |entry| GetReplicaResult.new do |res| res.transcoder = options.transcoder @@ -219,8 +221,8 @@ def get_all_replicas(id, options = Options::GetAllReplicas::DEFAULT) # # @return [GetReplicaResult] def get_any_replica(id, options = Options::GetAnyReplica::DEFAULT) - @observability.record_operation(Observability::OP_GET_ANY_REPLICA, options.parent_span, self, :kv) do |_obs_handler| - resp = @backend.document_get_any_replica(@bucket_name, @scope_name, @name, id, options.to_backend) + @observability.record_operation(Observability::OP_GET_ANY_REPLICA, options.parent_span, self, :kv) do |obs_handler| + resp = @backend.document_get_any_replica(@bucket_name, @scope_name, @name, id, options.to_backend, obs_handler) GetReplicaResult.new do |res| res.transcoder = options.transcoder res.cas = resp[:cas] @@ -242,8 +244,8 @@ def get_any_replica(id, options = Options::GetAnyReplica::DEFAULT) # # @return [ExistsResult] def exists(id, options = Options::Exists::DEFAULT) - @observability.record_operation(Observability::OP_EXISTS, options.parent_span, self, :kv) do |_obs_handler| - resp = @backend.document_exists(bucket_name, @scope_name, @name, id, options.to_backend) + @observability.record_operation(Observability::OP_EXISTS, options.parent_span, self, :kv) do |obs_handler| + resp = @backend.document_exists(bucket_name, @scope_name, @name, id, options.to_backend, obs_handler) ExistsResult.new do |res| res.deleted = resp[:deleted] res.exists = resp[:exists] @@ -279,7 +281,7 @@ def exists(id, options = Options::Exists::DEFAULT) def remove(id, options = Options::Remove::DEFAULT) @observability.record_operation(Observability::OP_REMOVE, options.parent_span, self, :kv) do |obs_handler| obs_handler.add_durability_level(options.durability_level) - resp = @backend.document_remove(bucket_name, @scope_name, @name, id, options.to_backend) + resp = @backend.document_remove(bucket_name, @scope_name, @name, id, options.to_backend, obs_handler) MutationResult.new do |res| res.cas = resp[:cas] res.mutation_token = extract_mutation_token(resp) @@ -352,7 +354,7 @@ def insert(id, content, options = Options::Insert::DEFAULT) @observability.record_operation(Observability::OP_INSERT, options.parent_span, self, :kv) do |obs_handler| obs_handler.add_durability_level(options.durability_level) blob, flags = encode_content(content, options, obs_handler) - resp = @backend.document_insert(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend) + resp = @backend.document_insert(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend, obs_handler) MutationResult.new do |res| res.cas = resp[:cas] res.mutation_token = extract_mutation_token(resp) @@ -375,7 +377,7 @@ def upsert(id, content, options = Options::Upsert::DEFAULT) @observability.record_operation(Observability::OP_UPSERT, options.parent_span, self, :kv) do |obs_handler| obs_handler.add_durability_level(options.durability_level) blob, flags = encode_content(content, options, obs_handler) - resp = @backend.document_upsert(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend) + resp = @backend.document_upsert(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend, obs_handler) MutationResult.new do |res| res.cas = resp[:cas] res.mutation_token = extract_mutation_token(resp) @@ -432,7 +434,7 @@ def replace(id, content, options = Options::Replace::DEFAULT) @observability.record_operation(Observability::OP_REPLACE, options.parent_span, self, :kv) do |obs_handler| obs_handler.add_durability_level(options.durability_level) blob, flags = encode_content(content, options, obs_handler) - resp = @backend.document_replace(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend) + resp = @backend.document_replace(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend, obs_handler) MutationResult.new do |res| res.cas = resp[:cas] res.mutation_token = extract_mutation_token(resp) @@ -451,10 +453,10 @@ def replace(id, content, options = Options::Replace::DEFAULT) # # @return [MutationResult] def touch(id, expiry, options = Options::Touch::DEFAULT) - @observability.record_operation(Observability::OP_TOUCH, options.parent_span, self, :kv) do |_obs_handler| + @observability.record_operation(Observability::OP_TOUCH, options.parent_span, self, :kv) do |obs_handler| resp = @backend.document_touch(bucket_name, @scope_name, @name, id, Utils::Time.extract_expiry_time(expiry), - options.to_backend) + options.to_backend, obs_handler) MutationResult.new do |res| res.cas = resp[:cas] end @@ -475,8 +477,8 @@ def touch(id, expiry, options = Options::Touch::DEFAULT) # # @raise [Error::DocumentNotFound] def unlock(id, cas, options = Options::Unlock::DEFAULT) - @observability.record_operation(Observability::OP_UNLOCK, options.parent_span, self, :kv) do |_obs_handler| - @backend.document_unlock(bucket_name, @scope_name, @name, id, cas, options.to_backend) + @observability.record_operation(Observability::OP_UNLOCK, options.parent_span, self, :kv) do |obs_handler| + @backend.document_unlock(bucket_name, @scope_name, @name, id, cas, options.to_backend, obs_handler) end end @@ -499,7 +501,7 @@ def unlock(id, cas, options = Options::Unlock::DEFAULT) # ] # @return [LookupInResult] def lookup_in(id, specs, options = Options::LookupIn::DEFAULT) - @observability.record_operation(Observability::OP_LOOKUP_IN, options.parent_span, self, :kv) do |_obs_handler| + @observability.record_operation(Observability::OP_LOOKUP_IN, options.parent_span, self, :kv) do |obs_handler| resp = @backend.document_lookup_in( bucket_name, @scope_name, @name, id, specs.map do |s| @@ -508,7 +510,7 @@ def lookup_in(id, specs, options = Options::LookupIn::DEFAULT) xattr: s.xattr?, path: s.path, } - end, options.to_backend + end, options.to_backend, obs_handler ) LookupInResult.new do |res| res.transcoder = options.transcoder @@ -541,7 +543,7 @@ def lookup_in(id, specs, options = Options::LookupIn::DEFAULT) # @raise [Error::CouchbaseError] # @raise [Error::FeatureNotAvailable] def lookup_in_any_replica(id, specs, options = Options::LookupInAnyReplica::DEFAULT) - @observability.record_operation(Observability::OP_LOOKUP_IN_ANY_REPLICA, options.parent_span, self, :kv) do |_obs_handler| + @observability.record_operation(Observability::OP_LOOKUP_IN_ANY_REPLICA, options.parent_span, self, :kv) do |obs_handler| resp = @backend.document_lookup_in_any_replica( bucket_name, @scope_name, @name, id, specs.map do |s| @@ -550,7 +552,7 @@ def lookup_in_any_replica(id, specs, options = Options::LookupInAnyReplica::DEFA xattr: s.xattr?, path: s.path, } - end, options.to_backend + end, options.to_backend, obs_handler ) extract_lookup_in_replica_result(resp, options) end @@ -570,7 +572,7 @@ def lookup_in_any_replica(id, specs, options = Options::LookupInAnyReplica::DEFA # @raise [Error::CouchbaseError] # @raise [Error::FeatureNotAvailable] def lookup_in_all_replicas(id, specs, options = Options::LookupInAllReplicas::DEFAULT) - @observability.record_operation(Observability::OP_LOOKUP_IN_ALL_REPLICAS, options.parent_span, self, :kv) do |_obs_handler| + @observability.record_operation(Observability::OP_LOOKUP_IN_ALL_REPLICAS, options.parent_span, self, :kv) do |obs_handler| resp = @backend.document_lookup_in_all_replicas( bucket_name, @scope_name, @name, id, specs.map do |s| @@ -579,7 +581,7 @@ def lookup_in_all_replicas(id, specs, options = Options::LookupInAllReplicas::DE xattr: s.xattr?, path: s.path, } - end, options.to_backend + end, options.to_backend, obs_handler ) resp.map do |entry| extract_lookup_in_replica_result(entry, options) @@ -621,7 +623,7 @@ def mutate_in(id, specs, options = Options::MutateIn::DEFAULT) expand_macros: s.expand_macros?, create_path: s.create_path?, } - end, options.to_backend + end, options.to_backend, obs_handler ) MutateInResult.new do |res| res.transcoder = options.transcoder diff --git a/lib/couchbase/management/analytics_index_manager.rb b/lib/couchbase/management/analytics_index_manager.rb index 0622cf8a..88ad4399 100644 --- a/lib/couchbase/management/analytics_index_manager.rb +++ b/lib/couchbase/management/analytics_index_manager.rb @@ -644,8 +644,8 @@ def initialize(backend, observability) # @raise [ArgumentError] # @raise [Error::DataverseExists] def create_dataverse(dataverse_name, options = Options::Analytics::CreateDataverse.new) - @observability.record_operation(Observability::OP_AM_CREATE_DATAVERSE, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_dataverse_create(dataverse_name, options.to_backend) + @observability.record_operation(Observability::OP_AM_CREATE_DATAVERSE, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_dataverse_create(dataverse_name, options.to_backend, obs_handler) end end @@ -659,8 +659,8 @@ def create_dataverse(dataverse_name, options = Options::Analytics::CreateDataver # @raise [ArgumentError] # @raise [Error::DataverseNotFound] def drop_dataverse(dataverse_name, options = Options::Analytics::DropDataverse.new) - @observability.record_operation(Observability::OP_AM_DROP_DATAVERSE, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_dataverse_drop(dataverse_name, options.to_backend) + @observability.record_operation(Observability::OP_AM_DROP_DATAVERSE, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_dataverse_drop(dataverse_name, options.to_backend, obs_handler) end end @@ -691,8 +691,8 @@ def create_dataset(dataset_name, bucket_name, options = Options::Analytics::Crea # @raise [ArgumentError] # @raise [Error::DatasetNotFound] def drop_dataset(dataset_name, options = Options::Analytics::DropDataset.new) - @observability.record_operation(Observability::OP_AM_DROP_DATASET, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_dataset_drop(dataset_name, options.to_backend) + @observability.record_operation(Observability::OP_AM_DROP_DATASET, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_dataset_drop(dataset_name, options.to_backend, obs_handler) end end @@ -702,8 +702,8 @@ def drop_dataset(dataset_name, options = Options::Analytics::DropDataset.new) # # @return [Array] def get_all_datasets(options = Options::Analytics::GetAllDatasets.new) - @observability.record_operation(Observability::OP_AM_GET_ALL_DATASETS, options.parent_span, self, :analytics) do |_obs_handler| - resp = @backend.analytics_dataset_get_all(options.to_backend) + @observability.record_operation(Observability::OP_AM_GET_ALL_DATASETS, options.parent_span, self, :analytics) do |obs_handler| + resp = @backend.analytics_dataset_get_all(options.to_backend, obs_handler) resp.map do |entry| AnalyticsDataset.new do |dataset| dataset.name = entry[:name] @@ -727,8 +727,8 @@ def get_all_datasets(options = Options::Analytics::GetAllDatasets.new) # @raise [ArgumentError] # @raise [Error::IndexExists] def create_index(index_name, dataset_name, fields, options = Options::Analytics::CreateIndex.new) - @observability.record_operation(Observability::OP_AM_CREATE_INDEX, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_index_create(index_name, dataset_name, fields.entries, options.to_backend) + @observability.record_operation(Observability::OP_AM_CREATE_INDEX, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_index_create(index_name, dataset_name, fields.entries, options.to_backend, obs_handler) end end @@ -743,8 +743,8 @@ def create_index(index_name, dataset_name, fields, options = Options::Analytics: # @raise [ArgumentError] # @raise [Error::IndexNotFound] def drop_index(index_name, dataset_name, options = Options::Analytics::DropIndex.new) - @observability.record_operation(Observability::OP_AM_DROP_INDEX, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_index_drop(index_name, dataset_name, options.to_backend) + @observability.record_operation(Observability::OP_AM_DROP_INDEX, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_index_drop(index_name, dataset_name, options.to_backend, obs_handler) end end @@ -754,8 +754,8 @@ def drop_index(index_name, dataset_name, options = Options::Analytics::DropIndex # # @return [Array] def get_all_indexes(options = Options::Analytics::GetAllIndexes.new) - @observability.record_operation(Observability::OP_AM_GET_ALL_INDEXES, options.parent_span, self, :analytics) do |_obs_handler| - resp = @backend.analytics_index_get_all(options.to_backend) + @observability.record_operation(Observability::OP_AM_GET_ALL_INDEXES, options.parent_span, self, :analytics) do |obs_handler| + resp = @backend.analytics_index_get_all(options.to_backend, obs_handler) resp.map do |entry| AnalyticsIndex.new do |dataset| dataset.name = entry[:name] @@ -776,8 +776,8 @@ def get_all_indexes(options = Options::Analytics::GetAllIndexes.new) # @raise [ArgumentError] # @raise [Error::LinkNotFound] def connect_link(options = Options::Analytics::ConnectLink.new) - @observability.record_operation(Observability::OP_AM_CONNECT_LINK, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_link_connect(options.to_backend) + @observability.record_operation(Observability::OP_AM_CONNECT_LINK, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_link_connect(options.to_backend, obs_handler) end end @@ -790,8 +790,8 @@ def connect_link(options = Options::Analytics::ConnectLink.new) # @raise [ArgumentError] # @raise [Error::LinkNotFound] def disconnect_link(options = Options::Analytics::DisconnectLink.new) - @observability.record_operation(Observability::OP_AM_DISCONNECT_LINK, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_link_disconnect(options.to_backend) + @observability.record_operation(Observability::OP_AM_DISCONNECT_LINK, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_link_disconnect(options.to_backend, obs_handler) end end @@ -805,8 +805,8 @@ def disconnect_link(options = Options::Analytics::DisconnectLink.new) # @return [Hash Integer>] dictionary, where keys are dataset coordinates encoded as +"dataverse.dataset"+ # and values are number of mutations for given dataset. def get_pending_mutations(options = Options::Analytics::GetPendingMutations.new) - @observability.record_operation(Observability::OP_AM_GET_PENDING_MUTATIONS, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_get_pending_mutations(options.to_backend) + @observability.record_operation(Observability::OP_AM_GET_PENDING_MUTATIONS, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_get_pending_mutations(options.to_backend, obs_handler) end end @@ -820,8 +820,8 @@ def get_pending_mutations(options = Options::Analytics::GetPendingMutations.new) # @raise [ArgumentError] # @raise [Error::LinkExists] def create_link(link, options = Options::Analytics::CreateLink.new) - @observability.record_operation(Observability::OP_AM_CREATE_LINK, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_link_create(link.to_backend, options.to_backend) + @observability.record_operation(Observability::OP_AM_CREATE_LINK, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_link_create(link.to_backend, options.to_backend, obs_handler) end end @@ -835,8 +835,8 @@ def create_link(link, options = Options::Analytics::CreateLink.new) # @raise [ArgumentError] # @raise [Error::LinkNotFound] def replace_link(link, options = Options::Analytics::ReplaceLink.new) - @observability.record_operation(Observability::OP_AM_REPLACE_LINK, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_link_replace(link.to_backend, options.to_backend) + @observability.record_operation(Observability::OP_AM_REPLACE_LINK, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_link_replace(link.to_backend, options.to_backend, obs_handler) end end @@ -851,8 +851,8 @@ def replace_link(link, options = Options::Analytics::ReplaceLink.new) # @raise [ArgumentError] # @raise [Error::LinkNotFound] def drop_link(link_name, dataverse_name, options = Options::Analytics::DropLink.new) - @observability.record_operation(Observability::OP_AM_DROP_LINK, options.parent_span, self, :analytics) do |_obs_handler| - @backend.analytics_link_drop(link_name, dataverse_name, options.to_backend) + @observability.record_operation(Observability::OP_AM_DROP_LINK, options.parent_span, self, :analytics) do |obs_handler| + @backend.analytics_link_drop(link_name, dataverse_name, options.to_backend, obs_handler) end end @@ -865,8 +865,8 @@ def drop_link(link_name, dataverse_name, options = Options::Analytics::DropLink. # @raise [ArgumentError] # @raise [Error::LinkNotFound] def get_links(options = Options::Analytics::GetLinks.new) - @observability.record_operation(Observability::OP_AM_GET_LINKS, options.parent_span, self, :analytics) do |_obs_handler| - resp = @backend.analytics_link_get_all(options.to_backend) + @observability.record_operation(Observability::OP_AM_GET_LINKS, options.parent_span, self, :analytics) do |obs_handler| + resp = @backend.analytics_link_get_all(options.to_backend, obs_handler) resp.map do |entry| case entry[:type] when :s3 diff --git a/lib/couchbase/management/bucket_manager.rb b/lib/couchbase/management/bucket_manager.rb index ce65a130..73c53dec 100644 --- a/lib/couchbase/management/bucket_manager.rb +++ b/lib/couchbase/management/bucket_manager.rb @@ -229,7 +229,9 @@ def create_bucket(settings, options = Options::Bucket::CreateBucket.new) history_retention_duration: settings.history_retention_duration, history_retention_bytes: settings.history_retention_bytes, num_vbuckets: settings.num_vbuckets, - }, options.to_backend + }, + options.to_backend, + obs_handler, ) end end @@ -264,7 +266,9 @@ def update_bucket(settings, options = Options::Bucket::UpdateBucket.new) history_retention_bytes: settings.history_retention_bytes, history_retention_duration: settings.history_retention_duration, num_vbuckets: settings.num_vbuckets, - }, options.to_backend + }, + options.to_backend, + obs_handler, ) end end @@ -282,7 +286,7 @@ def drop_bucket(bucket_name, options = Options::Bucket::DropBucket.new) @observability.record_operation(Observability::OP_BM_DROP_BUCKET, options.parent_span, self, :management) do |obs_handler| obs_handler.add_bucket_name(bucket_name) - @backend.bucket_drop(bucket_name, options.to_backend) + @backend.bucket_drop(bucket_name, options.to_backend, obs_handler) end end @@ -299,7 +303,7 @@ def get_bucket(bucket_name, options = Options::Bucket::GetBucket.new) @observability.record_operation(Observability::OP_BM_GET_BUCKET, options.parent_span, self, :management) do |obs_handler| obs_handler.add_bucket_name(bucket_name) - extract_bucket_settings(@backend.bucket_get(bucket_name, options.to_backend)) + extract_bucket_settings(@backend.bucket_get(bucket_name, options.to_backend, obs_handler)) end end @@ -308,8 +312,8 @@ def get_bucket(bucket_name, options = Options::Bucket::GetBucket.new) # @param [Options::Bucket::GetAllBuckets] options # @return [Array] def get_all_buckets(options = Options::Bucket::GetAllBuckets.new) - @observability.record_operation(Observability::OP_BM_GET_ALL_BUCKETS, options.parent_span, self, :management) do |_obs_handler| - @backend.bucket_get_all(options.to_backend) + @observability.record_operation(Observability::OP_BM_GET_ALL_BUCKETS, options.parent_span, self, :management) do |obs_handler| + @backend.bucket_get_all(options.to_backend, obs_handler) .map { |entry| extract_bucket_settings(entry) } end end @@ -323,8 +327,8 @@ def get_all_buckets(options = Options::Bucket::GetAllBuckets.new) # @raise [Error::BucketNotFound] # @raise [Error::BucketNotFlushable] def flush_bucket(bucket_name, options = Options::Bucket::FlushBucket.new) - @observability.record_operation(Observability::OP_BM_FLUSH_BUCKET, options.parent_span, self, :management) do |_obs_handler| - @backend.bucket_flush(bucket_name, options.to_backend) + @observability.record_operation(Observability::OP_BM_FLUSH_BUCKET, options.parent_span, self, :management) do |obs_handler| + @backend.bucket_flush(bucket_name, options.to_backend, obs_handler) end end diff --git a/lib/couchbase/management/collection_manager.rb b/lib/couchbase/management/collection_manager.rb index 12148c76..e9b78ca8 100644 --- a/lib/couchbase/management/collection_manager.rb +++ b/lib/couchbase/management/collection_manager.rb @@ -213,8 +213,8 @@ def initialize(backend, bucket_name, observability) # # @return [Array] def get_all_scopes(options = Options::Collection::GetAllScopes.new) - @observability.record_operation(Observability::OP_CM_GET_ALL_SCOPES, options.parent_span, self, :management) do |_obs_handler| - res = @backend.scope_get_all(@bucket_name, options.to_backend) + @observability.record_operation(Observability::OP_CM_GET_ALL_SCOPES, options.parent_span, self, :management) do |obs_handler| + res = @backend.scope_get_all(@bucket_name, options.to_backend, obs_handler) res[:scopes].map do |s| ScopeSpec.new do |scope| scope.name = s[:name] @@ -245,7 +245,7 @@ def get_scope(scope_name, options = GetScopeOptions.new) @observability.record_operation(Observability::OP_CM_GET_SCOPE, options.parent_span, self, :management) do |obs_handler| obs_handler.add_scope_name(scope_name) - get_all_scopes(Options::Collection::GetAllScopes(timeout: options.timeout, parent_span: options.parent_span)) + get_all_scopes(Options::Collection::GetAllScopes(timeout: options.timeout, parent_span: obs_handler.op_span)) .find { |scope| scope.name == scope_name } or raise Error::ScopeNotFound, "unable to find scope #{scope_name}" end end @@ -264,7 +264,7 @@ def create_scope(scope_name, options = Options::Collection::CreateScope.new) @observability.record_operation(Observability::OP_CM_CREATE_SCOPE, options.parent_span, self, :management) do |obs_handler| obs_handler.add_scope_name(scope_name) - @backend.scope_create(@bucket_name, scope_name, options.to_backend) + @backend.scope_create(@bucket_name, scope_name, options.to_backend, obs_handler) end end @@ -280,7 +280,7 @@ def drop_scope(scope_name, options = Options::Collection::DropScope.new) @observability.record_operation(Observability::OP_CM_DROP_SCOPE, options.parent_span, self, :management) do |obs_handler| obs_handler.add_scope_name(scope_name) - @backend.scope_drop(@bucket_name, scope_name, options.to_backend) + @backend.scope_drop(@bucket_name, scope_name, options.to_backend, obs_handler) end end @@ -328,7 +328,7 @@ def create_collection(*args) obs_handler.add_scope_name(scope_name) obs_handler.add_collection_name(collection_name) - @backend.collection_create(@bucket_name, scope_name, collection_name, settings.to_backend, options.to_backend) + @backend.collection_create(@bucket_name, scope_name, collection_name, settings.to_backend, options.to_backend, obs_handler) end end @@ -347,7 +347,7 @@ def update_collection(scope_name, collection_name, settings = UpdateCollectionSe obs_handler.add_scope_name(scope_name) obs_handler.add_collection_name(collection_name) - @backend.collection_update(@bucket_name, scope_name, collection_name, settings.to_backend, options.to_backend) + @backend.collection_update(@bucket_name, scope_name, collection_name, settings.to_backend, options.to_backend, obs_handler) end end @@ -390,7 +390,7 @@ def drop_collection(*args) obs_handler.add_scope_name(scope_name) obs_handler.add_collection_name(collection_name) - @backend.collection_drop(@bucket_name, scope_name, collection_name, options.to_backend) + @backend.collection_drop(@bucket_name, scope_name, collection_name, options.to_backend, obs_handler) end end diff --git a/lib/couchbase/management/collection_query_index_manager.rb b/lib/couchbase/management/collection_query_index_manager.rb index 19bc811b..2b373dcd 100644 --- a/lib/couchbase/management/collection_query_index_manager.rb +++ b/lib/couchbase/management/collection_query_index_manager.rb @@ -56,8 +56,8 @@ def get_all_indexes(options = Options::Query::GetAllIndexes.new) "Collection name cannot be set in the options when using the Query Index manager at the collection level" end - @observability.record_operation(Observability::OP_QM_GET_ALL_INDEXES, options.parent_span, self, :query) do |_obs_handler| - res = @backend.collection_query_index_get_all(@bucket_name, @scope_name, @collection_name, options.to_backend) + @observability.record_operation(Observability::OP_QM_GET_ALL_INDEXES, options.parent_span, self, :query) do |obs_handler| + res = @backend.collection_query_index_get_all(@bucket_name, @scope_name, @collection_name, options.to_backend, obs_handler) res[:indexes].map do |idx| QueryIndex.new do |index| index.name = idx[:name] @@ -96,8 +96,9 @@ def create_index(index_name, fields, options = Options::Query::CreateIndex.new) "Collection name cannot be set in the options when using the Query Index manager at the collection level" end - @observability.record_operation(Observability::OP_QM_CREATE_INDEX, options.parent_span, self, :query) do |_obs_handler| - @backend.collection_query_index_create(@bucket_name, @scope_name, @collection_name, index_name, fields, options.to_backend) + @observability.record_operation(Observability::OP_QM_CREATE_INDEX, options.parent_span, self, :query) do |obs_handler| + @backend.collection_query_index_create(@bucket_name, @scope_name, @collection_name, index_name, fields, options.to_backend, + obs_handler) end end @@ -120,8 +121,8 @@ def create_primary_index(options = Options::Query::CreatePrimaryIndex.new) "Collection name cannot be set in the options when using the Query Index manager at the collection level" end - @observability.record_operation(Observability::OP_QM_CREATE_PRIMARY_INDEX, options.parent_span, self, :query) do |_obs_handler| - @backend.collection_query_index_create_primary(@bucket_name, @scope_name, @collection_name, options.to_backend) + @observability.record_operation(Observability::OP_QM_CREATE_PRIMARY_INDEX, options.parent_span, self, :query) do |obs_handler| + @backend.collection_query_index_create_primary(@bucket_name, @scope_name, @collection_name, options.to_backend, obs_handler) end end @@ -145,8 +146,8 @@ def drop_index(index_name, options = Options::Query::DropIndex.new) "Collection name cannot be set in the options when using the Query Index manager at the collection level" end - @observability.record_operation(Observability::OP_QM_DROP_INDEX, options.parent_span, self, :query) do |_obs_handler| - @backend.collection_query_index_drop(@bucket_name, @scope_name, @collection_name, index_name, options.to_backend) + @observability.record_operation(Observability::OP_QM_DROP_INDEX, options.parent_span, self, :query) do |obs_handler| + @backend.collection_query_index_drop(@bucket_name, @scope_name, @collection_name, index_name, options.to_backend, obs_handler) end end @@ -169,8 +170,8 @@ def drop_primary_index(options = Options::Query::DropPrimaryIndex.new) "Collection name cannot be set in the options when using the Query Index manager at the collection level" end - @observability.record_operation(Observability::OP_QM_DROP_PRIMARY_INDEX, options.parent_span, self, :query) do |_obs_handler| - @backend.collection_query_index_drop_primary(@bucket_name, @scope_name, @collection_name, options.to_backend) + @observability.record_operation(Observability::OP_QM_DROP_PRIMARY_INDEX, options.parent_span, self, :query) do |obs_handler| + @backend.collection_query_index_drop_primary(@bucket_name, @scope_name, @collection_name, options.to_backend, obs_handler) end end @@ -192,8 +193,8 @@ def build_deferred_indexes(options = Options::Query::BuildDeferredIndexes.new) "Collection name cannot be set in the options when using the Query Index manager at the collection level" end - @observability.record_operation(Observability::OP_QM_BUILD_DEFERRED_INDEXES, options.parent_span, self, :query) do |_obs_handler| - @backend.collection_query_index_build_deferred(@bucket_name, @scope_name, @collection_name, options.to_backend) + @observability.record_operation(Observability::OP_QM_BUILD_DEFERRED_INDEXES, options.parent_span, self, :query) do |obs_handler| + @backend.collection_query_index_build_deferred(@bucket_name, @scope_name, @collection_name, options.to_backend, obs_handler) end end diff --git a/lib/couchbase/management/query_index_manager.rb b/lib/couchbase/management/query_index_manager.rb index 7a81894c..3b1eb472 100644 --- a/lib/couchbase/management/query_index_manager.rb +++ b/lib/couchbase/management/query_index_manager.rb @@ -411,7 +411,7 @@ def get_all_indexes(bucket_name, options = GetAllIndexOptions.new) obs_handler.add_scope_name(options.scope_name) unless options.scope_name.nil? obs_handler.add_collection_name(options.collection_name) unless options.collection_name.nil? - res = @backend.query_index_get_all(bucket_name, options.to_backend) + res = @backend.query_index_get_all(bucket_name, options.to_backend, obs_handler) res[:indexes].map do |idx| QueryIndex.new do |index| index.name = idx[:name] @@ -450,7 +450,7 @@ def create_index(bucket_name, index_name, fields, options = Options::Query::Crea obs_handler.add_scope_name(options.scope_name) unless options.scope_name.nil? obs_handler.add_collection_name(options.collection_name) unless options.collection_name.nil? - @backend.query_index_create(bucket_name, index_name, fields, options.to_backend) + @backend.query_index_create(bucket_name, index_name, fields, options.to_backend, obs_handler) end end @@ -473,7 +473,7 @@ def create_primary_index(bucket_name, options = Options::Query::CreatePrimaryInd obs_handler.add_scope_name(options.scope_name) unless options.scope_name.nil? obs_handler.add_collection_name(options.collection_name) unless options.collection_name.nil? - @backend.query_index_create_primary(bucket_name, options.to_backend) + @backend.query_index_create_primary(bucket_name, options.to_backend, obs_handler) end end @@ -497,7 +497,7 @@ def drop_index(bucket_name, index_name, options = Options::Query::DropIndex.new) obs_handler.add_scope_name(options.scope_name) unless options.scope_name.nil? obs_handler.add_collection_name(options.collection_name) unless options.collection_name.nil? - @backend.query_index_drop(bucket_name, index_name, options.to_backend) + @backend.query_index_drop(bucket_name, index_name, options.to_backend, obs_handler) end end @@ -520,7 +520,7 @@ def drop_primary_index(bucket_name, options = Options::Query::DropPrimaryIndex.n obs_handler.add_scope_name(options.scope_name) unless options.scope_name.nil? obs_handler.add_collection_name(options.collection_name) unless options.collection_name.nil? - @backend.query_index_drop_primary(bucket_name, options.to_backend) + @backend.query_index_drop_primary(bucket_name, options.to_backend, obs_handler) end end @@ -542,7 +542,7 @@ def build_deferred_indexes(bucket_name, options = Options::Query::BuildDeferredI obs_handler.add_scope_name(options.scope_name) unless options.scope_name.nil? obs_handler.add_collection_name(options.collection_name) unless options.collection_name.nil? - @backend.query_index_build_deferred(bucket_name, options.to_backend) + @backend.query_index_build_deferred(bucket_name, options.to_backend, obs_handler) end end diff --git a/lib/couchbase/management/scope_search_index_manager.rb b/lib/couchbase/management/scope_search_index_manager.rb index 3acbbd25..2c63bd84 100644 --- a/lib/couchbase/management/scope_search_index_manager.rb +++ b/lib/couchbase/management/scope_search_index_manager.rb @@ -42,8 +42,8 @@ def initialize(backend, bucket_name, scope_name, observability) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def get_index(index_name, options = Options::Search::GetIndex::DEFAULT) - @observability.record_operation(Observability::OP_SM_GET_INDEX, options.parent_span, self, :search) do |_obs_handler| - res = @backend.search_index_get(@bucket_name, @scope_name, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_GET_INDEX, options.parent_span, self, :search) do |obs_handler| + res = @backend.search_index_get(@bucket_name, @scope_name, index_name, options.timeout, obs_handler) SearchIndexManager.extract_search_index(res) end end @@ -54,8 +54,8 @@ def get_index(index_name, options = Options::Search::GetIndex::DEFAULT) # # @return [Array] def get_all_indexes(options = Options::Search::GetAllIndexes::DEFAULT) - @observability.record_operation(Observability::OP_SM_GET_ALL_INDEXES, options.parent_span, self, :search) do |_obs_handler| - res = @backend.search_index_get_all(@bucket_name, @scope_name, options.timeout) + @observability.record_operation(Observability::OP_SM_GET_ALL_INDEXES, options.parent_span, self, :search) do |obs_handler| + res = @backend.search_index_get_all(@bucket_name, @scope_name, options.timeout, obs_handler) res[:indexes].map { |idx| SearchIndexManager.extract_search_index(idx) } end end @@ -69,8 +69,8 @@ def get_all_indexes(options = Options::Search::GetAllIndexes::DEFAULT) # # @raise [ArgumentError] if name, type or source_type is empty def upsert_index(index_definition, options = Options::Search::UpsertIndex::DEFAULT) - @observability.record_operation(Observability::OP_SM_UPSERT_INDEX, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_upsert(@bucket_name, @scope_name, index_definition.to_backend, options.timeout) + @observability.record_operation(Observability::OP_SM_UPSERT_INDEX, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_upsert(@bucket_name, @scope_name, index_definition.to_backend, options.timeout, obs_handler) end end @@ -84,8 +84,8 @@ def upsert_index(index_definition, options = Options::Search::UpsertIndex::DEFAU # @raise [ArgumentError] # @raise [Error::IndexNotFound] def drop_index(index_name, options = Options::Search::DropIndex::DEFAULT) - @observability.record_operation(Observability::OP_SM_DROP_INDEX, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_drop(@bucket_name, @scope_name, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_DROP_INDEX, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_drop(@bucket_name, @scope_name, index_name, options.timeout, obs_handler) end end @@ -100,8 +100,8 @@ def drop_index(index_name, options = Options::Search::DropIndex::DEFAULT) # @raise [Error::IndexNotFound] def get_indexed_documents_count(index_name, options = Options::Search::GetIndexedDocumentsCount::DEFAULT) @observability.record_operation(Observability::OP_SM_GET_INDEXED_DOCUMENTS_COUNT, options.parent_span, self, - :search) do |_obs_handler| - res = @backend.search_index_get_documents_count(@bucket_name, @scope_name, index_name, options.timeout) + :search) do |obs_handler| + res = @backend.search_index_get_documents_count(@bucket_name, @scope_name, index_name, options.timeout, obs_handler) res[:count] end end @@ -116,8 +116,8 @@ def get_indexed_documents_count(index_name, options = Options::Search::GetIndexe # @raise [ArgumentError] # @raise [Error::IndexNotFound] def pause_ingest(index_name, options = Options::Search::PauseIngest::DEFAULT) - @observability.record_operation(Observability::OP_SM_PAUSE_INGEST, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_pause_ingest(@bucket_name, @scope_name, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_PAUSE_INGEST, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_pause_ingest(@bucket_name, @scope_name, index_name, options.timeout, obs_handler) end end @@ -131,8 +131,8 @@ def pause_ingest(index_name, options = Options::Search::PauseIngest::DEFAULT) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def resume_ingest(index_name, options = Options::Search::ResumeIngest::DEFAULT) - @observability.record_operation(Observability::OP_SM_RESUME_INGEST, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_resume_ingest(@bucket_name, @scope_name, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_RESUME_INGEST, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_resume_ingest(@bucket_name, @scope_name, index_name, options.timeout, obs_handler) end end @@ -146,8 +146,8 @@ def resume_ingest(index_name, options = Options::Search::ResumeIngest::DEFAULT) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def allow_querying(index_name, options = Options::Search::AllowQuerying::DEFAULT) - @observability.record_operation(Observability::OP_SM_ALLOW_QUERYING, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_allow_querying(@bucket_name, @scope_name, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_ALLOW_QUERYING, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_allow_querying(@bucket_name, @scope_name, index_name, options.timeout, obs_handler) end end @@ -161,8 +161,8 @@ def allow_querying(index_name, options = Options::Search::AllowQuerying::DEFAULT # @raise [ArgumentError] # @raise [Error::IndexNotFound] def disallow_querying(index_name, options = Options::Search::DisallowQuerying::DEFAULT) - @observability.record_operation(Observability::OP_SM_DISALLOW_QUERYING, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_disallow_querying(@bucket_name, @scope_name, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_DISALLOW_QUERYING, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_disallow_querying(@bucket_name, @scope_name, index_name, options.timeout, obs_handler) end end @@ -176,8 +176,8 @@ def disallow_querying(index_name, options = Options::Search::DisallowQuerying::D # @raise [ArgumentError] # @raise [Error::IndexNotFound] def freeze_plan(index_name, options = Options::Search::FreezePlan::DEFAULT) - @observability.record_operation(Observability::OP_SM_FREEZE_PLAN, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_freeze_plan(@bucket_name, @scope_name, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_FREEZE_PLAN, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_freeze_plan(@bucket_name, @scope_name, index_name, options.timeout, obs_handler) end end @@ -191,8 +191,8 @@ def freeze_plan(index_name, options = Options::Search::FreezePlan::DEFAULT) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def unfreeze_plan(index_name, options = Options::Search::UnfreezePlan::DEFAULT) - @observability.record_operation(Observability::OP_SM_UNFREEZE_PLAN, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_unfreeze_plan(@bucket_name, @scope_name, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_UNFREEZE_PLAN, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_unfreeze_plan(@bucket_name, @scope_name, index_name, options.timeout, obs_handler) end end @@ -207,8 +207,10 @@ def unfreeze_plan(index_name, options = Options::Search::UnfreezePlan::DEFAULT) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def analyze_document(index_name, document, options = Options::Search::AnalyzeDocument::DEFAULT) - @observability.record_operation(Observability::OP_SM_ANALYZE_DOCUMENT, options.parent_span, self, :search) do |_obs_handler| - res = @backend.search_index_analyze_document(@bucket_name, @scope_name, index_name, JSON.generate(document), options.timeout) + @observability.record_operation(Observability::OP_SM_ANALYZE_DOCUMENT, options.parent_span, self, :search) do |obs_handler| + res = @backend.search_index_analyze_document( + @bucket_name, @scope_name, index_name, JSON.generate(document), options.timeout, obs_handler + ) JSON.parse(res[:analysis]) end end diff --git a/lib/couchbase/management/search_index_manager.rb b/lib/couchbase/management/search_index_manager.rb index 88fb464b..acb780d6 100644 --- a/lib/couchbase/management/search_index_manager.rb +++ b/lib/couchbase/management/search_index_manager.rb @@ -305,8 +305,8 @@ def initialize(backend, observability) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def get_index(index_name, options = Options::Search::GetIndex::DEFAULT) - @observability.record_operation(Observability::OP_SM_GET_INDEX, options.parent_span, self, :search) do |_obs_handler| - res = @backend.search_index_get(nil, nil, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_GET_INDEX, options.parent_span, self, :search) do |obs_handler| + res = @backend.search_index_get(nil, nil, index_name, options.timeout, obs_handler) self.class.extract_search_index(res) end end @@ -317,8 +317,8 @@ def get_index(index_name, options = Options::Search::GetIndex::DEFAULT) # # @return [Array] def get_all_indexes(options = Options::Search::GetAllIndexes::DEFAULT) - @observability.record_operation(Observability::OP_SM_GET_ALL_INDEXES, options.parent_span, self, :search) do |_obs_handler| - res = @backend.search_index_get_all(nil, nil, options.timeout) + @observability.record_operation(Observability::OP_SM_GET_ALL_INDEXES, options.parent_span, self, :search) do |obs_handler| + res = @backend.search_index_get_all(nil, nil, options.timeout, obs_handler) res[:indexes].map { |idx| self.class.extract_search_index(idx) } end end @@ -332,7 +332,7 @@ def get_all_indexes(options = Options::Search::GetAllIndexes::DEFAULT) # # @raise [ArgumentError] if name, type or source_type is empty def upsert_index(index_definition, options = Options::Search::UpsertIndex::DEFAULT) - @observability.record_operation(Observability::OP_SM_UPSERT_INDEX, options.parent_span, self, :search) do |_obs_handler| + @observability.record_operation(Observability::OP_SM_UPSERT_INDEX, options.parent_span, self, :search) do |obs_handler| @backend.search_index_upsert( nil, nil, @@ -346,7 +346,9 @@ def upsert_index(index_definition, options = Options::Search::UpsertIndex::DEFAU source_uuid: index_definition.source_uuid, source_params: (JSON.generate(index_definition.source_params) if index_definition.source_params), plan_params: (JSON.generate(index_definition.plan_params) if index_definition.plan_params), - }, options.timeout + }, + options.timeout, + obs_handler, ) end end @@ -361,8 +363,8 @@ def upsert_index(index_definition, options = Options::Search::UpsertIndex::DEFAU # @raise [ArgumentError] # @raise [Error::IndexNotFound] def drop_index(index_name, options = Options::Search::DropIndex::DEFAULT) - @observability.record_operation(Observability::OP_SM_DROP_INDEX, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_drop(nil, nil, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_DROP_INDEX, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_drop(nil, nil, index_name, options.timeout, obs_handler) end end @@ -377,8 +379,8 @@ def drop_index(index_name, options = Options::Search::DropIndex::DEFAULT) # @raise [Error::IndexNotFound] def get_indexed_documents_count(index_name, options = Options::Search::GetIndexedDocumentsCount::DEFAULT) @observability.record_operation(Observability::OP_SM_GET_INDEXED_DOCUMENTS_COUNT, options.parent_span, self, - :search) do |_obs_handler| - res = @backend.search_index_get_documents_count(nil, nil, index_name, options.timeout) + :search) do |obs_handler| + res = @backend.search_index_get_documents_count(nil, nil, index_name, options.timeout, obs_handler) res[:count] end end @@ -395,8 +397,8 @@ def get_indexed_documents_count(index_name, options = Options::Search::GetIndexe # @raise [ArgumentError] # @raise [Error::IndexNotFound] def get_index_stats(index_name, options = Options::Search::GetIndexStats::DEFAULT) - @observability.record_operation(Observability::OP_SM_GET_INDEX_STATS, options.parent_span, self, :search) do |_obs_handler| - res = @backend.search_index_get_stats(index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_GET_INDEX_STATS, options.parent_span, self, :search) do |obs_handler| + res = @backend.search_index_get_stats(index_name, options.timeout, obs_handler) JSON.parse(res) end end @@ -412,8 +414,8 @@ def get_index_stats(index_name, options = Options::Search::GetIndexStats::DEFAUL # # @raise [ArgumentError] def get_stats(options = Options::Search::GetIndexStats::DEFAULT) - @observability.record_operation(Observability::OP_SM_GET_STATS, options.parent_span, self, :search) do |_obs_handler| - res = @backend.search_get_stats(options.timeout) + @observability.record_operation(Observability::OP_SM_GET_STATS, options.parent_span, self, :search) do |obs_handler| + res = @backend.search_get_stats(options.timeout, obs_handler) JSON.parse(res) end end @@ -428,8 +430,8 @@ def get_stats(options = Options::Search::GetIndexStats::DEFAULT) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def pause_ingest(index_name, options = Options::Search::PauseIngest::DEFAULT) - @observability.record_operation(Observability::OP_SM_PAUSE_INGEST, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_pause_ingest(nil, nil, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_PAUSE_INGEST, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_pause_ingest(nil, nil, index_name, options.timeout, obs_handler) end end @@ -443,8 +445,8 @@ def pause_ingest(index_name, options = Options::Search::PauseIngest::DEFAULT) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def resume_ingest(index_name, options = Options::Search::ResumeIngest::DEFAULT) - @observability.record_operation(Observability::OP_SM_RESUME_INGEST, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_resume_ingest(nil, nil, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_RESUME_INGEST, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_resume_ingest(nil, nil, index_name, options.timeout, obs_handler) end end @@ -458,8 +460,8 @@ def resume_ingest(index_name, options = Options::Search::ResumeIngest::DEFAULT) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def allow_querying(index_name, options = Options::Search::AllowQuerying::DEFAULT) - @observability.record_operation(Observability::OP_SM_ALLOW_QUERYING, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_allow_querying(nil, nil, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_ALLOW_QUERYING, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_allow_querying(nil, nil, index_name, options.timeout, obs_handler) end end @@ -473,8 +475,8 @@ def allow_querying(index_name, options = Options::Search::AllowQuerying::DEFAULT # @raise [ArgumentError] # @raise [Error::IndexNotFound] def disallow_querying(index_name, options = Options::Search::DisallowQuerying::DEFAULT) - @observability.record_operation(Observability::OP_SM_DISALLOW_QUERYING, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_disallow_querying(nil, nil, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_DISALLOW_QUERYING, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_disallow_querying(nil, nil, index_name, options.timeout, obs_handler) end end @@ -488,8 +490,8 @@ def disallow_querying(index_name, options = Options::Search::DisallowQuerying::D # @raise [ArgumentError] # @raise [Error::IndexNotFound] def freeze_plan(index_name, options = Options::Search::FreezePlan::DEFAULT) - @observability.record_operation(Observability::OP_SM_FREEZE_PLAN, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_freeze_plan(nil, nil, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_FREEZE_PLAN, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_freeze_plan(nil, nil, index_name, options.timeout, obs_handler) end end @@ -503,8 +505,8 @@ def freeze_plan(index_name, options = Options::Search::FreezePlan::DEFAULT) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def unfreeze_plan(index_name, options = Options::Search::UnfreezePlan::DEFAULT) - @observability.record_operation(Observability::OP_SM_UNFREEZE_PLAN, options.parent_span, self, :search) do |_obs_handler| - @backend.search_index_unfreeze_plan(nil, nil, index_name, options.timeout) + @observability.record_operation(Observability::OP_SM_UNFREEZE_PLAN, options.parent_span, self, :search) do |obs_handler| + @backend.search_index_unfreeze_plan(nil, nil, index_name, options.timeout, obs_handler) end end @@ -519,8 +521,8 @@ def unfreeze_plan(index_name, options = Options::Search::UnfreezePlan::DEFAULT) # @raise [ArgumentError] # @raise [Error::IndexNotFound] def analyze_document(index_name, document, options = Options::Search::AnalyzeDocument::DEFAULT) - @observability.record_operation(Observability::OP_SM_ANALYZE_DOCUMENT, options.parent_span, self, :search) do |_obs_handler| - res = @backend.search_index_analyze_document(nil, nil, index_name, JSON.generate(document), options.timeout) + @observability.record_operation(Observability::OP_SM_ANALYZE_DOCUMENT, options.parent_span, self, :search) do |obs_handler| + res = @backend.search_index_analyze_document(nil, nil, index_name, JSON.generate(document), options.timeout, obs_handler) JSON.parse(res[:analysis]) end end diff --git a/lib/couchbase/management/user_manager.rb b/lib/couchbase/management/user_manager.rb index 6a968804..9547217d 100644 --- a/lib/couchbase/management/user_manager.rb +++ b/lib/couchbase/management/user_manager.rb @@ -258,8 +258,8 @@ def initialize(backend, observability) # @raise [ArgumentError] # @raise [Error::UserNotFound] def get_user(username, options = Options::User::GetUser::DEFAULT) - @observability.record_operation(Observability::OP_UM_GET_USER, options.parent_span, self, :management) do |_obs_handler| - resp = @backend.user_get(options.domain, username, options.timeout) + @observability.record_operation(Observability::OP_UM_GET_USER, options.parent_span, self, :management) do |obs_handler| + resp = @backend.user_get(options.domain, username, options.timeout, obs_handler) extract_user(resp) end end @@ -270,8 +270,8 @@ def get_user(username, options = Options::User::GetUser::DEFAULT) # # @return [Array] def get_all_users(options = Options::User::GetAllUsers::DEFAULT) - @observability.record_operation(Observability::OP_UM_GET_ALL_USERS, options.parent_span, self, :management) do |_obs_handler| - resp = @backend.user_get_all(options.domain, options.timeout) + @observability.record_operation(Observability::OP_UM_GET_ALL_USERS, options.parent_span, self, :management) do |obs_handler| + resp = @backend.user_get_all(options.domain, options.timeout, obs_handler) resp.map { |entry| extract_user(entry) } end end @@ -283,7 +283,7 @@ def get_all_users(options = Options::User::GetAllUsers::DEFAULT) # # @raise [ArgumentError] def upsert_user(user, options = Options::User::UpsertUser::DEFAULT) - @observability.record_operation(Observability::OP_UM_UPSERT_USER, options.parent_span, self, :management) do |_obs_handler| + @observability.record_operation(Observability::OP_UM_UPSERT_USER, options.parent_span, self, :management) do |obs_handler| @backend.user_upsert( options.domain, { @@ -299,7 +299,9 @@ def upsert_user(user, options = Options::User::UpsertUser::DEFAULT) collection: role.collection, } end, - }, options.timeout + }, + options.timeout, + obs_handler, ) end end @@ -309,8 +311,8 @@ def upsert_user(user, options = Options::User::UpsertUser::DEFAULT) # @param [String] username ID of the user # @param [Options::User::DropUser] options def drop_user(username, options = Options::User::DropUser::DEFAULT) - @observability.record_operation(Observability::OP_UM_DROP_USER, options.parent_span, self, :management) do |_obs_handler| - @backend.user_drop(options.domain, username, options.timeout) + @observability.record_operation(Observability::OP_UM_DROP_USER, options.parent_span, self, :management) do |obs_handler| + @backend.user_drop(options.domain, username, options.timeout, obs_handler) end end @@ -320,8 +322,8 @@ def drop_user(username, options = Options::User::DropUser::DEFAULT) # # @return [Array] def get_roles(options = Options::User::GetRoles::DEFAULT) - @observability.record_operation(Observability::OP_UM_GET_ROLES, options.parent_span, self, :management) do |_obs_handler| - resp = @backend.role_get_all(options.timeout) + @observability.record_operation(Observability::OP_UM_GET_ROLES, options.parent_span, self, :management) do |obs_handler| + resp = @backend.role_get_all(options.timeout, obs_handler) resp.map do |r| RoleAndDescription.new do |role| role.name = r[:name] @@ -341,8 +343,8 @@ def get_roles(options = Options::User::GetRoles::DEFAULT) # # @raise [ArgumentError] def change_password(new_password, options = Options::User::ChangePassword::DEFAULT) - @observability.record_operation(Observability::OP_UM_CHANGE_PASSWORD, options.parent_span, self, :management) do |_obs_handler| - @backend.change_password(new_password, options.timeout) + @observability.record_operation(Observability::OP_UM_CHANGE_PASSWORD, options.parent_span, self, :management) do |obs_handler| + @backend.change_password(new_password, options.timeout, obs_handler) end end @@ -356,8 +358,8 @@ def change_password(new_password, options = Options::User::ChangePassword::DEFAU # @raise [ArgumentError] # @raise [Error::GroupNotFound] def get_group(group_name, options = Options::User::GetGroup::DEFAULT) - @observability.record_operation(Observability::OP_UM_GET_GROUP, options.parent_span, self, :management) do |_obs_handler| - resp = @backend.group_get(group_name, options.timeout) + @observability.record_operation(Observability::OP_UM_GET_GROUP, options.parent_span, self, :management) do |obs_handler| + resp = @backend.group_get(group_name, options.timeout, obs_handler) extract_group(resp) end end @@ -368,8 +370,8 @@ def get_group(group_name, options = Options::User::GetGroup::DEFAULT) # # @return [Array] def get_all_groups(options = Options::User::GetAllGroups::DEFAULT) - @observability.record_operation(Observability::OP_UM_GET_ALL_GROUPS, options.parent_span, self, :management) do |_obs_handler| - resp = @backend.group_get_all(options.timeout) + @observability.record_operation(Observability::OP_UM_GET_ALL_GROUPS, options.parent_span, self, :management) do |obs_handler| + resp = @backend.group_get_all(options.timeout, obs_handler) resp.map { |entry| extract_group(entry) } end end @@ -382,7 +384,7 @@ def get_all_groups(options = Options::User::GetAllGroups::DEFAULT) # @raise [ArgumentError] # @raise [Error::GroupNotFound] def upsert_group(group, options = Options::User::UpsertGroup::DEFAULT) - @observability.record_operation(Observability::OP_UM_UPSERT_GROUP, options.parent_span, self, :management) do |_obs_handler| + @observability.record_operation(Observability::OP_UM_UPSERT_GROUP, options.parent_span, self, :management) do |obs_handler| @backend.group_upsert({ name: group.name, description: group.description, @@ -395,7 +397,7 @@ def upsert_group(group, options = Options::User::UpsertGroup::DEFAULT) collection: role.collection, } end, - }, options.timeout) + }, options.timeout, obs_handler) end end @@ -406,8 +408,8 @@ def upsert_group(group, options = Options::User::UpsertGroup::DEFAULT) # # @raise [Error::GroupNotFound] def drop_group(group_name, options = Options::User::DropGroup::DEFAULT) - @observability.record_operation(Observability::OP_UM_DROP_GROUP, options.parent_span, self, :management) do |_obs_handler| - @backend.group_drop(group_name, options.timeout) + @observability.record_operation(Observability::OP_UM_DROP_GROUP, options.parent_span, self, :management) do |obs_handler| + @backend.group_drop(group_name, options.timeout, obs_handler) end end diff --git a/lib/couchbase/management/view_index_manager.rb b/lib/couchbase/management/view_index_manager.rb index 62acabf1..540063fa 100644 --- a/lib/couchbase/management/view_index_manager.rb +++ b/lib/couchbase/management/view_index_manager.rb @@ -167,8 +167,8 @@ def initialize(backend, bucket_name, observability) # # @raise [Error::DesignDocumentNotFound] def get_design_document(name, namespace, options = Options::View::GetDesignDocument::DEFAULT) - @observability.record_operation(Observability::OP_VM_GET_DESIGN_DOCUMENT, options.parent_span, self, :views) do |_obs_handler| - resp = @backend.view_index_get(@bucket_name, name, namespace, options.timeout) + @observability.record_operation(Observability::OP_VM_GET_DESIGN_DOCUMENT, options.parent_span, self, :views) do |obs_handler| + resp = @backend.view_index_get(@bucket_name, name, namespace, options.timeout, obs_handler) extract_design_document(resp) end end @@ -180,8 +180,8 @@ def get_design_document(name, namespace, options = Options::View::GetDesignDocum # # @return [Array] def get_all_design_documents(namespace, options = Options::View::GetAllDesignDocuments::DEFAULT) - @observability.record_operation(Observability::OP_VM_GET_ALL_DESIGN_DOCUMENTS, options.parent_span, self, :views) do |_obs_handler| - resp = @backend.view_index_get_all(@bucket_name, namespace, options.timeout) + @observability.record_operation(Observability::OP_VM_GET_ALL_DESIGN_DOCUMENTS, options.parent_span, self, :views) do |obs_handler| + resp = @backend.view_index_get_all(@bucket_name, namespace, options.timeout, obs_handler) resp.map do |entry| extract_design_document(entry) end @@ -196,7 +196,7 @@ def get_all_design_documents(namespace, options = Options::View::GetAllDesignDoc # # @return [void] def upsert_design_document(document, namespace, options = Options::View::UpsertDesignDocument::DEFAULT) - @observability.record_operation(Observability::OP_VM_UPSERT_DESIGN_DOCUMENT, options.parent_span, self, :views) do |_obs_handler| + @observability.record_operation(Observability::OP_VM_UPSERT_DESIGN_DOCUMENT, options.parent_span, self, :views) do |obs_handler| @backend.view_index_upsert(@bucket_name, { name: document.name, views: document.views.map do |name, view| @@ -206,7 +206,7 @@ def upsert_design_document(document, namespace, options = Options::View::UpsertD reduce: view.reduce_function, } end, - }, namespace, options.timeout) + }, namespace, options.timeout, obs_handler) end end @@ -220,8 +220,8 @@ def upsert_design_document(document, namespace, options = Options::View::UpsertD # # @raise [Error::DesignDocumentNotFound] def drop_design_document(name, namespace, options = Options::View::DropDesignDocument::DEFAULT) - @observability.record_operation(Observability::OP_VM_DROP_DESIGN_DOCUMENT, options.parent_span, self, :views) do |_obs_handler| - @backend.view_index_drop(@bucket_name, name, namespace, options.timeout) + @observability.record_operation(Observability::OP_VM_DROP_DESIGN_DOCUMENT, options.parent_span, self, :views) do |obs_handler| + @backend.view_index_drop(@bucket_name, name, namespace, options.timeout, obs_handler) end end @@ -238,9 +238,11 @@ def drop_design_document(name, namespace, options = Options::View::DropDesignDoc # @raise [ArgumentError] # @raise [Error::DesignDocumentNotFound] def publish_design_document(name, options = Options::View::PublishDesignDocument::DEFAULT) - @observability.record_operation(Observability::OP_VM_PUBLISH_DESIGN_DOCUMENT, options.parent_span, self, :views) do |_obs_handler| - document = get_design_document(name, :development, Options::View::GetDesignDocument.new(timeout: options.timeout)) - upsert_design_document(document, :production, Options::View::UpsertDesignDocument.new(timeout: options.timeout)) + @observability.record_operation(Observability::OP_VM_PUBLISH_DESIGN_DOCUMENT, options.parent_span, self, :views) do |obs_handler| + document = get_design_document(name, :development, + Options::View::GetDesignDocument.new(timeout: options.timeout, parent_span: obs_handler.op_span)) + upsert_design_document(document, :production, + Options::View::UpsertDesignDocument.new(timeout: options.timeout, parent_span: obs_handler.op_span)) end end diff --git a/lib/couchbase/scope.rb b/lib/couchbase/scope.rb index 9e1f952c..8f45a4a2 100644 --- a/lib/couchbase/scope.rb +++ b/lib/couchbase/scope.rb @@ -64,7 +64,7 @@ def query(statement, options = Options::Query::DEFAULT) @observability.record_operation(Observability::OP_QUERY, options.parent_span, self, :query) do |obs_handler| obs_handler.add_query_statement(statement, options) - resp = @backend.document_query(statement, options.to_backend(scope_name: @name, bucket_name: @bucket_name)) + resp = @backend.document_query(statement, options.to_backend(scope_name: @name, bucket_name: @bucket_name), obs_handler) Cluster::QueryResult.new do |res| res.meta_data = Cluster::QueryMetaData.new do |meta| @@ -154,8 +154,8 @@ def analytics_query(statement, options = Options::Analytics::DEFAULT) # # @return [SearchResult] def search_query(index_name, query, options = Options::Search::DEFAULT) - @observability.record_operation(Observability::OP_SEARCH_QUERY, options.parent_span, self, :search) do |_obs_handler| - resp = @backend.document_search(@bucket_name, @name, index_name, JSON.generate(query), {}, options.to_backend) + @observability.record_operation(Observability::OP_SEARCH_QUERY, options.parent_span, self, :search) do |obs_handler| + resp = @backend.document_search(@bucket_name, @name, index_name, JSON.generate(query), {}, options.to_backend, obs_handler) convert_search_result(resp, options) end end @@ -168,10 +168,10 @@ def search_query(index_name, query, options = Options::Search::DEFAULT) # # @return [SearchResult] def search(index_name, search_request, options = Options::Search::DEFAULT) - @observability.record_operation(Observability::OP_SEARCH_QUERY, options.parent_span, self, :search) do |_obs_handler| + @observability.record_operation(Observability::OP_SEARCH_QUERY, options.parent_span, self, :search) do |obs_handler| encoded_query, encoded_req = search_request.to_backend resp = @backend.document_search(@bucket_name, @name, index_name, encoded_query, encoded_req, - options.to_backend(show_request: false)) + options.to_backend(show_request: false), obs_handler) convert_search_result(resp, options) end end diff --git a/lib/couchbase/utils/observability.rb b/lib/couchbase/utils/observability.rb index 103abd4a..ba319720 100644 --- a/lib/couchbase/utils/observability.rb +++ b/lib/couchbase/utils/observability.rb @@ -36,6 +36,7 @@ def initialize def record_operation(op_name, parent_span, receiver, service = nil) handler = Handler.new(op_name, parent_span, receiver, @tracer, @meter) + handler.add_operation_name(op_name) handler.add_service(service) unless service.nil? begin res = yield(handler) @@ -150,7 +151,7 @@ def add_query_statement(statement, options) named_params = options.instance_variable_get(:@named_parameters) # The statement attribute is added only if positional or named parameters are in use. - return if pos_params.nil? || named_params.nil? || pos_params.empty? || named_params.empty? + return if (pos_params.nil? || pos_params.empty?) && (named_params.nil? || named_params.empty?) @op_span.set_attribute(ATTR_QUERY_STATEMENT, statement) end @@ -162,7 +163,7 @@ def add_spans_from_backend(backend_spans) add_backend_span(backend_span, @op_span) end - @op_span.set_attribute(ATTR_RETRIES, retries) if retries.positive? + @op_span.set_attribute(ATTR_RETRIES, retries) unless retries.negative? end def finish diff --git a/test/query_index_manager_test.rb b/test/query_index_manager_test.rb index ca30048b..e15f52c9 100644 --- a/test/query_index_manager_test.rb +++ b/test/query_index_manager_test.rb @@ -67,9 +67,10 @@ def test_get_all_indexes assert_equal 1, get_all_indexes_spans.size assert_http_span( + env, get_all_indexes_spans.first, "manager_query_get_all_indexes", - parent: @parent_span, + @parent_span, service: "query", bucket_name: @bucket_name, ) @@ -79,9 +80,10 @@ def test_get_all_indexes assert_equal 2, create_index_spans.size create_index_spans.each do |span| assert_http_span( + env, span, "manager_query_create_index", - parent: @parent_span, + @parent_span, service: "query", bucket_name: @bucket_name, ) @@ -129,9 +131,10 @@ def test_query_indexes assert_equal 4, get_all_indexes_root_spans.size get_all_indexes_root_spans.each do |span| assert_http_span( + env, span, "manager_query_get_all_indexes", - parent: @parent_span, + @parent_span, service: "query", bucket_name: @bucket_name, ) @@ -141,9 +144,10 @@ def test_query_indexes assert_equal 1, create_primary_index_spans.size assert_http_span( + env, create_primary_index_spans.first, "manager_query_create_primary_index", - parent: @parent_span, + @parent_span, service: "query", bucket_name: @bucket_name, ) @@ -153,9 +157,10 @@ def test_query_indexes assert_equal 2, create_index_spans.size create_index_spans.each do |span| assert_http_span( + env, span, "manager_query_create_index", - parent: @parent_span, + @parent_span, service: "query", bucket_name: @bucket_name, ) @@ -165,9 +170,10 @@ def test_query_indexes assert_equal 1, build_deferred_indexes_spans.size assert_http_span( + env, build_deferred_indexes_spans.first, "manager_query_build_deferred_indexes", - parent: @parent_span, + @parent_span, service: "query", bucket_name: @bucket_name, ) @@ -177,9 +183,10 @@ def test_query_indexes assert_equal 2, watch_indexes_spans.size watch_indexes_spans.each do |span| assert_http_span( + env, span, "manager_query_watch_indexes", - parent: @parent_span, + @parent_span, service: "query", bucket_name: @bucket_name, ) @@ -187,9 +194,10 @@ def test_query_indexes assert_predicate span.children.size, :positive? span.children.each do |child_span| assert_http_span( + env, child_span, "manager_query_get_all_indexes", - parent: span, + span, service: "query", bucket_name: @bucket_name, ) diff --git a/test/tracing_test.rb b/test/tracing_test.rb index a574a498..f3164a84 100644 --- a/test/tracing_test.rb +++ b/test/tracing_test.rb @@ -25,7 +25,10 @@ def setup @tracer = TestTracer.new connect(Options::Cluster.new(tracer: @tracer)) @bucket = @cluster.bucket(env.bucket) + @scope = @bucket.default_scope @collection = @bucket.default_collection + + @parent_span = @tracer.request_span("parent_span") end def teardown @@ -33,50 +36,46 @@ def teardown end def test_get - parent = @tracer.request_span("parent_span") doc_id = uniq_id(:foo) assert_raises(Couchbase::Error::DocumentNotFound) do - @collection.get(doc_id, Options::Get.new(parent_span: parent)) + @collection.get(doc_id, Options::Get.new(parent_span: @parent_span)) end spans = @tracer.spans("get") assert_equal 1, spans.size - assert_kv_span spans[0], "get", parent + assert_kv_span env, spans[0], "get", @collection, @parent_span end def test_upsert - parent = @tracer.request_span("parent_span") doc_id = uniq_id(:foo) - @collection.upsert(doc_id, {foo: "bar"}, Options::Upsert.new(parent_span: parent)) + @collection.upsert(doc_id, {foo: "bar"}, Options::Upsert.new(parent_span: @parent_span)) spans = @tracer.spans("upsert") assert_equal 1, spans.size - assert_kv_span spans[0], "upsert", parent - assert_has_request_encoding_span spans[0] + assert_kv_span env, spans[0], "upsert", @collection, @parent_span + assert_has_request_encoding_span env, spans[0] end def test_replace - parent = @tracer.request_span("parent_span") doc_id = uniq_id(:foo) assert_raises(Couchbase::Error::DocumentNotFound) do - @collection.replace(doc_id, {foo: "bar"}, Options::Upsert.new(parent_span: parent)) + @collection.replace(doc_id, {foo: "bar"}, Options::Upsert.new(parent_span: @parent_span)) end spans = @tracer.spans("replace") assert_equal 1, spans.size - assert_kv_span spans[0], "replace", parent - assert_has_request_encoding_span spans[0] + assert_kv_span env, spans[0], "replace", @collection, @parent_span + assert_has_request_encoding_span env, spans[0] end def test_replace_durable - parent = @tracer.request_span("parent_span") doc_id = uniq_id(:foo) assert_raises(Couchbase::Error::DocumentNotFound) do @collection.replace(doc_id, {foo: "bar"}, Options::Upsert.new( - parent_span: parent, + parent_span: @parent_span, durability_level: :persist_to_majority, )) end @@ -84,9 +83,474 @@ def test_replace_durable spans = @tracer.spans("replace") assert_equal 1, spans.size - assert_kv_span spans[0], "replace", parent - assert_has_request_encoding_span spans[0] + assert_kv_span env, spans[0], "replace", @collection, @parent_span + assert_has_request_encoding_span env, spans[0] assert_equal "persist_majority", spans[0].attributes["couchbase.durability"] end + + def test_append + doc_id = uniq_id(:foo) + @collection.upsert(doc_id, "foo", Options::Upsert.new( + transcoder: RawBinaryTranscoder.new, + )) + @collection.binary.append(doc_id, "bar", Options::Append.new( + parent_span: @parent_span, + )) + + spans = @tracer.spans("append") + + assert_equal 1, spans.size + assert_kv_span env, spans[0], "append", @collection, @parent_span + end + + def test_increment + doc_id = uniq_id(:foo) + res = @collection.binary.increment(doc_id, Options::Increment.new( + delta: 10, + initial: 0, + parent_span: @parent_span, + )) + + assert_equal 0, res.content + + res = @collection.binary.increment(doc_id, Options::Increment.new( + delta: 10, + parent_span: @parent_span, + )) + + assert_equal 10, res.content + + spans = @tracer.spans("increment") + + assert_equal 2, spans.size + spans.each do |span| + assert_kv_span env, span, "increment", @collection, @parent_span + end + end + + def test_get_all_replicas + num_replicas = @cluster.buckets.get_bucket(env.bucket).num_replicas + + doc_id = uniq_id(:foo) + @collection.upsert(doc_id, {"foo" => "bar"}, Options::Upsert.new( + durability_level: :majority, + )) + + res = @collection.get_all_replicas(doc_id, Options::GetAllReplicas.new( + parent_span: @parent_span, + )) + + res.each do |r| + assert_equal({"foo" => "bar"}, r.content) + end + + spans = @tracer.spans("get_all_replicas") + + assert_equal 1, spans.size + assert_compound_kv_span( + env, spans[0], "get_all_replicas", @collection, @parent_span, + child_op_names: Array.new(1, "get") + Array.new(num_replicas, "get_replica"), + enforce_child_ordering: false + ) + end + + def test_analytics_query + skip("#{name}: CAVES does not support analytics service yet") if use_caves? + + res = @cluster.analytics_query( + "SELECT 1=1 AS result", + Options::Analytics.new( + parent_span: @parent_span, + ), + ) + + assert_equal({"result" => true}, res.rows.first) + + spans = @tracer.spans("analytics") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "analytics", @parent_span, + service: "analytics", + statement: nil # No db.query.text attribute if no parameters are used + ) + end + + def test_analytics_query_with_parameters + skip("#{name}: CAVES does not support analytics service yet") if use_caves? + + res = @cluster.analytics_query( + "SELECT $value AS result", + Options::Analytics.new( + named_parameters: {value: 10}, + parent_span: @parent_span, + ), + ) + + assert_equal({"result" => 10}, res.rows.first) + + spans = @tracer.spans("analytics") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "analytics", @parent_span, + service: "analytics", + statement: "SELECT $value AS result" + ) + end + + def test_analytics_manager_get_all_datasets + skip("#{name}: CAVES does not support analytics service yet") if use_caves? + + res = @cluster.analytics_indexes.get_all_datasets( + Management::Options::Analytics::GetAllDatasets.new( + parent_span: @parent_span, + ), + ) + + assert_kind_of Array, res + + spans = @tracer.spans("manager_analytics_get_all_datasets") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "manager_analytics_get_all_datasets", @parent_span, + service: "analytics" + ) + end + + def test_get_all_buckets + res = @cluster.buckets.get_all_buckets( + Management::Options::Bucket::GetAllBuckets.new( + parent_span: @parent_span, + ), + ) + + assert(res.any? { |b| b.name == env.bucket }) + + spans = @tracer.spans("manager_buckets_get_all_buckets") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "manager_buckets_get_all_buckets", @parent_span, + service: "management" + ) + end + + def test_get_all_scopes + res = @bucket.collections.get_all_scopes( + Management::Options::Collection::GetAllScopes.new( + parent_span: @parent_span, + ), + ) + + assert(res.any? { |b| b.name == @scope.name }) + + spans = @tracer.spans("manager_collections_get_all_scopes") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "manager_collections_get_all_scopes", @parent_span, + bucket_name: @bucket.name, + service: "management" + ) + end + + def test_get_scope + res = @bucket.collections.get_scope( + @scope.name, + Management::Options::Collection::GetAllScopes.new( + parent_span: @parent_span, + ), + ) + + assert_equal @scope.name, res.name + + spans = @tracer.spans("manager_collections_get_scope") + + assert_equal 1, spans.size + assert_compound_http_span( + env, spans.first, "manager_collections_get_scope", @parent_span, + bucket_name: @bucket.name, + scope_name: @scope.name, + service: "management", + child_count: 1 + ) do |child_span| + assert_http_span( + env, child_span, "manager_collections_get_all_scopes", spans.first, + bucket_name: @bucket.name, + service: "management" + ) + end + end + + def test_drop_collection + collection_name = uniq_id(:non_existent_collection) + assert_raises Couchbase::Error::CollectionNotFound do + @bucket.collections.drop_collection( + @scope.name, + collection_name, + Management::Options::Collection::DropCollection.new( + parent_span: @parent_span, + ), + ) + end + + spans = @tracer.spans("manager_collections_drop_collection") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "manager_collections_drop_collection", @parent_span, + bucket_name: @bucket.name, + scope_name: @scope.name, + collection_name: collection_name, + service: "management" + ) + end + + def test_query_indexes_get_all + skip("#{name}: CAVES does not support query service") if use_caves? + + res = @cluster.query_indexes.get_all_indexes( + env.bucket, + Management::Options::Query::GetAllIndexes.new( + parent_span: @parent_span, + ), + ) + + assert_kind_of Array, res + + spans = @tracer.spans("manager_query_get_all_indexes") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "manager_query_get_all_indexes", @parent_span, + service: "query", + bucket_name: env.bucket + ) + end + + def test_collection_query_indexes_get_all + skip("#{name}: CAVES does not support query service") if use_caves? + + res = @collection.query_indexes.get_all_indexes( + Management::Options::Query::GetAllIndexes.new( + parent_span: @parent_span, + ), + ) + + assert_kind_of Array, res + + spans = @tracer.spans("manager_query_get_all_indexes") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "manager_query_get_all_indexes", @parent_span, + service: "query", + bucket_name: @collection.bucket_name, + scope_name: @collection.scope_name, + collection_name: @collection.name + ) + end + + def test_cluster_level_query + skip("#{name}: CAVES does not support query service") if use_caves? + + res = @cluster.query( + "SELECT 1=1 AS result", + Options::Query.new( + parent_span: @parent_span, + ), + ) + + assert_equal({"result" => true}, res.rows.first) + + spans = @tracer.spans("query") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "query", @parent_span, + service: "query", + statement: nil # No db.query.text attribute if no parameters are used + ) + end + + def test_cluster_level_query_with_parameters + skip("#{name}: CAVES does not support query service") if use_caves? + + res = @cluster.query( + "SELECT $1 AS result", + Options::Query.new( + parent_span: @parent_span, + positional_parameters: [10], + ), + ) + + assert_equal({"result" => 10}, res.rows.first) + + spans = @tracer.spans("query") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "query", @parent_span, + service: "query", + statement: "SELECT $1 AS result" + ) + end + + def test_scope_level_query + skip("#{name}: CAVES does not support query service") if use_caves? + + res = @scope.query( + "SELECT 1=1 AS result", + Options::Query.new( + parent_span: @parent_span, + ), + ) + + assert_equal({"result" => true}, res.rows.first) + + spans = @tracer.spans("query") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "query", @parent_span, + service: "query", + statement: nil, # No db.query.text attribute if no parameters are used + bucket_name: @scope.bucket_name, + scope_name: @scope.name + ) + end + + def test_scope_level_query_with_parameters + skip("#{name}: CAVES does not support query service") if use_caves? + + res = @scope.query( + "SELECT $1 AS result", + Options::Query.new( + parent_span: @parent_span, + positional_parameters: [10], + ), + ) + + assert_equal({"result" => 10}, res.rows.first) + + spans = @tracer.spans("query") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "query", @parent_span, + service: "query", + statement: "SELECT $1 AS result", + bucket_name: @scope.bucket_name, + scope_name: @scope.name + ) + end + + def test_get_all_users + res = @cluster.users.get_all_users( + Management::Options::User::GetAllUsers.new( + parent_span: @parent_span, + ), + ) + + assert_kind_of Array, res + + spans = @tracer.spans("manager_users_get_all_users") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "manager_users_get_all_users", @parent_span, + service: "management" + ) + end + + def test_cluster_level_search_get_all_indexes + skip("#{name}: CAVES does not support FTS") if use_caves? + + res = @cluster.search_indexes.get_all_indexes( + Management::Options::Search::GetAllIndexes.new( + parent_span: @parent_span, + ), + ) + + assert_kind_of Array, res + + spans = @tracer.spans("manager_search_get_all_indexes") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "manager_search_get_all_indexes", @parent_span, + service: "search" + ) + end + + def test_scope_level_search_get_all_indexes + skip("#{name}: CAVES does not support FTS") if use_caves? + + res = @scope.search_indexes.get_all_indexes( + Management::Options::Search::GetAllIndexes.new( + parent_span: @parent_span, + ), + ) + + assert_kind_of Array, res + + spans = @tracer.spans("manager_search_get_all_indexes") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "manager_search_get_all_indexes", @parent_span, + bucket_name: @scope.bucket_name, + scope_name: @scope.name, + service: "search" + ) + end + + def test_cluster_level_search_query + skip("#{name}: CAVES does not support FTS") if use_caves? + + assert_raises Couchbase::Error::IndexNotFound do + @cluster.search( + uniq_id(:non_existent_index), + Couchbase::SearchRequest.new(Couchbase::SearchQuery.match_none), + Options::Search.new( + parent_span: @parent_span, + ), + ) + end + + spans = @tracer.spans("search") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "search", @parent_span, + service: "search" + ) + end + + def test_scope_level_search_query + skip("#{name}: CAVES does not support FTS") if use_caves? + + assert_raises Couchbase::Error::IndexNotFound do + @scope.search( + uniq_id(:non_existent_index), + Couchbase::SearchRequest.new(Couchbase::SearchQuery.match_none), + Options::Search.new( + parent_span: @parent_span, + ), + ) + end + + spans = @tracer.spans("search") + + assert_equal 1, spans.size + assert_http_span( + env, spans.first, "search", @parent_span, + bucket_name: @scope.bucket_name, + scope_name: @scope.name, + service: "search" + ) + end end end diff --git a/test/utils/tracing.rb b/test/utils/tracing.rb index 0796390d..7514bc05 100644 --- a/test/utils/tracing.rb +++ b/test/utils/tracing.rb @@ -17,8 +17,8 @@ require_relative "tracing/test_span" require_relative "tracing/test_tracer" -def assert_span(span, name, parent = nil) - puts JSON.pretty_generate(@tracer.spans[0].to_h) +def assert_span(_env, span, name, parent = nil) + # puts JSON.pretty_generate(@tracer.spans[0].to_h) assert_equal name, span.name assert_equal span.parent, parent @@ -28,34 +28,140 @@ def assert_span(span, name, parent = nil) assert_equal "couchbase", span.attributes["db.system.name"] end -def assert_kv_span(span, op_name, parent = nil) - assert_span span, op_name, parent +def assert_kv_dispatch_span(env, span, parent) + assert_dispatch_span(env, span, parent) + assert span.attributes.key?("couchbase.local_id") + assert span.attributes.key?("couchbase.operation_id") +end + +def assert_dispatch_span(env, span, parent) + assert_span env, span, "dispatch_to_server", parent + + assert_equal "tcp", span.attributes["network.transport"] + assert span.attributes.key?("server.address") + assert span.attributes.key?("server.port") + assert span.attributes.key?("network.peer.address") + assert span.attributes.key?("network.peer.port") +end + +def assert_compound_kv_span( + env, span, op_name, collection, parent, + child_op_names:, enforce_child_ordering: +) + assert_span env, span, op_name, parent + + assert_equal "kv", span.attributes["couchbase.service"] + assert_equal collection.bucket_name, span.attributes["db.namespace"] + assert_equal collection.scope_name, span.attributes["couchbase.scope.name"] + assert_equal collection.name, span.attributes["couchbase.collection.name"] + + refute_empty span.children + + if enforce_child_ordering + span.children.each_with_index do |child_span, index| + assert_kv_span env, child_span, child_op_names[index], collection, span + end + else + span.children.each do |child_span| + refute_empty child_op_names, "Unexpected extra child span: #{child_span.name}" + + name = child_op_names.delete(child_span.name) + + refute_nil name, "Unexpected child span: #{name}" + assert_kv_span env, child_span, name, collection, span + end + end +end + +def assert_kv_span(env, span, op_name, collection, parent) + assert_span env, span, op_name, parent + + assert_equal op_name, span.attributes["db.operation.name"] assert_equal "kv", span.attributes["couchbase.service"] - assert_equal @collection.bucket_name, span.attributes["db.namespace"] - assert_equal @collection.scope_name, span.attributes["couchbase.scope.name"] - assert_equal @collection.name, span.attributes["couchbase.collection.name"] + assert_equal collection.bucket_name, span.attributes["db.namespace"] + assert_equal collection.scope_name, span.attributes["couchbase.scope.name"] + assert_equal collection.name, span.attributes["couchbase.collection.name"] + assert span.attributes.key?("couchbase.retries") + + refute_empty span.children + + dispatch_spans = span.children.select { |child| child.name == "dispatch_to_server" } + + refute_empty dispatch_spans + dispatch_spans.each do |ds| + assert_dispatch_span(env, ds, span) + end end -def assert_has_request_encoding_span(span) - assert_predicate span.children.size, :positive? +def assert_has_request_encoding_span(env, span) + refute_empty span.children request_encoding_span = span.children[0] # The request encoding span is always the first child span - assert_span request_encoding_span, "request_encoding", span + assert_span env, request_encoding_span, "request_encoding", span +end + +def assert_compound_http_span( + env, + span, + op_name, + parent, + child_count: nil, + service: nil, + bucket_name: nil, + scope_name: nil, + collection_name: nil, + statement: nil, + &block +) + assert_span env, span, op_name, parent + + if service.nil? + assert_nil span.attributes["couchbase.service"] + else + assert_equal service, span.attributes["couchbase.service"] + end + if bucket_name.nil? + assert_nil span.attributes["couchbase.bucket"] + else + assert_equal bucket_name, span.attributes["db.namespace"] + end + if scope_name.nil? + assert_nil span.attributes["couchbase.scope.name"] + else + assert_equal scope_name, span.attributes["couchbase.scope.name"] + end + if collection_name.nil? + assert_nil span.attributes["couchbase.collection.name"] + else + assert_equal collection_name, span.attributes["couchbase.collection.name"] + end + if statement.nil? + assert_nil span.attributes["db.query.text"] + else + assert_equal statement, span.attributes["db.query.text"] + end + + refute_empty span.children, "Expected at least one child span for compound HTTP operation" + + assert_equal child_count, span.children.size unless child_count.nil? + + span.children.each(&block) end def assert_http_span( + env, span, op_name, - parent: nil, + parent, service: nil, bucket_name: nil, scope_name: nil, collection_name: nil, statement: nil ) - assert_span span, op_name, parent + assert_span env, span, op_name, parent if service.nil? assert_nil span.attributes["couchbase.service"] @@ -82,4 +188,13 @@ def assert_http_span( else assert_equal statement, span.attributes["db.query.text"] end + + refute_empty span.children, "Expected at least one child span for HTTP operation" + + dispatch_spans = span.children.select { |child| child.name == "dispatch_to_server" } + + refute_empty dispatch_spans, "Expected at least one dispatch_to_server child span for HTTP operation" + dispatch_spans.each do |ds| + assert_dispatch_span(env, ds, span) + end end