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.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/ext/CMakeLists.txt +4 -1
- data/ext/cache/extconf_include.rb +4 -3
- data/ext/cache/mozilla-ca-bundle.crt +66 -93
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +24 -11
- data/ext/couchbase/cmake/APKBUILD.in +17 -1
- data/ext/couchbase/cmake/Bundler.cmake +9 -1
- data/ext/couchbase/cmake/Cache.cmake +48 -19
- data/ext/couchbase/cmake/CompilerOptions.cmake +3 -1
- data/ext/couchbase/cmake/OpenSSL.cmake +10 -2
- data/ext/couchbase/cmake/Packaging.cmake +48 -8
- data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +43 -1
- data/ext/couchbase/cmake/build_config.hxx.in +2 -0
- data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +18 -0
- data/ext/couchbase/cmake/tarball_glob.txt +10 -0
- data/ext/couchbase/core/app_telemetry_meter.cxx +1 -0
- data/ext/couchbase/core/app_telemetry_reporter.cxx +45 -43
- data/ext/couchbase/core/app_telemetry_reporter.hxx +4 -3
- data/ext/couchbase/core/bucket.cxx +128 -13
- data/ext/couchbase/core/bucket.hxx +12 -2
- data/ext/couchbase/core/cluster.cxx +304 -152
- data/ext/couchbase/core/cluster.hxx +32 -0
- data/ext/couchbase/core/cluster_credentials.cxx +25 -0
- data/ext/couchbase/core/cluster_credentials.hxx +5 -0
- data/ext/couchbase/core/cluster_label_listener.cxx +72 -0
- data/ext/couchbase/core/cluster_label_listener.hxx +46 -0
- data/ext/couchbase/core/cluster_options.hxx +4 -0
- data/ext/couchbase/core/deprecation_utils.hxx +26 -0
- data/ext/couchbase/core/error.hxx +27 -0
- data/ext/couchbase/core/free_form_http_request.hxx +0 -2
- data/ext/couchbase/core/http_component.cxx +12 -48
- data/ext/couchbase/core/impl/analytics.cxx +3 -2
- data/ext/couchbase/core/impl/analytics.hxx +2 -1
- data/ext/couchbase/core/impl/analytics_index_manager.cxx +249 -137
- data/ext/couchbase/core/impl/binary_collection.cxx +134 -58
- data/ext/couchbase/core/impl/bucket_manager.cxx +87 -35
- data/ext/couchbase/core/impl/collection.cxx +560 -245
- data/ext/couchbase/core/impl/collection_manager.cxx +89 -49
- data/ext/couchbase/core/impl/dns_srv_tracker.cxx +4 -4
- data/ext/couchbase/core/impl/error.cxx +20 -13
- data/ext/couchbase/core/impl/error.hxx +15 -10
- data/ext/couchbase/core/impl/get_all_replicas.hxx +1 -1
- data/ext/couchbase/core/impl/get_any_replica.hxx +2 -1
- data/ext/couchbase/core/impl/get_replica.hxx +2 -0
- data/ext/couchbase/core/impl/lookup_in_replica.hxx +1 -1
- data/ext/couchbase/core/impl/observability_recorder.cxx +161 -0
- data/ext/couchbase/core/impl/observability_recorder.hxx +77 -0
- data/ext/couchbase/core/impl/observe_seqno.hxx +2 -0
- data/ext/couchbase/core/impl/public_bucket.cxx +31 -7
- data/ext/couchbase/core/impl/public_cluster.cxx +107 -19
- data/ext/couchbase/core/impl/query.cxx +6 -3
- data/ext/couchbase/core/impl/query.hxx +3 -1
- data/ext/couchbase/core/impl/query_index_manager.cxx +267 -102
- data/ext/couchbase/core/impl/scope.cxx +53 -11
- data/ext/couchbase/core/impl/search.cxx +8 -4
- data/ext/couchbase/core/impl/search.hxx +6 -2
- data/ext/couchbase/core/impl/search_index_manager.cxx +131 -41
- data/ext/couchbase/core/impl/with_cancellation.hxx +75 -0
- data/ext/couchbase/core/io/config_tracker.cxx +9 -9
- data/ext/couchbase/core/io/config_tracker.hxx +2 -1
- data/ext/couchbase/core/io/http_command.hxx +98 -49
- data/ext/couchbase/core/io/http_context.hxx +2 -0
- data/ext/couchbase/core/io/http_session.cxx +23 -10
- data/ext/couchbase/core/io/http_session.hxx +17 -9
- data/ext/couchbase/core/io/http_session_manager.hxx +163 -228
- data/ext/couchbase/core/io/http_traits.hxx +0 -7
- data/ext/couchbase/core/io/mcbp_command.hxx +123 -44
- data/ext/couchbase/core/io/mcbp_session.cxx +251 -26
- data/ext/couchbase/core/io/mcbp_session.hxx +9 -1
- data/ext/couchbase/core/io/mcbp_traits.hxx +0 -8
- data/ext/couchbase/core/io/streams.cxx +3 -3
- data/ext/couchbase/core/io/streams.hxx +3 -2
- data/ext/couchbase/core/meta/features.hxx +15 -0
- data/ext/couchbase/core/meta/version.cxx +13 -0
- data/ext/couchbase/core/meta/version.hxx +3 -0
- data/ext/couchbase/core/metrics/constants.hxx +23 -0
- data/ext/couchbase/core/metrics/logging_meter.cxx +5 -5
- data/ext/couchbase/core/metrics/meter_wrapper.cxx +65 -63
- data/ext/couchbase/core/metrics/meter_wrapper.hxx +12 -10
- data/ext/couchbase/core/operations/document_analytics.hxx +0 -5
- data/ext/couchbase/core/operations/document_append.hxx +0 -4
- data/ext/couchbase/core/operations/document_decrement.hxx +0 -5
- data/ext/couchbase/core/operations/document_exists.hxx +0 -7
- data/ext/couchbase/core/operations/document_get.hxx +0 -7
- data/ext/couchbase/core/operations/document_get_all_replicas.hxx +77 -27
- data/ext/couchbase/core/operations/document_get_and_lock.hxx +0 -9
- data/ext/couchbase/core/operations/document_get_and_touch.hxx +0 -9
- data/ext/couchbase/core/operations/document_get_any_replica.hxx +83 -2
- data/ext/couchbase/core/operations/document_get_projected.hxx +0 -9
- data/ext/couchbase/core/operations/document_increment.hxx +0 -5
- data/ext/couchbase/core/operations/document_insert.hxx +0 -4
- data/ext/couchbase/core/operations/document_lookup_in.hxx +0 -9
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +46 -4
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +121 -43
- data/ext/couchbase/core/operations/document_mutate_in.hxx +0 -5
- data/ext/couchbase/core/operations/document_prepend.hxx +0 -4
- data/ext/couchbase/core/operations/document_query.hxx +0 -4
- data/ext/couchbase/core/operations/document_remove.hxx +0 -4
- data/ext/couchbase/core/operations/document_replace.hxx +0 -4
- data/ext/couchbase/core/operations/document_search.hxx +0 -7
- data/ext/couchbase/core/operations/document_touch.hxx +0 -7
- data/ext/couchbase/core/operations/document_unlock.hxx +0 -6
- data/ext/couchbase/core/operations/document_upsert.hxx +0 -4
- data/ext/couchbase/core/operations/document_view.cxx +2 -0
- data/ext/couchbase/core/operations/document_view.hxx +10 -13
- data/ext/couchbase/core/operations/http_noop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataverse_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataverse_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_index_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_index_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_index_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_connect.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_disconnect.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_replace.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_describe.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_flush.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_update.hxx +2 -0
- data/ext/couchbase/core/operations/management/change_password.hxx +2 -0
- data/ext/couchbase/core/operations/management/cluster_describe.hxx +2 -0
- data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.hxx +2 -0
- data/ext/couchbase/core/operations/management/collection_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/collection_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/collection_update.hxx +2 -0
- data/ext/couchbase/core/operations/management/collections_manifest_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/error_utils.cxx +4 -1
- data/ext/couchbase/core/operations/management/eventing_deploy_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_drop_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_get_all_functions.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_get_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_get_status.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_pause_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_resume_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_undeploy_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_upsert_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/freeform.hxx +2 -0
- data/ext/couchbase/core/operations/management/group_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/group_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/group_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/group_upsert.hxx +2 -0
- data/ext/couchbase/core/operations/management/query_index_build.hxx +2 -0
- data/ext/couchbase/core/operations/management/query_index_build_deferred.hxx +68 -30
- data/ext/couchbase/core/operations/management/query_index_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/query_index_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/query_index_get_all.hxx +4 -3
- data/ext/couchbase/core/operations/management/query_index_get_all_deferred.hxx +2 -1
- data/ext/couchbase/core/operations/management/role_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/scope_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/scope_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/scope_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_get_stats.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_analyze_document.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_control_ingest.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_control_query.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_get_documents_count.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_get_stats.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_upsert.hxx +2 -0
- data/ext/couchbase/core/operations/management/user_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/user_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/user_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/user_upsert.hxx +2 -0
- data/ext/couchbase/core/operations/management/view_index_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/view_index_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/view_index_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/view_index_upsert.hxx +2 -0
- data/ext/couchbase/core/operations/operation_traits.hxx +6 -0
- data/ext/couchbase/core/operations.hxx +0 -1
- data/ext/couchbase/core/operations_fwd.hxx +8 -0
- data/ext/couchbase/core/origin.cxx +67 -12
- data/ext/couchbase/core/origin.hxx +13 -8
- data/ext/couchbase/core/orphan_reporter.cxx +164 -0
- data/ext/couchbase/core/orphan_reporter.hxx +65 -0
- data/ext/couchbase/core/sasl/CMakeLists.txt +1 -0
- data/ext/couchbase/core/sasl/client.cc +6 -0
- data/ext/couchbase/core/sasl/mechanism.cc +2 -1
- data/ext/couchbase/core/sasl/mechanism.h +2 -1
- data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.cc +41 -0
- data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.h +47 -0
- data/ext/couchbase/core/tls_context_provider.cxx +44 -0
- data/ext/couchbase/core/tls_context_provider.hxx +44 -0
- data/ext/couchbase/core/tracing/attribute_helpers.hxx +45 -0
- data/ext/couchbase/core/tracing/constants.hxx +148 -68
- data/ext/couchbase/core/tracing/threshold_logging_options.hxx +0 -3
- data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +122 -170
- data/ext/couchbase/core/tracing/tracer_wrapper.cxx +17 -24
- data/ext/couchbase/core/tracing/tracer_wrapper.hxx +8 -10
- data/ext/couchbase/core/tracing/wrapper_sdk_tracer.cxx +114 -0
- data/ext/couchbase/core/tracing/wrapper_sdk_tracer.hxx +85 -0
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +16 -14
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +4 -4
- data/ext/couchbase/core/transactions/transactions.cxx +1 -1
- data/ext/couchbase/core/transactions/transactions_cleanup.cxx +1 -2
- data/ext/couchbase/core/utils/byteswap.hxx +12 -0
- data/ext/couchbase/core/utils/concurrent_fixed_priority_queue.hxx +102 -0
- data/ext/couchbase/core/utils/connection_string.cxx +2 -0
- data/ext/couchbase/couchbase/certificate_authenticator.hxx +1 -0
- data/ext/couchbase/couchbase/cluster.hxx +47 -0
- data/ext/couchbase/couchbase/cluster_options.hxx +16 -0
- data/ext/couchbase/couchbase/collection.hxx +60 -15
- data/ext/couchbase/couchbase/error_codes.hxx +48 -48
- data/ext/couchbase/couchbase/jwt_authenticator.hxx +52 -0
- data/ext/couchbase/couchbase/metrics/meter.hxx +2 -1
- data/ext/couchbase/couchbase/metrics/otel_meter.hxx +75 -80
- data/ext/couchbase/couchbase/network_options.hxx +19 -0
- data/ext/couchbase/couchbase/password_authenticator.hxx +1 -0
- data/ext/couchbase/couchbase/tracing/otel_tracer.hxx +15 -17
- data/ext/couchbase/couchbase/tracing/request_span.hxx +2 -2
- data/ext/couchbase.cxx +4 -0
- data/ext/extconf.rb +1 -0
- data/ext/rcb_analytics.cxx +157 -47
- data/ext/rcb_backend.cxx +118 -71
- data/ext/rcb_buckets.cxx +39 -16
- data/ext/rcb_collections.cxx +36 -12
- data/ext/rcb_crud.cxx +587 -294
- data/ext/rcb_hdr_histogram.cxx +219 -0
- data/ext/rcb_hdr_histogram.hxx +28 -0
- data/ext/rcb_multi.cxx +142 -59
- data/ext/rcb_observability.cxx +132 -0
- data/ext/rcb_observability.hxx +49 -0
- data/ext/rcb_query.cxx +77 -27
- data/ext/rcb_search.cxx +92 -31
- data/ext/rcb_users.cxx +69 -26
- data/ext/rcb_utils.cxx +91 -0
- data/ext/rcb_utils.hxx +141 -168
- data/ext/rcb_views.cxx +36 -12
- data/lib/active_support/cache/couchbase_store.rb +6 -6
- data/lib/couchbase/authenticator.rb +14 -0
- data/lib/couchbase/binary_collection.rb +37 -22
- data/lib/couchbase/bucket.rb +46 -31
- data/lib/couchbase/cluster.rb +146 -61
- data/lib/couchbase/collection.rb +257 -186
- data/lib/couchbase/datastructures/couchbase_list.rb +81 -50
- data/lib/couchbase/datastructures/couchbase_map.rb +86 -50
- data/lib/couchbase/datastructures/couchbase_queue.rb +64 -38
- data/lib/couchbase/datastructures/couchbase_set.rb +57 -41
- data/lib/couchbase/deprecations.rb +1 -1
- data/lib/couchbase/diagnostics.rb +8 -8
- data/lib/couchbase/errors.rb +6 -0
- data/lib/couchbase/management/analytics_index_manager.rb +90 -59
- data/lib/couchbase/management/bucket_manager.rb +73 -45
- data/lib/couchbase/management/collection_manager.rb +86 -43
- data/lib/couchbase/management/collection_query_index_manager.rb +56 -33
- data/lib/couchbase/management/query_index_manager.rb +88 -36
- data/lib/couchbase/management/scope_search_index_manager.rb +119 -52
- data/lib/couchbase/management/search_index_manager.rb +401 -178
- data/lib/couchbase/management/user_manager.rb +343 -174
- data/lib/couchbase/management/view_index_manager.rb +166 -73
- data/lib/couchbase/metrics/logging_meter.rb +108 -0
- data/lib/couchbase/metrics/logging_value_recorder.rb +50 -0
- data/lib/couchbase/metrics/meter.rb +27 -0
- data/lib/couchbase/metrics/noop_meter.rb +30 -0
- data/lib/couchbase/metrics/noop_value_recorder.rb +27 -0
- data/lib/couchbase/metrics/value_recorder.rb +25 -0
- data/lib/couchbase/options.rb +69 -3
- data/lib/couchbase/protostellar/cluster.rb +3 -0
- data/lib/couchbase/scope.rb +62 -48
- data/lib/couchbase/search_options.rb +18 -18
- data/lib/couchbase/tracing/noop_span.rb +29 -0
- data/lib/couchbase/tracing/noop_tracer.rb +29 -0
- data/lib/couchbase/tracing/request_span.rb +34 -0
- data/lib/couchbase/tracing/request_tracer.rb +28 -0
- data/lib/couchbase/tracing/threshold_logging_span.rb +112 -0
- data/lib/couchbase/tracing/threshold_logging_tracer.rb +231 -0
- data/lib/couchbase/utils/hdr_histogram.rb +55 -0
- data/lib/couchbase/utils/observability.rb +257 -0
- data/lib/couchbase/utils/observability_constants.rb +200 -0
- data/lib/couchbase/utils/stdlib_logger_adapter.rb +1 -3
- data/lib/couchbase/version.rb +1 -1
- data/lib/couchbase.rb +2 -2
- metadata +58 -6
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright 2025-Present 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
|
+
require 'couchbase/tracing/request_tracer'
|
|
18
|
+
require 'couchbase/tracing/threshold_logging_span'
|
|
19
|
+
require 'couchbase/utils/observability_constants'
|
|
20
|
+
require 'couchbase/logger'
|
|
21
|
+
require 'couchbase/utils/stdlib_logger_adapter'
|
|
22
|
+
|
|
23
|
+
require 'json'
|
|
24
|
+
|
|
25
|
+
module Couchbase
|
|
26
|
+
module Tracing
|
|
27
|
+
class ThresholdLoggingTracer < RequestTracer
|
|
28
|
+
# @api private
|
|
29
|
+
DEFAULT_KV_THRESHOLD = 500 # milliseconds
|
|
30
|
+
|
|
31
|
+
# @api private
|
|
32
|
+
DEFAULT_HTTP_THRESHOLD = 1_000 # milliseconds
|
|
33
|
+
|
|
34
|
+
# @api private
|
|
35
|
+
DEFAULT_SAMPLE_SIZE = 10
|
|
36
|
+
|
|
37
|
+
# @api private
|
|
38
|
+
DEFAULT_EMIT_INTERVAL = 10_000 # milliseconds
|
|
39
|
+
|
|
40
|
+
def initialize(
|
|
41
|
+
emit_interval: nil,
|
|
42
|
+
kv_threshold: nil,
|
|
43
|
+
query_threshold: nil,
|
|
44
|
+
views_threshold: nil,
|
|
45
|
+
search_threshold: nil,
|
|
46
|
+
analytics_threshold: nil,
|
|
47
|
+
management_threshold: nil,
|
|
48
|
+
sample_size: nil
|
|
49
|
+
)
|
|
50
|
+
super()
|
|
51
|
+
|
|
52
|
+
emit_interval = DEFAULT_EMIT_INTERVAL if emit_interval.nil?
|
|
53
|
+
kv_threshold = DEFAULT_KV_THRESHOLD if kv_threshold.nil?
|
|
54
|
+
query_threshold = DEFAULT_HTTP_THRESHOLD if query_threshold.nil?
|
|
55
|
+
views_threshold = DEFAULT_HTTP_THRESHOLD if views_threshold.nil?
|
|
56
|
+
search_threshold = DEFAULT_HTTP_THRESHOLD if search_threshold.nil?
|
|
57
|
+
analytics_threshold = DEFAULT_HTTP_THRESHOLD if analytics_threshold.nil?
|
|
58
|
+
management_threshold = DEFAULT_HTTP_THRESHOLD if management_threshold.nil?
|
|
59
|
+
sample_size = DEFAULT_SAMPLE_SIZE if sample_size.nil?
|
|
60
|
+
|
|
61
|
+
raise ArgumentError, "The sample size for ThresholdLoggingTracer must be positive" unless sample_size.positive?
|
|
62
|
+
|
|
63
|
+
@emit_interval = emit_interval
|
|
64
|
+
@sample_size = sample_size
|
|
65
|
+
@groups = {
|
|
66
|
+
Observability::ATTR_VALUE_SERVICE_KV => Group.new(floor_us: 1000 * kv_threshold, capacity: @sample_size),
|
|
67
|
+
Observability::ATTR_VALUE_SERVICE_QUERY => Group.new(floor_us: 1000 * query_threshold, capacity: @sample_size),
|
|
68
|
+
Observability::ATTR_VALUE_SERVICE_VIEWS => Group.new(floor_us: 1000 * views_threshold, capacity: @sample_size),
|
|
69
|
+
Observability::ATTR_VALUE_SERVICE_SEARCH => Group.new(floor_us: 1000 * search_threshold, capacity: @sample_size),
|
|
70
|
+
Observability::ATTR_VALUE_SERVICE_ANALYTICS => Group.new(floor_us: 1000 * analytics_threshold, capacity: @sample_size),
|
|
71
|
+
Observability::ATTR_VALUE_SERVICE_MANAGEMENT => Group.new(floor_us: 1000 * management_threshold, capacity: @sample_size),
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# TODO(DC): Find better solution for logging
|
|
75
|
+
@logger = Couchbase.logger || Logger.new($stdout, Utils::StdlibLoggerAdapter.map_spdlog_level(Couchbase.log_level))
|
|
76
|
+
start_reporting_thread
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def request_span(name, parent: nil, start_timestamp: nil)
|
|
80
|
+
ThresholdLoggingSpan.new(
|
|
81
|
+
name,
|
|
82
|
+
start_timestamp: start_timestamp,
|
|
83
|
+
parent: parent,
|
|
84
|
+
tracer: self,
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def record_operation(service, item)
|
|
89
|
+
group = @groups[service]
|
|
90
|
+
return if group.nil?
|
|
91
|
+
|
|
92
|
+
group.record_operation(item)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def close
|
|
96
|
+
@thread.exit
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def create_report
|
|
100
|
+
data = {}
|
|
101
|
+
@groups.each do |service, group|
|
|
102
|
+
group_data = group.steal_data
|
|
103
|
+
next if group_data.nil?
|
|
104
|
+
|
|
105
|
+
data[service] = group_data
|
|
106
|
+
end
|
|
107
|
+
data
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def start_reporting_thread
|
|
111
|
+
@thread = Thread.new do # rubocop:disable ThreadSafety/NewThread
|
|
112
|
+
loop do
|
|
113
|
+
sleep(@emit_interval / 1_000.0)
|
|
114
|
+
report = create_report
|
|
115
|
+
|
|
116
|
+
next if report.empty?
|
|
117
|
+
|
|
118
|
+
begin
|
|
119
|
+
@logger.info("Threshold Logging Report: #{report.to_json}")
|
|
120
|
+
rescue StandardError => e
|
|
121
|
+
@logger.debug("Failed to log threshold logging report: #{e.message}")
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
class Item
|
|
128
|
+
attr_accessor :total_duration_us
|
|
129
|
+
attr_accessor :encode_duration_us
|
|
130
|
+
attr_accessor :last_dispatch_duration_us
|
|
131
|
+
attr_accessor :total_dispatch_duration_us
|
|
132
|
+
attr_accessor :last_server_duration_us
|
|
133
|
+
attr_accessor :total_server_duration_us
|
|
134
|
+
attr_accessor :operation_name
|
|
135
|
+
attr_accessor :last_local_id
|
|
136
|
+
attr_accessor :operation_id
|
|
137
|
+
attr_accessor :last_remote_socket
|
|
138
|
+
|
|
139
|
+
def initialize(
|
|
140
|
+
total_duration_us:,
|
|
141
|
+
encode_duration_us:,
|
|
142
|
+
last_dispatch_duration_us:,
|
|
143
|
+
total_dispatch_duration_us:,
|
|
144
|
+
last_server_duration_us:,
|
|
145
|
+
total_server_duration_us:,
|
|
146
|
+
operation_name:,
|
|
147
|
+
last_local_id:,
|
|
148
|
+
operation_id:,
|
|
149
|
+
last_remote_socket:
|
|
150
|
+
)
|
|
151
|
+
@total_duration_us = total_duration_us
|
|
152
|
+
@encode_duration_us = encode_duration_us
|
|
153
|
+
@last_dispatch_duration_us = last_dispatch_duration_us
|
|
154
|
+
@total_dispatch_duration_us = total_dispatch_duration_us
|
|
155
|
+
@last_server_duration_us = last_server_duration_us
|
|
156
|
+
@total_server_duration_us = total_server_duration_us
|
|
157
|
+
@operation_name = operation_name
|
|
158
|
+
@last_local_id = last_local_id
|
|
159
|
+
@operation_id = operation_id
|
|
160
|
+
@last_remote_socket = last_remote_socket
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def to_h
|
|
164
|
+
{
|
|
165
|
+
total_duration_us: @total_duration_us,
|
|
166
|
+
encode_duration_us: @encode_duration_us,
|
|
167
|
+
last_dispatch_duration_us: @last_dispatch_duration_us,
|
|
168
|
+
total_dispatch_duration_us: @total_dispatch_duration_us,
|
|
169
|
+
last_server_duration_us: @last_server_duration_us,
|
|
170
|
+
total_server_duration_us: @total_server_duration_us,
|
|
171
|
+
operation_name: @operation_name,
|
|
172
|
+
last_local_id: @last_local_id,
|
|
173
|
+
operation_id: @operation_id,
|
|
174
|
+
last_remote_socket: @last_remote_socket,
|
|
175
|
+
}.compact
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
class Group
|
|
180
|
+
def initialize(capacity:, floor_us:)
|
|
181
|
+
@capacity = capacity
|
|
182
|
+
@floor_us = floor_us
|
|
183
|
+
|
|
184
|
+
@total_count = 0
|
|
185
|
+
@top_requests = []
|
|
186
|
+
@mutex = Mutex.new
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def record_operation(item)
|
|
190
|
+
return if item.total_duration_us < @floor_us
|
|
191
|
+
|
|
192
|
+
@mutex.synchronize do
|
|
193
|
+
@total_count += 1
|
|
194
|
+
|
|
195
|
+
return if @top_requests.size >= @capacity && item.total_duration_us < @top_requests[-1].total_duration_us
|
|
196
|
+
|
|
197
|
+
idx = @top_requests.bsearch_index do |x|
|
|
198
|
+
item.total_duration_us >= x.total_duration_us
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# The item is smaller than all existing items. We will insert it at the end.
|
|
202
|
+
idx = @top_requests.size if idx.nil?
|
|
203
|
+
|
|
204
|
+
if @top_requests.size >= @capacity
|
|
205
|
+
# We are at capacity, remove the smallest (last) item
|
|
206
|
+
@top_requests.pop
|
|
207
|
+
end
|
|
208
|
+
@top_requests.insert(idx, item)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def steal_data
|
|
213
|
+
top_requests, total_count = @mutex.synchronize do
|
|
214
|
+
top_requests_tmp = @top_requests
|
|
215
|
+
total_count_tmp = @total_count
|
|
216
|
+
@top_requests = []
|
|
217
|
+
@total_count = 0
|
|
218
|
+
[top_requests_tmp, total_count_tmp]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
return nil if total_count.zero?
|
|
222
|
+
|
|
223
|
+
{
|
|
224
|
+
total_count: total_count,
|
|
225
|
+
top_requests: top_requests.map(&:to_h),
|
|
226
|
+
}
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright 2025-Present 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
|
+
module Couchbase
|
|
18
|
+
module Utils
|
|
19
|
+
class HdrHistogram
|
|
20
|
+
def initialize(
|
|
21
|
+
lowest_discernible_value:,
|
|
22
|
+
highest_trackable_value:,
|
|
23
|
+
significant_figures:,
|
|
24
|
+
percentiles: nil
|
|
25
|
+
)
|
|
26
|
+
@histogram_backend = HdrHistogramC.new(lowest_discernible_value, highest_trackable_value, significant_figures)
|
|
27
|
+
@percentiles = percentiles || [50.0, 90.0, 99.0, 99.9, 100.0]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def record_value(value)
|
|
31
|
+
@histogram_backend.record_value(value)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def close
|
|
35
|
+
@histogram_backend.close
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def report_and_reset
|
|
39
|
+
backend_report = @histogram_backend.get_percentiles_and_reset(@percentiles)
|
|
40
|
+
total_count = backend_report[:total_count]
|
|
41
|
+
|
|
42
|
+
return nil if total_count.zero?
|
|
43
|
+
|
|
44
|
+
report = {
|
|
45
|
+
total_count: total_count,
|
|
46
|
+
percentiles_us: {},
|
|
47
|
+
}
|
|
48
|
+
@percentiles.zip(backend_report[:percentiles]).each do |percentile, percentile_value|
|
|
49
|
+
report[:percentiles_us][percentile.to_s] = percentile_value
|
|
50
|
+
end
|
|
51
|
+
report
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright 2025-Present 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
|
+
require "couchbase/tracing/request_span"
|
|
18
|
+
require "couchbase/tracing/request_tracer"
|
|
19
|
+
|
|
20
|
+
require_relative "observability_constants"
|
|
21
|
+
|
|
22
|
+
module Couchbase
|
|
23
|
+
module Observability
|
|
24
|
+
class ClusterLabelListener
|
|
25
|
+
attr_reader :cluster_name
|
|
26
|
+
attr_reader :cluster_uuid
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class Wrapper
|
|
30
|
+
attr_accessor :tracer
|
|
31
|
+
attr_accessor :meter
|
|
32
|
+
|
|
33
|
+
def initialize(backend:, tracer: nil, meter: nil)
|
|
34
|
+
@backend = backend
|
|
35
|
+
@tracer = tracer
|
|
36
|
+
@meter = meter
|
|
37
|
+
|
|
38
|
+
yield self if block_given?
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def record_operation(op_name, parent_span, receiver, service = nil)
|
|
42
|
+
handler = Handler.new(@backend, op_name, parent_span, receiver, @tracer, @meter)
|
|
43
|
+
handler.add_operation_name(op_name)
|
|
44
|
+
handler.add_service(service) unless service.nil?
|
|
45
|
+
begin
|
|
46
|
+
res = yield(handler)
|
|
47
|
+
rescue StandardError => e
|
|
48
|
+
handler.add_error(e)
|
|
49
|
+
raise e
|
|
50
|
+
else
|
|
51
|
+
handler.set_success
|
|
52
|
+
ensure
|
|
53
|
+
handler.finish
|
|
54
|
+
end
|
|
55
|
+
res
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def close
|
|
59
|
+
@tracer&.close
|
|
60
|
+
@meter&.close
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class Handler
|
|
65
|
+
attr_reader :op_span
|
|
66
|
+
|
|
67
|
+
def initialize(backend, op_name, parent_span, receiver, tracer, meter)
|
|
68
|
+
@tracer = tracer
|
|
69
|
+
@meter = meter
|
|
70
|
+
|
|
71
|
+
cluster_labels = backend.cluster_labels
|
|
72
|
+
@cluster_name = cluster_labels[:cluster_name]
|
|
73
|
+
@cluster_uuid = cluster_labels[:cluster_uuid]
|
|
74
|
+
|
|
75
|
+
@op_span = create_span(op_name, parent_span)
|
|
76
|
+
@meter_attributes = create_meter_attributes
|
|
77
|
+
@start_time = Time.now
|
|
78
|
+
add_operation_name(op_name)
|
|
79
|
+
add_receiver_attributes(receiver)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def with_request_encoding_span
|
|
83
|
+
span = create_span(STEP_REQUEST_ENCODING, @op_span)
|
|
84
|
+
begin
|
|
85
|
+
res = yield
|
|
86
|
+
ensure
|
|
87
|
+
span.finish
|
|
88
|
+
end
|
|
89
|
+
res
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def add_service(service)
|
|
93
|
+
service_str =
|
|
94
|
+
case service
|
|
95
|
+
when :kv
|
|
96
|
+
ATTR_VALUE_SERVICE_KV
|
|
97
|
+
when :query
|
|
98
|
+
ATTR_VALUE_SERVICE_QUERY
|
|
99
|
+
when :analytics
|
|
100
|
+
ATTR_VALUE_SERVICE_ANALYTICS
|
|
101
|
+
when :search
|
|
102
|
+
ATTR_VALUE_SERVICE_SEARCH
|
|
103
|
+
when :management
|
|
104
|
+
ATTR_VALUE_SERVICE_MANAGEMENT
|
|
105
|
+
when :views
|
|
106
|
+
ATTR_VALUE_SERVICE_VIEWS
|
|
107
|
+
end
|
|
108
|
+
@op_span.set_attribute(ATTR_SERVICE, service_str) unless service_str.nil?
|
|
109
|
+
@meter_attributes[ATTR_SERVICE] = service_str unless service_str.nil?
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def add_operation_name(name)
|
|
113
|
+
@op_span.set_attribute(ATTR_OPERATION_NAME, name)
|
|
114
|
+
@meter_attributes[ATTR_OPERATION_NAME] = name
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def add_bucket_name(name)
|
|
118
|
+
@op_span.set_attribute(ATTR_BUCKET_NAME, name)
|
|
119
|
+
@meter_attributes[ATTR_BUCKET_NAME] = name
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def add_scope_name(name)
|
|
123
|
+
@op_span.set_attribute(ATTR_SCOPE_NAME, name)
|
|
124
|
+
@meter_attributes[ATTR_SCOPE_NAME] = name
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def add_collection_name(name)
|
|
128
|
+
@op_span.set_attribute(ATTR_COLLECTION_NAME, name)
|
|
129
|
+
@meter_attributes[ATTR_COLLECTION_NAME] = name
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def add_durability_level(level)
|
|
133
|
+
durability_str =
|
|
134
|
+
case level
|
|
135
|
+
when :majority
|
|
136
|
+
ATTR_VALUE_DURABILITY_MAJORITY
|
|
137
|
+
when :majority_and_persist_to_active
|
|
138
|
+
ATTR_VALUE_DURABILITY_MAJORITY_AND_PERSIST_TO_ACTIVE
|
|
139
|
+
when :persist_to_majority
|
|
140
|
+
ATTR_VALUE_DURABILITY_PERSIST_TO_MAJORITY
|
|
141
|
+
end
|
|
142
|
+
@op_span.set_attribute(ATTR_DURABILITY, durability_str) unless durability_str.nil?
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def add_retries(retries)
|
|
146
|
+
@op_span.set_attribute(ATTR_RETRIES, retries.to_i)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def set_success
|
|
150
|
+
@op_span.status = :ok
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def add_error(error)
|
|
154
|
+
@op_span.status = :error
|
|
155
|
+
@meter_attributes[ATTR_ERROR_TYPE] =
|
|
156
|
+
if error.is_a?(Couchbase::Error::CouchbaseError) || error.is_a?(Couchbase::Error::InvalidArgument)
|
|
157
|
+
error.class.name.split("::").last
|
|
158
|
+
else
|
|
159
|
+
"_OTHER"
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def add_query_statement(statement, options)
|
|
164
|
+
pos_params = options.instance_variable_get(:@positional_parameters)
|
|
165
|
+
named_params = options.instance_variable_get(:@named_parameters)
|
|
166
|
+
|
|
167
|
+
# The statement attribute is added only if positional or named parameters are in use.
|
|
168
|
+
return if (pos_params.nil? || pos_params.empty?) && (named_params.nil? || named_params.empty?)
|
|
169
|
+
|
|
170
|
+
@op_span.set_attribute(ATTR_QUERY_STATEMENT, statement)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def add_spans_from_backend(backend_spans)
|
|
174
|
+
backend_spans.each do |backend_span|
|
|
175
|
+
add_backend_span(backend_span, @op_span)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def finish
|
|
180
|
+
@op_span.finish
|
|
181
|
+
duration_us = ((Time.now - @start_time) * 1_000_000).round
|
|
182
|
+
@meter.value_recorder(METER_NAME_OPERATION_DURATION, @meter_attributes).record_value(duration_us)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
private
|
|
186
|
+
|
|
187
|
+
def add_backend_span(backend_span, parent)
|
|
188
|
+
span = @tracer.request_span(
|
|
189
|
+
backend_span[:name],
|
|
190
|
+
parent: parent,
|
|
191
|
+
start_timestamp: convert_backend_timestamp(backend_span[:start_timestamp]),
|
|
192
|
+
)
|
|
193
|
+
backend_span[:attributes].each do |k, v|
|
|
194
|
+
span.set_attribute(k, v)
|
|
195
|
+
end
|
|
196
|
+
if backend_span.key?(:children)
|
|
197
|
+
backend_span[:children].each do |c|
|
|
198
|
+
add_backend_span(c, span)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
span.finish(end_timestamp: convert_backend_timestamp(backend_span[:end_timestamp]))
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def convert_backend_timestamp(backend_timestamp)
|
|
205
|
+
Time.at(backend_timestamp / (10**6), backend_timestamp % (10**6))
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def create_meter_attributes
|
|
209
|
+
attrs = {
|
|
210
|
+
ATTR_SYSTEM_NAME => ATTR_VALUE_SYSTEM_NAME,
|
|
211
|
+
ATTR_RESERVED_UNIT => ATTR_VALUE_RESERVED_UNIT_SECONDS,
|
|
212
|
+
}
|
|
213
|
+
attrs[ATTR_CLUSTER_NAME] = @cluster_name unless @cluster_name.nil?
|
|
214
|
+
attrs[ATTR_CLUSTER_UUID] = @cluster_uuid unless @cluster_uuid.nil?
|
|
215
|
+
attrs
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def create_span(name, parent, start_timestamp: nil)
|
|
219
|
+
span = @tracer.request_span(name, parent: parent, start_timestamp: start_timestamp)
|
|
220
|
+
span.set_attribute(ATTR_SYSTEM_NAME, ATTR_VALUE_SYSTEM_NAME)
|
|
221
|
+
span.set_attribute(ATTR_CLUSTER_NAME, @cluster_name) unless @cluster_name.nil?
|
|
222
|
+
span.set_attribute(ATTR_CLUSTER_UUID, @cluster_uuid) unless @cluster_uuid.nil?
|
|
223
|
+
span
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def add_receiver_attributes(receiver)
|
|
227
|
+
if receiver.instance_variable_defined?(:@collection)
|
|
228
|
+
collection = receiver.instance_variable_get(:@collection)
|
|
229
|
+
add_bucket_name(collection.bucket_name)
|
|
230
|
+
add_scope_name(collection.scope_name)
|
|
231
|
+
add_collection_name(collection.name)
|
|
232
|
+
return
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
if receiver.instance_variable_defined?(:@bucket_name)
|
|
236
|
+
add_bucket_name(receiver.instance_variable_get(:@bucket_name))
|
|
237
|
+
elsif receiver.instance_variable_defined?(:@name)
|
|
238
|
+
add_bucket_name(receiver.instance_variable_get(:@name))
|
|
239
|
+
return
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
if receiver.instance_variable_defined?(:@scope_name)
|
|
243
|
+
add_scope_name(receiver.instance_variable_get(:@scope_name))
|
|
244
|
+
elsif receiver.instance_variable_defined?(:@name)
|
|
245
|
+
add_scope_name(receiver.instance_variable_get(:@name))
|
|
246
|
+
return
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
if receiver.instance_variable_defined?(:@collection_name)
|
|
250
|
+
add_collection_name(receiver.instance_variable_get(:@collection_name))
|
|
251
|
+
elsif receiver.instance_variable_defined?(:@name)
|
|
252
|
+
add_collection_name(receiver.instance_variable_get(:@name))
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|