couchbase 3.7.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/ext/CMakeLists.txt +4 -1
  4. data/ext/cache/extconf_include.rb +4 -3
  5. data/ext/cache/mozilla-ca-bundle.crt +66 -93
  6. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  7. data/ext/couchbase/CMakeLists.txt +24 -11
  8. data/ext/couchbase/cmake/APKBUILD.in +17 -1
  9. data/ext/couchbase/cmake/Bundler.cmake +9 -1
  10. data/ext/couchbase/cmake/Cache.cmake +48 -19
  11. data/ext/couchbase/cmake/CompilerOptions.cmake +3 -1
  12. data/ext/couchbase/cmake/OpenSSL.cmake +10 -2
  13. data/ext/couchbase/cmake/Packaging.cmake +48 -8
  14. data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +43 -1
  15. data/ext/couchbase/cmake/build_config.hxx.in +2 -0
  16. data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +18 -0
  17. data/ext/couchbase/cmake/tarball_glob.txt +10 -0
  18. data/ext/couchbase/core/app_telemetry_meter.cxx +1 -0
  19. data/ext/couchbase/core/app_telemetry_reporter.cxx +45 -43
  20. data/ext/couchbase/core/app_telemetry_reporter.hxx +4 -3
  21. data/ext/couchbase/core/bucket.cxx +128 -13
  22. data/ext/couchbase/core/bucket.hxx +12 -2
  23. data/ext/couchbase/core/cluster.cxx +304 -152
  24. data/ext/couchbase/core/cluster.hxx +32 -0
  25. data/ext/couchbase/core/cluster_credentials.cxx +25 -0
  26. data/ext/couchbase/core/cluster_credentials.hxx +5 -0
  27. data/ext/couchbase/core/cluster_label_listener.cxx +72 -0
  28. data/ext/couchbase/core/cluster_label_listener.hxx +46 -0
  29. data/ext/couchbase/core/cluster_options.hxx +4 -0
  30. data/ext/couchbase/core/deprecation_utils.hxx +26 -0
  31. data/ext/couchbase/core/error.hxx +27 -0
  32. data/ext/couchbase/core/free_form_http_request.hxx +0 -2
  33. data/ext/couchbase/core/http_component.cxx +12 -48
  34. data/ext/couchbase/core/impl/analytics.cxx +3 -2
  35. data/ext/couchbase/core/impl/analytics.hxx +2 -1
  36. data/ext/couchbase/core/impl/analytics_index_manager.cxx +249 -137
  37. data/ext/couchbase/core/impl/binary_collection.cxx +134 -58
  38. data/ext/couchbase/core/impl/bucket_manager.cxx +87 -35
  39. data/ext/couchbase/core/impl/collection.cxx +560 -245
  40. data/ext/couchbase/core/impl/collection_manager.cxx +89 -49
  41. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +4 -4
  42. data/ext/couchbase/core/impl/error.cxx +20 -13
  43. data/ext/couchbase/core/impl/error.hxx +15 -10
  44. data/ext/couchbase/core/impl/get_all_replicas.hxx +1 -1
  45. data/ext/couchbase/core/impl/get_any_replica.hxx +2 -1
  46. data/ext/couchbase/core/impl/get_replica.hxx +2 -0
  47. data/ext/couchbase/core/impl/lookup_in_replica.hxx +1 -1
  48. data/ext/couchbase/core/impl/observability_recorder.cxx +161 -0
  49. data/ext/couchbase/core/impl/observability_recorder.hxx +77 -0
  50. data/ext/couchbase/core/impl/observe_seqno.hxx +2 -0
  51. data/ext/couchbase/core/impl/public_bucket.cxx +31 -7
  52. data/ext/couchbase/core/impl/public_cluster.cxx +107 -19
  53. data/ext/couchbase/core/impl/query.cxx +6 -3
  54. data/ext/couchbase/core/impl/query.hxx +3 -1
  55. data/ext/couchbase/core/impl/query_index_manager.cxx +267 -102
  56. data/ext/couchbase/core/impl/scope.cxx +53 -11
  57. data/ext/couchbase/core/impl/search.cxx +8 -4
  58. data/ext/couchbase/core/impl/search.hxx +6 -2
  59. data/ext/couchbase/core/impl/search_index_manager.cxx +131 -41
  60. data/ext/couchbase/core/impl/with_cancellation.hxx +75 -0
  61. data/ext/couchbase/core/io/config_tracker.cxx +9 -9
  62. data/ext/couchbase/core/io/config_tracker.hxx +2 -1
  63. data/ext/couchbase/core/io/http_command.hxx +98 -49
  64. data/ext/couchbase/core/io/http_context.hxx +2 -0
  65. data/ext/couchbase/core/io/http_session.cxx +23 -10
  66. data/ext/couchbase/core/io/http_session.hxx +17 -9
  67. data/ext/couchbase/core/io/http_session_manager.hxx +163 -228
  68. data/ext/couchbase/core/io/http_traits.hxx +0 -7
  69. data/ext/couchbase/core/io/mcbp_command.hxx +123 -44
  70. data/ext/couchbase/core/io/mcbp_session.cxx +251 -26
  71. data/ext/couchbase/core/io/mcbp_session.hxx +9 -1
  72. data/ext/couchbase/core/io/mcbp_traits.hxx +0 -8
  73. data/ext/couchbase/core/io/streams.cxx +3 -3
  74. data/ext/couchbase/core/io/streams.hxx +3 -2
  75. data/ext/couchbase/core/meta/features.hxx +15 -0
  76. data/ext/couchbase/core/meta/version.cxx +13 -0
  77. data/ext/couchbase/core/meta/version.hxx +3 -0
  78. data/ext/couchbase/core/metrics/constants.hxx +23 -0
  79. data/ext/couchbase/core/metrics/logging_meter.cxx +5 -5
  80. data/ext/couchbase/core/metrics/meter_wrapper.cxx +65 -63
  81. data/ext/couchbase/core/metrics/meter_wrapper.hxx +12 -10
  82. data/ext/couchbase/core/operations/document_analytics.hxx +0 -5
  83. data/ext/couchbase/core/operations/document_append.hxx +0 -4
  84. data/ext/couchbase/core/operations/document_decrement.hxx +0 -5
  85. data/ext/couchbase/core/operations/document_exists.hxx +0 -7
  86. data/ext/couchbase/core/operations/document_get.hxx +0 -7
  87. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +77 -27
  88. data/ext/couchbase/core/operations/document_get_and_lock.hxx +0 -9
  89. data/ext/couchbase/core/operations/document_get_and_touch.hxx +0 -9
  90. data/ext/couchbase/core/operations/document_get_any_replica.hxx +83 -2
  91. data/ext/couchbase/core/operations/document_get_projected.hxx +0 -9
  92. data/ext/couchbase/core/operations/document_increment.hxx +0 -5
  93. data/ext/couchbase/core/operations/document_insert.hxx +0 -4
  94. data/ext/couchbase/core/operations/document_lookup_in.hxx +0 -9
  95. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +46 -4
  96. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +121 -43
  97. data/ext/couchbase/core/operations/document_mutate_in.hxx +0 -5
  98. data/ext/couchbase/core/operations/document_prepend.hxx +0 -4
  99. data/ext/couchbase/core/operations/document_query.hxx +0 -4
  100. data/ext/couchbase/core/operations/document_remove.hxx +0 -4
  101. data/ext/couchbase/core/operations/document_replace.hxx +0 -4
  102. data/ext/couchbase/core/operations/document_search.hxx +0 -7
  103. data/ext/couchbase/core/operations/document_touch.hxx +0 -7
  104. data/ext/couchbase/core/operations/document_unlock.hxx +0 -6
  105. data/ext/couchbase/core/operations/document_upsert.hxx +0 -4
  106. data/ext/couchbase/core/operations/document_view.cxx +2 -0
  107. data/ext/couchbase/core/operations/document_view.hxx +10 -13
  108. data/ext/couchbase/core/operations/http_noop.hxx +2 -0
  109. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +2 -0
  110. data/ext/couchbase/core/operations/management/analytics_dataset_drop.hxx +2 -0
  111. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.hxx +2 -0
  112. data/ext/couchbase/core/operations/management/analytics_dataverse_create.hxx +2 -0
  113. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.hxx +2 -0
  114. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.hxx +2 -0
  115. data/ext/couchbase/core/operations/management/analytics_index_create.hxx +2 -0
  116. data/ext/couchbase/core/operations/management/analytics_index_drop.hxx +2 -0
  117. data/ext/couchbase/core/operations/management/analytics_index_get_all.hxx +2 -0
  118. data/ext/couchbase/core/operations/management/analytics_link_connect.hxx +2 -0
  119. data/ext/couchbase/core/operations/management/analytics_link_create.hxx +2 -0
  120. data/ext/couchbase/core/operations/management/analytics_link_disconnect.hxx +2 -0
  121. data/ext/couchbase/core/operations/management/analytics_link_drop.hxx +2 -0
  122. data/ext/couchbase/core/operations/management/analytics_link_get_all.hxx +2 -0
  123. data/ext/couchbase/core/operations/management/analytics_link_replace.hxx +2 -0
  124. data/ext/couchbase/core/operations/management/bucket_create.hxx +2 -0
  125. data/ext/couchbase/core/operations/management/bucket_describe.hxx +2 -0
  126. data/ext/couchbase/core/operations/management/bucket_drop.hxx +2 -0
  127. data/ext/couchbase/core/operations/management/bucket_flush.hxx +2 -0
  128. data/ext/couchbase/core/operations/management/bucket_get.hxx +2 -0
  129. data/ext/couchbase/core/operations/management/bucket_get_all.hxx +2 -0
  130. data/ext/couchbase/core/operations/management/bucket_update.hxx +2 -0
  131. data/ext/couchbase/core/operations/management/change_password.hxx +2 -0
  132. data/ext/couchbase/core/operations/management/cluster_describe.hxx +2 -0
  133. data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.hxx +2 -0
  134. data/ext/couchbase/core/operations/management/collection_create.hxx +2 -0
  135. data/ext/couchbase/core/operations/management/collection_drop.hxx +2 -0
  136. data/ext/couchbase/core/operations/management/collection_update.hxx +2 -0
  137. data/ext/couchbase/core/operations/management/collections_manifest_get.hxx +2 -0
  138. data/ext/couchbase/core/operations/management/error_utils.cxx +4 -1
  139. data/ext/couchbase/core/operations/management/eventing_deploy_function.hxx +2 -0
  140. data/ext/couchbase/core/operations/management/eventing_drop_function.hxx +2 -0
  141. data/ext/couchbase/core/operations/management/eventing_get_all_functions.hxx +2 -0
  142. data/ext/couchbase/core/operations/management/eventing_get_function.hxx +2 -0
  143. data/ext/couchbase/core/operations/management/eventing_get_status.hxx +2 -0
  144. data/ext/couchbase/core/operations/management/eventing_pause_function.hxx +2 -0
  145. data/ext/couchbase/core/operations/management/eventing_resume_function.hxx +2 -0
  146. data/ext/couchbase/core/operations/management/eventing_undeploy_function.hxx +2 -0
  147. data/ext/couchbase/core/operations/management/eventing_upsert_function.hxx +2 -0
  148. data/ext/couchbase/core/operations/management/freeform.hxx +2 -0
  149. data/ext/couchbase/core/operations/management/group_drop.hxx +2 -0
  150. data/ext/couchbase/core/operations/management/group_get.hxx +2 -0
  151. data/ext/couchbase/core/operations/management/group_get_all.hxx +2 -0
  152. data/ext/couchbase/core/operations/management/group_upsert.hxx +2 -0
  153. data/ext/couchbase/core/operations/management/query_index_build.hxx +2 -0
  154. data/ext/couchbase/core/operations/management/query_index_build_deferred.hxx +68 -30
  155. data/ext/couchbase/core/operations/management/query_index_create.hxx +2 -0
  156. data/ext/couchbase/core/operations/management/query_index_drop.hxx +2 -0
  157. data/ext/couchbase/core/operations/management/query_index_get_all.hxx +4 -3
  158. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.hxx +2 -1
  159. data/ext/couchbase/core/operations/management/role_get_all.hxx +2 -0
  160. data/ext/couchbase/core/operations/management/scope_create.hxx +2 -0
  161. data/ext/couchbase/core/operations/management/scope_drop.hxx +2 -0
  162. data/ext/couchbase/core/operations/management/scope_get_all.hxx +2 -0
  163. data/ext/couchbase/core/operations/management/search_get_stats.hxx +2 -0
  164. data/ext/couchbase/core/operations/management/search_index_analyze_document.hxx +2 -0
  165. data/ext/couchbase/core/operations/management/search_index_control_ingest.hxx +2 -0
  166. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.hxx +2 -0
  167. data/ext/couchbase/core/operations/management/search_index_control_query.hxx +2 -0
  168. data/ext/couchbase/core/operations/management/search_index_drop.hxx +2 -0
  169. data/ext/couchbase/core/operations/management/search_index_get.hxx +2 -0
  170. data/ext/couchbase/core/operations/management/search_index_get_all.hxx +2 -0
  171. data/ext/couchbase/core/operations/management/search_index_get_documents_count.hxx +2 -0
  172. data/ext/couchbase/core/operations/management/search_index_get_stats.hxx +2 -0
  173. data/ext/couchbase/core/operations/management/search_index_upsert.hxx +2 -0
  174. data/ext/couchbase/core/operations/management/user_drop.hxx +2 -0
  175. data/ext/couchbase/core/operations/management/user_get.hxx +2 -0
  176. data/ext/couchbase/core/operations/management/user_get_all.hxx +2 -0
  177. data/ext/couchbase/core/operations/management/user_upsert.hxx +2 -0
  178. data/ext/couchbase/core/operations/management/view_index_drop.hxx +2 -0
  179. data/ext/couchbase/core/operations/management/view_index_get.hxx +2 -0
  180. data/ext/couchbase/core/operations/management/view_index_get_all.hxx +2 -0
  181. data/ext/couchbase/core/operations/management/view_index_upsert.hxx +2 -0
  182. data/ext/couchbase/core/operations/operation_traits.hxx +6 -0
  183. data/ext/couchbase/core/operations.hxx +0 -1
  184. data/ext/couchbase/core/operations_fwd.hxx +8 -0
  185. data/ext/couchbase/core/origin.cxx +67 -12
  186. data/ext/couchbase/core/origin.hxx +13 -8
  187. data/ext/couchbase/core/orphan_reporter.cxx +164 -0
  188. data/ext/couchbase/core/orphan_reporter.hxx +65 -0
  189. data/ext/couchbase/core/sasl/CMakeLists.txt +1 -0
  190. data/ext/couchbase/core/sasl/client.cc +6 -0
  191. data/ext/couchbase/core/sasl/mechanism.cc +2 -1
  192. data/ext/couchbase/core/sasl/mechanism.h +2 -1
  193. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.cc +41 -0
  194. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.h +47 -0
  195. data/ext/couchbase/core/tls_context_provider.cxx +44 -0
  196. data/ext/couchbase/core/tls_context_provider.hxx +44 -0
  197. data/ext/couchbase/core/tracing/attribute_helpers.hxx +45 -0
  198. data/ext/couchbase/core/tracing/constants.hxx +148 -68
  199. data/ext/couchbase/core/tracing/threshold_logging_options.hxx +0 -3
  200. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +122 -170
  201. data/ext/couchbase/core/tracing/tracer_wrapper.cxx +17 -24
  202. data/ext/couchbase/core/tracing/tracer_wrapper.hxx +8 -10
  203. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.cxx +114 -0
  204. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.hxx +85 -0
  205. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +16 -14
  206. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +4 -4
  207. data/ext/couchbase/core/transactions/transactions.cxx +1 -1
  208. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +1 -2
  209. data/ext/couchbase/core/utils/byteswap.hxx +12 -0
  210. data/ext/couchbase/core/utils/concurrent_fixed_priority_queue.hxx +102 -0
  211. data/ext/couchbase/core/utils/connection_string.cxx +2 -0
  212. data/ext/couchbase/couchbase/certificate_authenticator.hxx +1 -0
  213. data/ext/couchbase/couchbase/cluster.hxx +47 -0
  214. data/ext/couchbase/couchbase/cluster_options.hxx +16 -0
  215. data/ext/couchbase/couchbase/collection.hxx +60 -15
  216. data/ext/couchbase/couchbase/error_codes.hxx +48 -48
  217. data/ext/couchbase/couchbase/jwt_authenticator.hxx +52 -0
  218. data/ext/couchbase/couchbase/metrics/meter.hxx +2 -1
  219. data/ext/couchbase/couchbase/metrics/otel_meter.hxx +75 -80
  220. data/ext/couchbase/couchbase/network_options.hxx +19 -0
  221. data/ext/couchbase/couchbase/password_authenticator.hxx +1 -0
  222. data/ext/couchbase/couchbase/tracing/otel_tracer.hxx +15 -17
  223. data/ext/couchbase/couchbase/tracing/request_span.hxx +2 -2
  224. data/ext/couchbase.cxx +4 -0
  225. data/ext/extconf.rb +1 -0
  226. data/ext/rcb_analytics.cxx +157 -47
  227. data/ext/rcb_backend.cxx +118 -71
  228. data/ext/rcb_buckets.cxx +39 -16
  229. data/ext/rcb_collections.cxx +36 -12
  230. data/ext/rcb_crud.cxx +587 -294
  231. data/ext/rcb_hdr_histogram.cxx +219 -0
  232. data/ext/rcb_hdr_histogram.hxx +28 -0
  233. data/ext/rcb_multi.cxx +142 -59
  234. data/ext/rcb_observability.cxx +132 -0
  235. data/ext/rcb_observability.hxx +49 -0
  236. data/ext/rcb_query.cxx +77 -27
  237. data/ext/rcb_search.cxx +92 -31
  238. data/ext/rcb_users.cxx +69 -26
  239. data/ext/rcb_utils.cxx +91 -0
  240. data/ext/rcb_utils.hxx +141 -168
  241. data/ext/rcb_views.cxx +36 -12
  242. data/lib/active_support/cache/couchbase_store.rb +6 -6
  243. data/lib/couchbase/authenticator.rb +14 -0
  244. data/lib/couchbase/binary_collection.rb +37 -22
  245. data/lib/couchbase/bucket.rb +46 -31
  246. data/lib/couchbase/cluster.rb +146 -61
  247. data/lib/couchbase/collection.rb +257 -186
  248. data/lib/couchbase/datastructures/couchbase_list.rb +81 -50
  249. data/lib/couchbase/datastructures/couchbase_map.rb +86 -50
  250. data/lib/couchbase/datastructures/couchbase_queue.rb +64 -38
  251. data/lib/couchbase/datastructures/couchbase_set.rb +57 -41
  252. data/lib/couchbase/deprecations.rb +1 -1
  253. data/lib/couchbase/diagnostics.rb +8 -8
  254. data/lib/couchbase/errors.rb +6 -0
  255. data/lib/couchbase/management/analytics_index_manager.rb +90 -59
  256. data/lib/couchbase/management/bucket_manager.rb +73 -45
  257. data/lib/couchbase/management/collection_manager.rb +86 -43
  258. data/lib/couchbase/management/collection_query_index_manager.rb +56 -33
  259. data/lib/couchbase/management/query_index_manager.rb +88 -36
  260. data/lib/couchbase/management/scope_search_index_manager.rb +119 -52
  261. data/lib/couchbase/management/search_index_manager.rb +401 -178
  262. data/lib/couchbase/management/user_manager.rb +343 -174
  263. data/lib/couchbase/management/view_index_manager.rb +166 -73
  264. data/lib/couchbase/metrics/logging_meter.rb +108 -0
  265. data/lib/couchbase/metrics/logging_value_recorder.rb +50 -0
  266. data/lib/couchbase/metrics/meter.rb +27 -0
  267. data/lib/couchbase/metrics/noop_meter.rb +30 -0
  268. data/lib/couchbase/metrics/noop_value_recorder.rb +27 -0
  269. data/lib/couchbase/metrics/value_recorder.rb +25 -0
  270. data/lib/couchbase/options.rb +69 -3
  271. data/lib/couchbase/protostellar/cluster.rb +3 -0
  272. data/lib/couchbase/scope.rb +62 -48
  273. data/lib/couchbase/search_options.rb +18 -18
  274. data/lib/couchbase/tracing/noop_span.rb +29 -0
  275. data/lib/couchbase/tracing/noop_tracer.rb +29 -0
  276. data/lib/couchbase/tracing/request_span.rb +34 -0
  277. data/lib/couchbase/tracing/request_tracer.rb +28 -0
  278. data/lib/couchbase/tracing/threshold_logging_span.rb +112 -0
  279. data/lib/couchbase/tracing/threshold_logging_tracer.rb +231 -0
  280. data/lib/couchbase/utils/hdr_histogram.rb +55 -0
  281. data/lib/couchbase/utils/observability.rb +257 -0
  282. data/lib/couchbase/utils/observability_constants.rb +200 -0
  283. data/lib/couchbase/utils/stdlib_logger_adapter.rb +1 -3
  284. data/lib/couchbase/version.rb +1 -1
  285. data/lib/couchbase.rb +2 -2
  286. metadata +58 -6
@@ -24,14 +24,14 @@
24
24
  #include "core/meta/version.hxx"
25
25
  #include "core/platform/uuid.h"
26
26
  #include "core/service_type_fmt.hxx"
27
+ #include "core/utils/concurrent_fixed_priority_queue.hxx"
27
28
  #include "core/utils/json.hxx"
28
29
 
29
30
  #include <asio/steady_timer.hpp>
31
+ #include <memory>
30
32
  #include <tao/json/value.hpp>
31
33
 
32
34
  #include <chrono>
33
- #include <mutex>
34
- #include <queue>
35
35
  #include <utility>
36
36
 
37
37
  namespace couchbase::core::tracing
@@ -44,6 +44,11 @@ struct reported_span {
44
44
  {
45
45
  return duration < other.duration;
46
46
  }
47
+
48
+ auto operator>(const reported_span& other) const -> bool
49
+ {
50
+ return duration > other.duration;
51
+ }
47
52
  };
48
53
 
49
54
  class threshold_logging_span
@@ -52,16 +57,15 @@ class threshold_logging_span
52
57
  {
53
58
  private:
54
59
  std::chrono::system_clock::time_point start_{ std::chrono::system_clock::now() };
55
- std::string id_{ uuid::to_string(uuid::random()) };
56
- std::map<std::string, std::uint64_t> integer_tags_{};
57
- std::map<std::string, std::string> string_tags_{
58
- { attributes::system, "couchbase" },
59
- { attributes::span_kind, "client" },
60
- { attributes::component, couchbase::core::meta::sdk_id() },
61
- };
62
- std::chrono::microseconds duration_{ 0 };
60
+ std::chrono::microseconds total_duration_{ 0 };
61
+
63
62
  std::uint64_t last_server_duration_us_{ 0 };
64
63
  std::uint64_t total_server_duration_us_{ 0 };
64
+ std::optional<std::string> operation_id_{};
65
+ std::optional<std::string> last_local_id_{};
66
+ std::optional<std::string> service_{};
67
+ std::optional<std::string> peer_hostname_{};
68
+ std::optional<std::uint16_t> peer_port_{};
65
69
 
66
70
  std::shared_ptr<threshold_logging_tracer> tracer_{};
67
71
 
@@ -74,30 +78,74 @@ public:
74
78
  {
75
79
  }
76
80
 
77
- void add_tag(const std::string& name, std::uint64_t value) override
81
+ void add_tag(const std::string& tag_name, std::uint64_t value) override
78
82
  {
79
- if (name == tracing::attributes::server_duration) {
83
+ if (tag_name == tracing::attributes::dispatch::server_duration) {
80
84
  last_server_duration_us_ = value;
81
- total_server_duration_us_ += value;
85
+ if (name() != tracing::operation::step_dispatch) {
86
+ total_server_duration_us_ += value;
87
+ }
88
+ }
89
+ if (tag_name == tracing::attributes::dispatch::peer_port) {
90
+ peer_port_ = static_cast<std::uint16_t>(value);
82
91
  }
83
- integer_tags_.try_emplace(name, value);
84
92
  }
85
93
 
86
- void add_tag(const std::string& name, const std::string& value) override
94
+ void add_tag(const std::string& tag_name, const std::string& value) override
87
95
  {
88
- string_tags_.try_emplace(name, value);
96
+ if (tag_name == tracing::attributes::op::service) {
97
+ service_ = value;
98
+ }
99
+ if (tag_name == tracing::attributes::dispatch::local_id) {
100
+ last_local_id_ = value;
101
+ }
102
+ if (tag_name == tracing::attributes::dispatch::operation_id) {
103
+ operation_id_ = value;
104
+ }
105
+ if (tag_name == tracing::attributes::dispatch::peer_address) {
106
+ peer_hostname_ = value;
107
+ }
89
108
  }
90
109
 
91
110
  void end() override;
92
111
 
93
- [[nodiscard]] auto string_tags() const -> const auto&
112
+ void set_last_local_id(const std::string& id)
113
+ {
114
+ last_local_id_ = id;
115
+ }
116
+
117
+ void set_operation_id(const std::string& id)
118
+ {
119
+ operation_id_ = id;
120
+ }
121
+
122
+ void set_peer_hostname(const std::string& hostname)
123
+ {
124
+ peer_hostname_ = hostname;
125
+ }
126
+
127
+ void set_peer_port(const std::uint16_t port)
128
+ {
129
+ peer_port_ = port;
130
+ }
131
+
132
+ [[nodiscard]] auto last_remote_socket() const -> std::optional<std::string>
133
+ {
134
+ if (peer_hostname_.has_value() && peer_port_.has_value()) {
135
+ return fmt::format("{}:{}", peer_hostname_.value(), peer_port_.value());
136
+ }
137
+ return {};
138
+ }
139
+
140
+ void add_server_duration(const std::uint64_t duration_us)
94
141
  {
95
- return string_tags_;
142
+ last_server_duration_us_ = duration_us;
143
+ total_server_duration_us_ += duration_us;
96
144
  }
97
145
 
98
- [[nodiscard]] auto duration() const -> std::chrono::microseconds
146
+ [[nodiscard]] auto total_duration() const -> std::chrono::microseconds
99
147
  {
100
- return duration_;
148
+ return total_duration_;
101
149
  }
102
150
 
103
151
  [[nodiscard]] auto last_server_duration_us() const -> std::uint64_t
@@ -110,27 +158,27 @@ public:
110
158
  return total_server_duration_us_;
111
159
  }
112
160
 
113
- [[nodiscard]] auto orphan() const -> bool
161
+ [[nodiscard]] auto operation_id() const -> std::optional<std::string>
114
162
  {
115
- return string_tags_.find(tracing::attributes::orphan) != string_tags_.end();
163
+ return operation_id_;
164
+ }
165
+
166
+ [[nodiscard]] auto last_local_id() const -> std::optional<std::string>
167
+ {
168
+ return last_local_id_;
116
169
  }
117
170
 
118
171
  [[nodiscard]] auto is_key_value() const -> bool
119
172
  {
120
- auto service_tag = string_tags_.find(tracing::attributes::service);
121
- if (service_tag == string_tags_.end()) {
122
- return false;
123
- }
124
- return service_tag->second == tracing::service::key_value;
173
+ return service_.has_value() && service_.value() == tracing::service::key_value;
125
174
  }
126
175
 
127
176
  [[nodiscard]] auto service() const -> std::optional<service_type>
128
177
  {
129
- auto service_tag = string_tags_.find(tracing::attributes::service);
130
- if (service_tag == string_tags_.end()) {
178
+ if (!service_.has_value()) {
131
179
  return {};
132
180
  }
133
- const auto& service_name = service_tag->second;
181
+ const auto& service_name = service_.value();
134
182
  if (service_name == tracing::service::key_value) {
135
183
  return service_type::key_value;
136
184
  }
@@ -153,65 +201,7 @@ public:
153
201
  }
154
202
  };
155
203
 
156
- template<typename T>
157
- class concurrent_fixed_queue
158
- {
159
- private:
160
- std::mutex mutex_;
161
- std::priority_queue<T> data_;
162
- std::size_t capacity_{};
163
-
164
- public:
165
- using size_type = typename std::priority_queue<T>::size_type;
166
-
167
- explicit concurrent_fixed_queue(std::size_t capacity)
168
- : capacity_(capacity)
169
- {
170
- }
171
-
172
- concurrent_fixed_queue(const concurrent_fixed_queue&) = delete;
173
- concurrent_fixed_queue(concurrent_fixed_queue&&) = delete;
174
- auto operator=(const concurrent_fixed_queue&) -> concurrent_fixed_queue& = delete;
175
- auto operator=(concurrent_fixed_queue&&) -> concurrent_fixed_queue& = delete;
176
- ~concurrent_fixed_queue() = default;
177
-
178
- void pop()
179
- {
180
- std::unique_lock<std::mutex> lock(mutex_);
181
- data_.pop();
182
- }
183
-
184
- auto size() -> size_type
185
- {
186
- std::unique_lock<std::mutex> lock(mutex_);
187
- return data_.size();
188
- }
189
-
190
- auto empty() -> bool
191
- {
192
- const std::unique_lock<std::mutex> lock(mutex_);
193
- return data_.empty();
194
- }
195
-
196
- void emplace(const T&& item)
197
- {
198
- const std::unique_lock<std::mutex> lock(mutex_);
199
- data_.emplace(std::forward<const T>(item));
200
- if (data_.size() > capacity_) {
201
- data_.pop();
202
- }
203
- }
204
-
205
- auto steal_data() -> std::priority_queue<T>
206
- {
207
- std::priority_queue<T> data;
208
- const std::unique_lock<std::mutex> lock(mutex_);
209
- std::swap(data, data_);
210
- return data;
211
- }
212
- };
213
-
214
- using fixed_span_queue = concurrent_fixed_queue<reported_span>;
204
+ using fixed_span_queue = utils::concurrent_fixed_priority_queue<reported_span>;
215
205
 
216
206
  auto
217
207
  convert(const std::shared_ptr<threshold_logging_span>& span) -> reported_span
@@ -219,45 +209,35 @@ convert(const std::shared_ptr<threshold_logging_span>& span) -> reported_span
219
209
  tao::json::value entry{
220
210
  { "operation_name", span->name() },
221
211
  { "total_duration_us",
222
- std::chrono::duration_cast<std::chrono::microseconds>(span->duration()).count() }
212
+ std::chrono::duration_cast<std::chrono::microseconds>(span->total_duration()).count() }
223
213
  };
224
214
  if (span->is_key_value()) {
225
215
  entry["last_server_duration_us"] = span->last_server_duration_us();
226
216
  entry["total_server_duration_us"] = span->total_server_duration_us();
227
217
  }
228
218
 
229
- const auto& tags = span->string_tags();
230
- auto pair = tags.find(attributes::operation_id);
231
- if (pair != tags.end()) {
232
- entry["last_operation_id"] = pair->second;
219
+ if (span->operation_id().has_value()) {
220
+ entry["last_operation_id"] = span->operation_id().value();
233
221
  }
234
222
 
235
- pair = tags.find(attributes::local_id);
236
- if (pair != tags.end()) {
237
- entry["last_local_id"] = pair->second;
223
+ if (span->last_local_id().has_value()) {
224
+ entry["last_local_id"] = span->last_local_id().value();
238
225
  }
239
226
 
240
- pair = tags.find(attributes::local_socket);
241
- if (pair != tags.end()) {
242
- entry["last_local_socket"] = pair->second;
227
+ if (span->last_remote_socket().has_value()) {
228
+ entry["last_remote_socket"] = span->last_remote_socket().value();
243
229
  }
244
230
 
245
- pair = tags.find(attributes::remote_socket);
246
- if (pair != tags.end()) {
247
- entry["last_remote_socket"] = pair->second;
248
- }
249
-
250
- return { span->duration(), std::move(entry) };
231
+ return { span->total_duration(), std::move(entry) };
251
232
  }
252
233
 
253
234
  class threshold_logging_tracer_impl
235
+ : public std::enable_shared_from_this<threshold_logging_tracer_impl>
254
236
  {
255
237
  public:
256
238
  threshold_logging_tracer_impl(const threshold_logging_options& options, asio::io_context& ctx)
257
239
  : options_(options)
258
- , emit_orphan_report_(ctx)
259
240
  , emit_threshold_report_(ctx)
260
- , orphan_queue_{ options.orphaned_sample_size }
261
241
  {
262
242
  threshold_queues_.try_emplace(service_type::key_value, options.threshold_sample_size);
263
243
  threshold_queues_.try_emplace(service_type::query, options.threshold_sample_size);
@@ -274,98 +254,55 @@ public:
274
254
 
275
255
  ~threshold_logging_tracer_impl()
276
256
  {
277
- emit_orphan_report_.cancel();
278
257
  emit_threshold_report_.cancel();
279
258
 
280
- log_orphan_report();
281
259
  log_threshold_report();
282
260
  }
283
261
 
284
262
  void start()
285
263
  {
286
- rearm_orphan_reporter();
287
264
  rearm_threshold_reporter();
288
265
  }
289
266
 
290
267
  void stop()
291
268
  {
292
- emit_orphan_report_.cancel();
293
269
  emit_threshold_report_.cancel();
294
270
  }
295
271
 
296
- void add_orphan(const std::shared_ptr<threshold_logging_span>& span)
297
- {
298
- orphan_queue_.emplace(convert(span));
299
- }
300
-
301
272
  void check_threshold(const std::shared_ptr<threshold_logging_span>& span)
302
273
  {
303
- auto service = span->service();
274
+ const auto service = span->service();
304
275
  if (!service.has_value()) {
305
276
  return;
306
277
  }
307
- if (span->duration() > options_.threshold_for_service(service.value())) {
308
- auto queue = threshold_queues_.find(service.value());
309
- if (queue != threshold_queues_.end()) {
278
+ if (span->total_duration() > options_.threshold_for_service(service.value())) {
279
+ if (const auto queue = threshold_queues_.find(service.value());
280
+ queue != threshold_queues_.end()) {
310
281
  queue->second.emplace(convert(span));
311
282
  }
312
283
  }
313
284
  }
314
285
 
315
286
  private:
316
- void rearm_orphan_reporter()
317
- {
318
- emit_orphan_report_.expires_after(options_.orphaned_emit_interval);
319
- emit_orphan_report_.async_wait([this](std::error_code ec) {
320
- if (ec == asio::error::operation_aborted) {
321
- return;
322
- }
323
- log_orphan_report();
324
- rearm_orphan_reporter();
325
- });
326
- }
327
-
328
287
  void rearm_threshold_reporter()
329
288
  {
330
289
  emit_threshold_report_.expires_after(options_.threshold_emit_interval);
331
- emit_threshold_report_.async_wait([this](std::error_code ec) {
290
+ emit_threshold_report_.async_wait([self = shared_from_this()](std::error_code ec) -> void {
332
291
  if (ec == asio::error::operation_aborted) {
333
292
  return;
334
293
  }
335
- log_threshold_report();
336
- rearm_threshold_reporter();
294
+ self->log_threshold_report();
295
+ self->rearm_threshold_reporter();
337
296
  });
338
297
  }
339
298
 
340
- void log_orphan_report()
341
- {
342
- if (orphan_queue_.empty()) {
343
- return;
344
- }
345
- auto queue = orphan_queue_.steal_data();
346
- tao::json::value report{
347
- { "count", queue.size() },
348
- #if COUCHBASE_CXX_CLIENT_DEBUG_BUILD
349
- { "emit_interval_ms", options_.orphaned_emit_interval.count() },
350
- { "sample_size", options_.orphaned_sample_size },
351
- #endif
352
- };
353
- tao::json::value entries = tao::json::empty_array;
354
- while (!queue.empty()) {
355
- entries.emplace_back(queue.top().payload);
356
- queue.pop();
357
- }
358
- report["top"] = entries;
359
- CB_LOG_WARNING("Orphan responses observed: {}", utils::json::generate(report));
360
- }
361
-
362
299
  void log_threshold_report()
363
300
  {
364
301
  for (auto& [service, threshold_queue] : threshold_queues_) {
365
302
  if (threshold_queue.empty()) {
366
303
  continue;
367
304
  }
368
- auto queue = threshold_queue.steal_data();
305
+ auto [queue, _] = threshold_queue.steal_data();
369
306
  tao::json::value report{
370
307
  { "count", queue.size() },
371
308
  { "service", fmt::format("{}", service) },
@@ -388,11 +325,9 @@ private:
388
325
  }
389
326
  }
390
327
 
391
- const threshold_logging_options& options_;
328
+ threshold_logging_options options_;
392
329
 
393
- asio::steady_timer emit_orphan_report_;
394
330
  asio::steady_timer emit_threshold_report_;
395
- fixed_span_queue orphan_queue_;
396
331
  std::map<service_type, fixed_span_queue> threshold_queues_{};
397
332
  };
398
333
 
@@ -407,11 +342,7 @@ threshold_logging_tracer::start_span(std::string name,
407
342
  void
408
343
  threshold_logging_tracer::report(const std::shared_ptr<threshold_logging_span>& span)
409
344
  {
410
- if (span->orphan()) {
411
- impl_->add_orphan(span);
412
- } else {
413
- impl_->check_threshold(span);
414
- }
345
+ impl_->check_threshold(span);
415
346
  }
416
347
 
417
348
  threshold_logging_tracer::threshold_logging_tracer(asio::io_context& ctx,
@@ -436,9 +367,30 @@ threshold_logging_tracer::stop()
436
367
  void
437
368
  threshold_logging_span::end()
438
369
  {
439
- duration_ = std::chrono::duration_cast<std::chrono::microseconds>(
370
+ total_duration_ = std::chrono::duration_cast<std::chrono::microseconds>(
440
371
  std::chrono::system_clock::now() - start_);
441
- tracer_->report(shared_from_this());
372
+ if (service_.has_value()) {
373
+ tracer_->report(shared_from_this());
374
+ }
375
+ if (name() == tracing::operation::step_dispatch) {
376
+ // Transfer the relevant attributes to the operation-level span
377
+ if (const auto p = std::dynamic_pointer_cast<threshold_logging_span>(parent()); p) {
378
+ if (last_local_id_.has_value()) {
379
+ p->set_last_local_id(last_local_id_.value());
380
+ }
381
+ if (operation_id_.has_value()) {
382
+ p->set_operation_id(operation_id_.value());
383
+ }
384
+ if (peer_hostname_.has_value()) {
385
+ p->set_peer_hostname(peer_hostname_.value());
386
+ }
387
+ if (peer_port_.has_value()) {
388
+ p->set_peer_port(peer_port_.value());
389
+ }
390
+ if (last_server_duration_us_ > 0) {
391
+ p->add_server_duration(last_server_duration_us_);
392
+ }
393
+ }
394
+ }
442
395
  }
443
-
444
396
  } // namespace couchbase::core::tracing
@@ -18,13 +18,14 @@
18
18
  #include "tracer_wrapper.hxx"
19
19
 
20
20
  #include "constants.hxx"
21
-
22
- #include <mutex>
21
+ #include "core/logger/logger.hxx"
23
22
 
24
23
  namespace couchbase::core::tracing
25
24
  {
26
- tracer_wrapper::tracer_wrapper(std::shared_ptr<couchbase::tracing::request_tracer> tracer)
25
+ tracer_wrapper::tracer_wrapper(std::shared_ptr<couchbase::tracing::request_tracer> tracer,
26
+ std::shared_ptr<cluster_label_listener> label_listener)
27
27
  : tracer_{ std::move(tracer) }
28
+ , cluster_label_listener_{ std::move(label_listener) }
28
29
  {
29
30
  }
30
31
 
@@ -46,42 +47,34 @@ tracer_wrapper::create_span(std::string span_name,
46
47
  -> std::shared_ptr<couchbase::tracing::request_span>
47
48
  {
48
49
  auto span = tracer_->start_span(std::move(span_name), std::move(parent_span));
49
- span->add_tag(attributes::system, "couchbase");
50
-
51
- std::optional<std::string> cluster_name;
52
- std::optional<std::string> cluster_uuid;
53
- {
54
- const std::shared_lock lock{ cluster_labels_mutex_ };
55
- cluster_name = cluster_name_;
56
- cluster_uuid = cluster_uuid_;
50
+ if (!span->uses_tags()) {
51
+ return span;
57
52
  }
58
53
 
54
+ span->add_tag(attributes::common::system, "couchbase");
55
+
56
+ auto [cluster_name, cluster_uuid] = cluster_label_listener_->cluster_labels();
59
57
  if (cluster_name) {
60
- span->add_tag(attributes::cluster_name, cluster_name.value());
58
+ span->add_tag(attributes::common::cluster_name, cluster_name.value());
61
59
  }
62
60
  if (cluster_uuid) {
63
- span->add_tag(attributes::cluster_uuid, cluster_uuid.value());
61
+ span->add_tag(attributes::common::cluster_uuid, cluster_uuid.value());
64
62
  }
65
63
 
66
64
  return span;
67
65
  }
68
66
 
69
- void
70
- tracer_wrapper::update_config(topology::configuration config)
67
+ auto
68
+ tracer_wrapper::wrapped() -> std::shared_ptr<couchbase::tracing::request_tracer>
71
69
  {
72
- const std::scoped_lock<std::shared_mutex> lock{ cluster_labels_mutex_ };
73
- if (config.cluster_uuid.has_value()) {
74
- cluster_uuid_ = config.cluster_uuid;
75
- }
76
- if (config.cluster_name.has_value()) {
77
- cluster_name_ = config.cluster_name;
78
- }
70
+ return tracer_;
79
71
  }
80
72
 
81
73
  auto
82
- tracer_wrapper::create(std::shared_ptr<couchbase::tracing::request_tracer> tracer)
74
+ tracer_wrapper::create(std::shared_ptr<couchbase::tracing::request_tracer> tracer,
75
+ std::shared_ptr<cluster_label_listener> label_listener)
83
76
  -> std::shared_ptr<tracer_wrapper>
84
77
  {
85
- return std::make_shared<tracer_wrapper>(std::move(tracer));
78
+ return std::make_shared<tracer_wrapper>(std::move(tracer), std::move(label_listener));
86
79
  }
87
80
  } // namespace couchbase::core::tracing
@@ -17,8 +17,7 @@
17
17
 
18
18
  #pragma once
19
19
 
20
- #include "core/config_listener.hxx"
21
- #include "core/topology/configuration.hxx"
20
+ #include "core/cluster_label_listener.hxx"
22
21
 
23
22
  #include <couchbase/tracing/request_span.hxx>
24
23
  #include <couchbase/tracing/request_tracer.hxx>
@@ -30,10 +29,11 @@
30
29
 
31
30
  namespace couchbase::core::tracing
32
31
  {
33
- class tracer_wrapper : public config_listener
32
+ class tracer_wrapper
34
33
  {
35
34
  public:
36
- explicit tracer_wrapper(std::shared_ptr<couchbase::tracing::request_tracer> tracer);
35
+ explicit tracer_wrapper(std::shared_ptr<couchbase::tracing::request_tracer> tracer,
36
+ std::shared_ptr<cluster_label_listener> label_listener);
37
37
 
38
38
  void start();
39
39
  void stop();
@@ -42,16 +42,14 @@ public:
42
42
  std::shared_ptr<couchbase::tracing::request_span> parent_span)
43
43
  -> std::shared_ptr<couchbase::tracing::request_span>;
44
44
 
45
- void update_config(topology::configuration config) override;
45
+ [[nodiscard]] auto wrapped() -> std::shared_ptr<couchbase::tracing::request_tracer>;
46
46
 
47
- [[nodiscard]] static auto create(std::shared_ptr<couchbase::tracing::request_tracer> tracer)
47
+ [[nodiscard]] static auto create(std::shared_ptr<couchbase::tracing::request_tracer> tracer,
48
+ std::shared_ptr<cluster_label_listener> label_listener)
48
49
  -> std::shared_ptr<tracer_wrapper>;
49
50
 
50
51
  private:
51
52
  std::shared_ptr<couchbase::tracing::request_tracer> tracer_;
52
-
53
- std::optional<std::string> cluster_name_{};
54
- std::optional<std::string> cluster_uuid_{};
55
- std::shared_mutex cluster_labels_mutex_{};
53
+ std::shared_ptr<couchbase::core::cluster_label_listener> cluster_label_listener_;
56
54
  };
57
55
  } // namespace couchbase::core::tracing
@@ -0,0 +1,114 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2025. Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include "wrapper_sdk_tracer.hxx"
19
+
20
+ #include "core/logger/logger.hxx"
21
+
22
+ namespace couchbase::core::tracing
23
+ {
24
+ auto
25
+ wrapper_sdk_tracer::start_span(std::string name,
26
+ std::shared_ptr<couchbase::tracing::request_span> parent)
27
+ -> std::shared_ptr<couchbase::tracing::request_span>
28
+ {
29
+ const auto parent_wrapper_span = std::dynamic_pointer_cast<wrapper_sdk_span>(parent);
30
+ if (!parent_wrapper_span) {
31
+ // If no parent span is provided, wrappers have no way of accessing any child spans created, so
32
+ // there is no reason to create spans.
33
+ return noop_instance_;
34
+ }
35
+ const auto span = std::make_shared<wrapper_sdk_span>(std::move(name), std::move(parent));
36
+ parent_wrapper_span->add_child(span);
37
+ return span;
38
+ }
39
+
40
+ wrapper_sdk_span::wrapper_sdk_span(std::string name)
41
+ : couchbase::tracing::request_span{ std::move(name) }
42
+ {
43
+ }
44
+
45
+ wrapper_sdk_span::wrapper_sdk_span(std::string name,
46
+ const std::shared_ptr<couchbase::tracing::request_span>& parent)
47
+ : couchbase::tracing::request_span{ std::move(name) }
48
+ , parent_{ parent }
49
+ {
50
+ }
51
+
52
+ void
53
+ wrapper_sdk_span::add_child(const std::shared_ptr<wrapper_sdk_span>& child)
54
+ {
55
+ const std::scoped_lock lock(children_mutex_);
56
+ children_.emplace_back(child);
57
+ }
58
+
59
+ void
60
+ wrapper_sdk_span::add_tag(const std::string& name, std::uint64_t value)
61
+ {
62
+ uint_tags_.emplace(name, value);
63
+ }
64
+
65
+ void
66
+ wrapper_sdk_span::add_tag(const std::string& name, const std::string& value)
67
+ {
68
+ string_tags_.emplace(name, value);
69
+ }
70
+
71
+ void
72
+ wrapper_sdk_span::end()
73
+ {
74
+ end_time_ = std::chrono::system_clock::now();
75
+ }
76
+
77
+ auto
78
+ wrapper_sdk_span::uint_tags() const -> const std::map<std::string, std::uint64_t>&
79
+ {
80
+ return uint_tags_;
81
+ }
82
+
83
+ auto
84
+ wrapper_sdk_span::string_tags() const -> const std::map<std::string, std::string>&
85
+ {
86
+ return string_tags_;
87
+ }
88
+
89
+ auto
90
+ wrapper_sdk_span::children() -> std::vector<std::shared_ptr<wrapper_sdk_span>>
91
+ {
92
+ const std::scoped_lock lock(children_mutex_);
93
+ return children_;
94
+ }
95
+
96
+ auto
97
+ wrapper_sdk_span::start_time() const -> const std::chrono::system_clock::time_point&
98
+ {
99
+ return start_time_;
100
+ }
101
+
102
+ auto
103
+ wrapper_sdk_span::end_time() const -> const std::chrono::system_clock::time_point&
104
+ {
105
+ return end_time_;
106
+ }
107
+
108
+ auto
109
+ wrapper_sdk_span::parent() const -> std::shared_ptr<couchbase::tracing::request_span>
110
+ {
111
+ return parent_.lock();
112
+ }
113
+
114
+ } // namespace couchbase::core::tracing