couchbase 3.1.1-universal-darwin-20 → 3.2.0-universal-darwin-20
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 +2 -2
- data/ext/CMakeLists.txt +3 -1
- data/ext/build_version.hxx.in +1 -1
- data/ext/cmake/Testing.cmake +1 -0
- data/ext/cmake/ThirdPartyDependencies.cmake +6 -0
- data/ext/cmake/VersionInfo.cmake +3 -0
- data/ext/couchbase/bucket.hxx +47 -28
- data/ext/couchbase/cbsasl/client.h +1 -1
- data/ext/couchbase/cbsasl/context.cc +1 -1
- data/ext/couchbase/cbsasl/context.h +3 -3
- data/ext/couchbase/cbsasl/mechanism.cc +5 -8
- data/ext/couchbase/cbsasl/mechanism.h +1 -4
- data/ext/couchbase/cbsasl/plain/plain.cc +1 -1
- data/ext/couchbase/cbsasl/scram-sha/scram-sha.cc +30 -36
- data/ext/couchbase/cluster.hxx +40 -22
- data/ext/couchbase/cluster_options.hxx +7 -1
- data/ext/couchbase/configuration.hxx +37 -16
- data/ext/couchbase/couchbase.cxx +1145 -291
- data/ext/couchbase/error_map.hxx +1 -1
- data/ext/couchbase/errors.hxx +25 -17
- data/ext/couchbase/io/dns_client.hxx +3 -3
- data/ext/couchbase/io/dns_codec.hxx +4 -5
- data/ext/couchbase/io/dns_config.hxx +5 -6
- data/ext/couchbase/io/dns_message.hxx +3 -3
- data/ext/couchbase/io/http_command.hxx +70 -35
- data/ext/couchbase/io/http_session.hxx +4 -3
- data/ext/couchbase/io/http_session_manager.hxx +28 -19
- data/ext/couchbase/io/mcbp_command.hxx +51 -19
- data/ext/couchbase/io/mcbp_context.hxx +1 -1
- data/ext/couchbase/io/mcbp_parser.hxx +4 -4
- data/ext/couchbase/io/mcbp_session.hxx +91 -101
- data/ext/couchbase/io/query_cache.hxx +2 -2
- data/ext/couchbase/io/retry_orchestrator.hxx +2 -4
- data/ext/couchbase/io/retry_reason.hxx +2 -2
- data/ext/couchbase/io/retry_strategy.hxx +1 -6
- data/ext/couchbase/io/streams.hxx +7 -7
- data/ext/couchbase/metrics/logging_meter.hxx +228 -0
- data/ext/couchbase/metrics/logging_meter_options.hxx +28 -0
- data/ext/couchbase/metrics/meter.hxx +49 -0
- data/ext/couchbase/metrics/noop_meter.hxx +43 -0
- data/ext/couchbase/operations.hxx +4 -0
- data/ext/couchbase/operations/analytics_dataset_create.hxx +16 -12
- data/ext/couchbase/operations/analytics_dataset_drop.hxx +11 -11
- data/ext/couchbase/operations/analytics_dataset_get_all.hxx +6 -6
- data/ext/couchbase/operations/analytics_dataverse_create.hxx +10 -11
- data/ext/couchbase/operations/analytics_dataverse_drop.hxx +10 -11
- data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +9 -11
- data/ext/couchbase/operations/analytics_index_create.hxx +14 -13
- data/ext/couchbase/operations/analytics_index_drop.hxx +18 -12
- data/ext/couchbase/operations/analytics_index_get_all.hxx +8 -6
- data/ext/couchbase/operations/analytics_link.hxx +39 -0
- data/ext/couchbase/operations/analytics_link_azure_blob_external.hxx +145 -0
- data/ext/couchbase/operations/analytics_link_connect.hxx +14 -12
- data/ext/couchbase/operations/analytics_link_couchbase_remote.hxx +220 -0
- data/ext/couchbase/operations/analytics_link_create.hxx +128 -0
- data/ext/couchbase/operations/analytics_link_disconnect.hxx +11 -12
- data/ext/couchbase/operations/analytics_link_drop.hxx +130 -0
- data/ext/couchbase/operations/analytics_link_get_all.hxx +160 -0
- data/ext/couchbase/operations/analytics_link_replace.hxx +128 -0
- data/ext/couchbase/operations/analytics_link_s3_external.hxx +122 -0
- data/ext/couchbase/operations/bucket_create.hxx +8 -8
- data/ext/couchbase/operations/bucket_drop.hxx +5 -5
- data/ext/couchbase/operations/bucket_flush.hxx +5 -5
- data/ext/couchbase/operations/bucket_get.hxx +7 -7
- data/ext/couchbase/operations/bucket_get_all.hxx +7 -5
- data/ext/couchbase/operations/bucket_settings.hxx +40 -49
- data/ext/couchbase/operations/bucket_update.hxx +8 -8
- data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +7 -7
- data/ext/couchbase/operations/collection_create.hxx +11 -11
- data/ext/couchbase/operations/collection_drop.hxx +12 -10
- data/ext/couchbase/operations/collections_manifest_get.hxx +3 -3
- data/ext/couchbase/operations/design_document.hxx +2 -2
- data/ext/couchbase/operations/document_analytics.hxx +29 -36
- data/ext/couchbase/operations/document_append.hxx +3 -3
- data/ext/couchbase/operations/document_decrement.hxx +3 -3
- data/ext/couchbase/operations/document_exists.hxx +2 -2
- data/ext/couchbase/operations/document_get.hxx +3 -3
- data/ext/couchbase/operations/document_get_and_lock.hxx +5 -3
- data/ext/couchbase/operations/document_get_and_touch.hxx +5 -3
- data/ext/couchbase/operations/document_get_projected.hxx +10 -11
- data/ext/couchbase/operations/document_increment.hxx +3 -3
- data/ext/couchbase/operations/document_insert.hxx +3 -3
- data/ext/couchbase/operations/document_lookup_in.hxx +12 -18
- data/ext/couchbase/operations/document_mutate_in.hxx +13 -18
- data/ext/couchbase/operations/document_prepend.hxx +3 -3
- data/ext/couchbase/operations/document_query.hxx +39 -41
- data/ext/couchbase/operations/document_remove.hxx +3 -3
- data/ext/couchbase/operations/document_replace.hxx +3 -3
- data/ext/couchbase/operations/document_search.hxx +56 -61
- data/ext/couchbase/operations/document_touch.hxx +3 -3
- data/ext/couchbase/operations/document_unlock.hxx +3 -3
- data/ext/couchbase/operations/document_upsert.hxx +3 -3
- data/ext/couchbase/operations/document_view.hxx +23 -23
- data/ext/couchbase/operations/group_drop.hxx +5 -5
- data/ext/couchbase/operations/group_get.hxx +7 -7
- data/ext/couchbase/operations/group_get_all.hxx +6 -6
- data/ext/couchbase/operations/group_upsert.hxx +11 -11
- data/ext/couchbase/operations/http_noop.hxx +6 -6
- data/ext/couchbase/operations/mcbp_noop.hxx +3 -3
- data/ext/couchbase/operations/query_index_build_deferred.hxx +6 -6
- data/ext/couchbase/operations/query_index_create.hxx +10 -8
- data/ext/couchbase/operations/query_index_drop.hxx +8 -8
- data/ext/couchbase/operations/query_index_get_all.hxx +43 -39
- data/ext/couchbase/operations/rbac.hxx +40 -63
- data/ext/couchbase/operations/role_get_all.hxx +6 -6
- data/ext/couchbase/operations/scope_create.hxx +10 -10
- data/ext/couchbase/operations/scope_drop.hxx +9 -9
- data/ext/couchbase/operations/scope_get_all.hxx +8 -8
- data/ext/couchbase/operations/search_get_stats.hxx +5 -3
- data/ext/couchbase/operations/search_index.hxx +6 -15
- data/ext/couchbase/operations/search_index_analyze_document.hxx +11 -11
- data/ext/couchbase/operations/search_index_control_ingest.hxx +9 -9
- data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +9 -9
- data/ext/couchbase/operations/search_index_control_query.hxx +9 -9
- data/ext/couchbase/operations/search_index_drop.hxx +11 -9
- data/ext/couchbase/operations/search_index_get.hxx +11 -9
- data/ext/couchbase/operations/search_index_get_all.hxx +11 -11
- data/ext/couchbase/operations/search_index_get_documents_count.hxx +10 -10
- data/ext/couchbase/operations/search_index_get_stats.hxx +10 -8
- data/ext/couchbase/operations/search_index_upsert.hxx +12 -10
- data/ext/couchbase/operations/user_drop.hxx +5 -5
- data/ext/couchbase/operations/user_get.hxx +7 -7
- data/ext/couchbase/operations/user_get_all.hxx +6 -6
- data/ext/couchbase/operations/user_upsert.hxx +9 -9
- data/ext/couchbase/operations/view_index_drop.hxx +10 -10
- data/ext/couchbase/operations/view_index_get.hxx +13 -15
- data/ext/couchbase/operations/view_index_get_all.hxx +17 -20
- data/ext/couchbase/operations/view_index_upsert.hxx +9 -7
- data/ext/couchbase/origin.hxx +14 -10
- data/ext/couchbase/platform/backtrace.c +1 -1
- data/ext/couchbase/platform/base64.cc +5 -5
- data/ext/couchbase/platform/base64.h +2 -5
- data/ext/couchbase/protocol/client_opcode.hxx +7 -4
- data/ext/couchbase/protocol/client_request.hxx +2 -2
- data/ext/couchbase/protocol/client_response.hxx +41 -16
- data/ext/couchbase/protocol/cmd_append.hxx +17 -16
- data/ext/couchbase/protocol/cmd_cluster_map_change_notification.hxx +4 -4
- data/ext/couchbase/protocol/cmd_decrement.hxx +10 -11
- data/ext/couchbase/protocol/cmd_exists.hxx +12 -15
- data/ext/couchbase/protocol/cmd_get.hxx +11 -14
- data/ext/couchbase/protocol/cmd_get_and_lock.hxx +10 -12
- data/ext/couchbase/protocol/cmd_get_and_touch.hxx +10 -12
- data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +13 -18
- data/ext/couchbase/protocol/cmd_get_collection_id.hxx +12 -15
- data/ext/couchbase/protocol/cmd_get_collections_manifest.hxx +12 -16
- data/ext/couchbase/protocol/cmd_get_error_map.hxx +14 -17
- data/ext/couchbase/protocol/cmd_hello.hxx +8 -10
- data/ext/couchbase/protocol/cmd_increment.hxx +9 -10
- data/ext/couchbase/protocol/cmd_insert.hxx +9 -9
- data/ext/couchbase/protocol/cmd_lookup_in.hxx +12 -13
- data/ext/couchbase/protocol/cmd_mutate_in.hxx +11 -11
- data/ext/couchbase/protocol/cmd_noop.hxx +16 -20
- data/ext/couchbase/protocol/cmd_prepend.hxx +9 -10
- data/ext/couchbase/protocol/cmd_remove.hxx +10 -13
- data/ext/couchbase/protocol/cmd_replace.hxx +7 -7
- data/ext/couchbase/protocol/cmd_sasl_auth.hxx +8 -10
- data/ext/couchbase/protocol/cmd_sasl_list_mechs.hxx +10 -15
- data/ext/couchbase/protocol/cmd_sasl_step.hxx +10 -12
- data/ext/couchbase/protocol/cmd_select_bucket.hxx +14 -18
- data/ext/couchbase/protocol/cmd_touch.hxx +8 -11
- data/ext/couchbase/protocol/cmd_unlock.hxx +10 -14
- data/ext/couchbase/protocol/cmd_upsert.hxx +8 -8
- data/ext/couchbase/protocol/datatype.hxx +3 -3
- data/ext/couchbase/protocol/durability_level.hxx +2 -2
- data/ext/couchbase/protocol/frame_info_id.hxx +4 -4
- data/ext/couchbase/protocol/hello_feature.hxx +2 -2
- data/ext/couchbase/protocol/magic.hxx +2 -2
- data/ext/couchbase/protocol/server_opcode.hxx +2 -2
- data/ext/couchbase/protocol/server_request.hxx +1 -1
- data/ext/couchbase/protocol/status.hxx +4 -7
- data/ext/couchbase/protocol/unsigned_leb128.h +5 -20
- data/ext/couchbase/service_type.hxx +4 -4
- data/ext/couchbase/tracing/constants.hxx +261 -0
- data/ext/couchbase/tracing/noop_tracer.hxx +50 -0
- data/ext/couchbase/tracing/request_tracer.hxx +77 -0
- data/ext/couchbase/tracing/threshold_logging_options.hxx +64 -0
- data/ext/couchbase/tracing/threshold_logging_tracer.hxx +366 -0
- data/ext/couchbase/utils/byteswap.hxx +1 -1
- data/ext/couchbase/utils/connection_string.hxx +21 -1
- data/ext/couchbase/utils/name_codec.hxx +41 -0
- data/ext/couchbase/utils/url_codec.hxx +236 -0
- data/ext/couchbase/version.hxx +1 -1
- data/ext/test/CMakeLists.txt +1 -0
- data/ext/test/test_native_trivial_query.cxx +60 -0
- data/ext/third_party/hdr_histogram_c/CMakeLists.txt +84 -0
- data/ext/third_party/hdr_histogram_c/COPYING.txt +121 -0
- data/ext/third_party/hdr_histogram_c/LICENSE.txt +41 -0
- data/ext/third_party/hdr_histogram_c/config.cmake.in +6 -0
- data/ext/third_party/hdr_histogram_c/src/CMakeLists.txt +83 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_atomic.h +146 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_encoding.c +322 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_encoding.h +79 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_endian.h +116 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram.c +1196 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram.h +516 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log.c +1290 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log.h +236 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log_no_op.c +171 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_interval_recorder.c +227 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_interval_recorder.h +109 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_malloc.h +19 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_tests.h +22 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_thread.c +108 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_thread.h +55 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_time.c +98 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_time.h +49 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_writer_reader_phaser.c +143 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_writer_reader_phaser.h +51 -0
- data/lib/couchbase/cluster.rb +1 -0
- data/lib/couchbase/errors.rb +3 -0
- data/lib/couchbase/libcouchbase.bundle +0 -0
- data/lib/couchbase/management/analytics_index_manager.rb +920 -226
- data/lib/couchbase/management/bucket_manager.rb +207 -69
- data/lib/couchbase/management/collection_manager.rb +173 -61
- data/lib/couchbase/management/query_index_manager.rb +357 -169
- data/lib/couchbase/options.rb +75 -3
- data/lib/couchbase/scope.rb +102 -0
- data/lib/couchbase/utils/time.rb +4 -0
- data/lib/couchbase/version.rb +6 -6
- metadata +48 -5
@@ -0,0 +1,64 @@
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright 2021 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
|
+
#pragma once
|
19
|
+
|
20
|
+
#include <chrono>
|
21
|
+
|
22
|
+
#include <service_type.hxx>
|
23
|
+
|
24
|
+
namespace couchbase::tracing
|
25
|
+
{
|
26
|
+
struct threshold_logging_options {
|
27
|
+
std::chrono::milliseconds orphaned_emit_interval{ std::chrono::seconds{ 10 } };
|
28
|
+
std::size_t orphaned_sample_size{ 64 };
|
29
|
+
|
30
|
+
std::chrono::milliseconds threshold_emit_interval{ std::chrono::seconds{ 10 } };
|
31
|
+
std::size_t threshold_sample_size{ 64 };
|
32
|
+
std::chrono::milliseconds key_value_threshold{ 500 };
|
33
|
+
std::chrono::milliseconds query_threshold{ 1'000 };
|
34
|
+
std::chrono::milliseconds view_threshold{ 1'000 };
|
35
|
+
std::chrono::milliseconds search_threshold{ 1'000 };
|
36
|
+
std::chrono::milliseconds analytics_threshold{ 1'000 };
|
37
|
+
std::chrono::milliseconds management_threshold{ 1'000 };
|
38
|
+
|
39
|
+
[[nodiscard]] std::chrono::milliseconds threshold_for_service(service_type service) const
|
40
|
+
{
|
41
|
+
switch (service) {
|
42
|
+
case service_type::key_value:
|
43
|
+
return key_value_threshold;
|
44
|
+
|
45
|
+
case service_type::query:
|
46
|
+
return query_threshold;
|
47
|
+
|
48
|
+
case service_type::analytics:
|
49
|
+
return analytics_threshold;
|
50
|
+
|
51
|
+
case service_type::search:
|
52
|
+
return search_threshold;
|
53
|
+
|
54
|
+
case service_type::view:
|
55
|
+
return view_threshold;
|
56
|
+
|
57
|
+
case service_type::management:
|
58
|
+
return management_threshold;
|
59
|
+
}
|
60
|
+
return {};
|
61
|
+
}
|
62
|
+
};
|
63
|
+
|
64
|
+
} // namespace couchbase::tracing
|
@@ -0,0 +1,366 @@
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright 2021 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
|
+
#pragma once
|
19
|
+
|
20
|
+
#include <chrono>
|
21
|
+
|
22
|
+
#include <tao/json.hpp>
|
23
|
+
|
24
|
+
#include "request_tracer.hxx"
|
25
|
+
#include "threshold_logging_options.hxx"
|
26
|
+
#include "version.hxx"
|
27
|
+
|
28
|
+
namespace couchbase::tracing
|
29
|
+
{
|
30
|
+
namespace impl
|
31
|
+
{
|
32
|
+
struct reported_span {
|
33
|
+
std::chrono::milliseconds duration;
|
34
|
+
tao::json::value payload;
|
35
|
+
|
36
|
+
bool operator<(const reported_span& other) const
|
37
|
+
{
|
38
|
+
return duration < other.duration;
|
39
|
+
}
|
40
|
+
};
|
41
|
+
|
42
|
+
template<typename T>
|
43
|
+
class fixed_queue : private std::priority_queue<T>
|
44
|
+
{
|
45
|
+
private:
|
46
|
+
std::size_t capacity_{};
|
47
|
+
|
48
|
+
public:
|
49
|
+
explicit fixed_queue(std::size_t capacity)
|
50
|
+
: std::priority_queue<T>()
|
51
|
+
, capacity_(capacity)
|
52
|
+
{
|
53
|
+
}
|
54
|
+
|
55
|
+
using std::priority_queue<T>::pop;
|
56
|
+
using std::priority_queue<T>::size;
|
57
|
+
using std::priority_queue<T>::empty;
|
58
|
+
using std::priority_queue<T>::top;
|
59
|
+
|
60
|
+
void emplace(const T&& item)
|
61
|
+
{
|
62
|
+
std::priority_queue<T>::emplace(item);
|
63
|
+
if (size() > capacity_) {
|
64
|
+
pop();
|
65
|
+
}
|
66
|
+
}
|
67
|
+
};
|
68
|
+
|
69
|
+
using fixed_span_queue = fixed_queue<reported_span>;
|
70
|
+
} // namespace impl
|
71
|
+
|
72
|
+
class threshold_logging_tracer;
|
73
|
+
|
74
|
+
class threshold_logging_span : public request_span
|
75
|
+
{
|
76
|
+
private:
|
77
|
+
std::chrono::system_clock::time_point start_{ std::chrono::system_clock::now() };
|
78
|
+
std::string id_{ uuid::to_string(uuid::random()) };
|
79
|
+
std::map<std::string, std::uint64_t> integer_tags_{};
|
80
|
+
std::map<std::string, std::string> string_tags_{
|
81
|
+
{ attributes::system, "couchbase" },
|
82
|
+
{ attributes::span_kind, "client" },
|
83
|
+
{ attributes::component, couchbase::sdk_id() },
|
84
|
+
};
|
85
|
+
std::chrono::milliseconds duration_{ 0 };
|
86
|
+
std::uint64_t last_server_duration_us_{ 0 };
|
87
|
+
std::uint64_t total_server_duration_us_{ 0 };
|
88
|
+
|
89
|
+
std::string name_;
|
90
|
+
threshold_logging_tracer* tracer_;
|
91
|
+
|
92
|
+
public:
|
93
|
+
threshold_logging_span(const std::string& name, threshold_logging_tracer* tracer)
|
94
|
+
: request_span(name)
|
95
|
+
, tracer_{ tracer }
|
96
|
+
{
|
97
|
+
}
|
98
|
+
|
99
|
+
void add_tag(const std::string& name, std::uint64_t value) override
|
100
|
+
{
|
101
|
+
if (name == tracing::attributes::server_duration) {
|
102
|
+
last_server_duration_us_ = value;
|
103
|
+
total_server_duration_us_ += value;
|
104
|
+
}
|
105
|
+
integer_tags_.try_emplace(name, value);
|
106
|
+
}
|
107
|
+
|
108
|
+
void add_tag(const std::string& name, const std::string& value) override
|
109
|
+
{
|
110
|
+
string_tags_.try_emplace(name, value);
|
111
|
+
}
|
112
|
+
|
113
|
+
void end() override;
|
114
|
+
|
115
|
+
[[nodiscard]] const auto& string_tags() const
|
116
|
+
{
|
117
|
+
return string_tags_;
|
118
|
+
}
|
119
|
+
|
120
|
+
[[nodiscard]] std::chrono::milliseconds duration() const
|
121
|
+
{
|
122
|
+
return duration_;
|
123
|
+
}
|
124
|
+
|
125
|
+
[[nodiscard]] std::uint64_t last_server_duration_us() const
|
126
|
+
{
|
127
|
+
return last_server_duration_us_;
|
128
|
+
}
|
129
|
+
|
130
|
+
[[nodiscard]] std::uint64_t total_server_duration_us() const
|
131
|
+
{
|
132
|
+
return total_server_duration_us_;
|
133
|
+
}
|
134
|
+
|
135
|
+
[[nodiscard]] bool orphan() const
|
136
|
+
{
|
137
|
+
return string_tags_.find(tracing::attributes::orphan) != string_tags_.end();
|
138
|
+
}
|
139
|
+
|
140
|
+
[[nodiscard]] bool is_key_value() const
|
141
|
+
{
|
142
|
+
auto service_tag = string_tags_.find(tracing::attributes::service);
|
143
|
+
if (service_tag == string_tags_.end()) {
|
144
|
+
return false;
|
145
|
+
}
|
146
|
+
return service_tag->second == tracing::service::key_value;
|
147
|
+
}
|
148
|
+
|
149
|
+
[[nodiscard]] std::optional<service_type> service() const
|
150
|
+
{
|
151
|
+
auto service_tag = string_tags_.find(tracing::attributes::service);
|
152
|
+
if (service_tag == string_tags_.end()) {
|
153
|
+
return {};
|
154
|
+
}
|
155
|
+
const auto& service_name = service_tag->second;
|
156
|
+
if (service_name == tracing::service::key_value) {
|
157
|
+
return service_type::key_value;
|
158
|
+
}
|
159
|
+
if (service_name == tracing::service::query) {
|
160
|
+
return service_type::query;
|
161
|
+
}
|
162
|
+
if (service_name == tracing::service::view) {
|
163
|
+
return service_type::view;
|
164
|
+
}
|
165
|
+
if (service_name == tracing::service::search) {
|
166
|
+
return service_type::search;
|
167
|
+
}
|
168
|
+
if (service_name == tracing::service::analytics) {
|
169
|
+
return service_type::analytics;
|
170
|
+
}
|
171
|
+
if (service_name == tracing::service::management) {
|
172
|
+
return service_type::management;
|
173
|
+
}
|
174
|
+
return {};
|
175
|
+
}
|
176
|
+
};
|
177
|
+
|
178
|
+
class threshold_logging_tracer : public request_tracer
|
179
|
+
{
|
180
|
+
private:
|
181
|
+
asio::steady_timer emit_orphan_report_;
|
182
|
+
asio::steady_timer emit_threshold_report_;
|
183
|
+
threshold_logging_options options_;
|
184
|
+
impl::fixed_span_queue orphan_queue_;
|
185
|
+
std::map<service_type, impl::fixed_span_queue> threshold_queues_{};
|
186
|
+
|
187
|
+
void add_orphan(threshold_logging_span* span)
|
188
|
+
{
|
189
|
+
orphan_queue_.emplace(convert(span));
|
190
|
+
}
|
191
|
+
|
192
|
+
void check_threshold(threshold_logging_span* span)
|
193
|
+
{
|
194
|
+
auto service = span->service();
|
195
|
+
if (!service.has_value()) {
|
196
|
+
return;
|
197
|
+
}
|
198
|
+
if (span->duration() > options_.threshold_for_service(service.value())) {
|
199
|
+
auto queue = threshold_queues_.find(service.value());
|
200
|
+
if (queue != threshold_queues_.end()) {
|
201
|
+
queue->second.emplace(convert(span));
|
202
|
+
}
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
impl::reported_span convert(threshold_logging_span* span)
|
207
|
+
{
|
208
|
+
tao::json::value entry{ { "operation_name", span->name() },
|
209
|
+
{ "total_duration_us", std::chrono::duration_cast<std::chrono::microseconds>(span->duration()).count() } };
|
210
|
+
if (span->is_key_value()) {
|
211
|
+
entry["last_server_duration_us"] = span->last_server_duration_us();
|
212
|
+
entry["total_server_duration_us"] = span->total_server_duration_us();
|
213
|
+
}
|
214
|
+
|
215
|
+
const auto& tags = span->string_tags();
|
216
|
+
auto pair = tags.find(attributes::operation_id);
|
217
|
+
if (pair != tags.end()) {
|
218
|
+
entry["last_operation_id"] = pair->second;
|
219
|
+
}
|
220
|
+
|
221
|
+
pair = tags.find(attributes::local_id);
|
222
|
+
if (pair != tags.end()) {
|
223
|
+
entry["last_local_id"] = pair->second;
|
224
|
+
}
|
225
|
+
|
226
|
+
pair = tags.find(attributes::local_socket);
|
227
|
+
if (pair != tags.end()) {
|
228
|
+
entry["last_local_socket"] = pair->second;
|
229
|
+
}
|
230
|
+
|
231
|
+
pair = tags.find(attributes::remote_socket);
|
232
|
+
if (pair != tags.end()) {
|
233
|
+
entry["last_remote_socket"] = pair->second;
|
234
|
+
}
|
235
|
+
|
236
|
+
return { span->duration(), std::move(entry) };
|
237
|
+
}
|
238
|
+
|
239
|
+
void log_orphan_report()
|
240
|
+
{
|
241
|
+
if (orphan_queue_.empty()) {
|
242
|
+
return;
|
243
|
+
}
|
244
|
+
auto queue = impl::fixed_span_queue(options_.orphaned_sample_size);
|
245
|
+
std::swap(orphan_queue_, queue);
|
246
|
+
tao::json::value report
|
247
|
+
{
|
248
|
+
{ "count", queue.size() },
|
249
|
+
#if BACKEND_DEBUG_BUILD
|
250
|
+
{ "emit_interval_ms", options_.orphaned_emit_interval.count() }, { "sample_size", options_.orphaned_sample_size },
|
251
|
+
#endif
|
252
|
+
};
|
253
|
+
tao::json::value entries = tao::json::empty_array;
|
254
|
+
while (!queue.empty()) {
|
255
|
+
entries.emplace_back(queue.top().payload);
|
256
|
+
queue.pop();
|
257
|
+
}
|
258
|
+
report["top"] = entries;
|
259
|
+
spdlog::warn("Orphan responses observed: {}", tao::json::to_string(report));
|
260
|
+
}
|
261
|
+
|
262
|
+
void log_threshold_report()
|
263
|
+
{
|
264
|
+
for (auto& [service, threshold_queue] : threshold_queues_) {
|
265
|
+
if (threshold_queue.empty()) {
|
266
|
+
continue;
|
267
|
+
}
|
268
|
+
auto queue = impl::fixed_span_queue(options_.threshold_sample_size);
|
269
|
+
std::swap(threshold_queue, queue);
|
270
|
+
tao::json::value report
|
271
|
+
{
|
272
|
+
{ "count", queue.size() }, { "service", fmt::format("{}", service) },
|
273
|
+
#if BACKEND_DEBUG_BUILD
|
274
|
+
{ "emit_interval_ms", options_.threshold_emit_interval.count() }, { "sample_size", options_.threshold_sample_size },
|
275
|
+
{ "threshold_ms",
|
276
|
+
std::chrono::duration_cast<std::chrono::microseconds>(options_.threshold_for_service(service)).count() },
|
277
|
+
#endif
|
278
|
+
};
|
279
|
+
tao::json::value entries = tao::json::empty_array;
|
280
|
+
while (!queue.empty()) {
|
281
|
+
entries.emplace_back(queue.top().payload);
|
282
|
+
queue.pop();
|
283
|
+
}
|
284
|
+
report["top"] = entries;
|
285
|
+
spdlog::warn("Operations over threshold: {}", tao::json::to_string(report));
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
void rearm_orphan_reporter()
|
290
|
+
{
|
291
|
+
emit_orphan_report_.expires_after(options_.orphaned_emit_interval);
|
292
|
+
emit_orphan_report_.async_wait([this](std::error_code ec) {
|
293
|
+
if (ec == asio::error::operation_aborted) {
|
294
|
+
return;
|
295
|
+
}
|
296
|
+
log_orphan_report();
|
297
|
+
rearm_orphan_reporter();
|
298
|
+
});
|
299
|
+
}
|
300
|
+
|
301
|
+
void rearm_threshold_reporter()
|
302
|
+
{
|
303
|
+
emit_threshold_report_.expires_after(options_.threshold_emit_interval);
|
304
|
+
emit_threshold_report_.async_wait([this](std::error_code ec) {
|
305
|
+
if (ec == asio::error::operation_aborted) {
|
306
|
+
return;
|
307
|
+
}
|
308
|
+
log_threshold_report();
|
309
|
+
rearm_threshold_reporter();
|
310
|
+
});
|
311
|
+
}
|
312
|
+
|
313
|
+
public:
|
314
|
+
threshold_logging_tracer(asio::io_context& ctx, threshold_logging_options options)
|
315
|
+
: request_tracer()
|
316
|
+
, emit_orphan_report_(ctx)
|
317
|
+
, emit_threshold_report_(ctx)
|
318
|
+
, options_{ options }
|
319
|
+
, orphan_queue_{ options_.orphaned_sample_size }
|
320
|
+
{
|
321
|
+
threshold_queues_.emplace(service_type::key_value, options_.threshold_sample_size);
|
322
|
+
threshold_queues_.emplace(service_type::query, options_.threshold_sample_size);
|
323
|
+
threshold_queues_.emplace(service_type::view, options_.threshold_sample_size);
|
324
|
+
threshold_queues_.emplace(service_type::search, options_.threshold_sample_size);
|
325
|
+
threshold_queues_.emplace(service_type::analytics, options_.threshold_sample_size);
|
326
|
+
threshold_queues_.emplace(service_type::management, options_.threshold_sample_size);
|
327
|
+
}
|
328
|
+
|
329
|
+
void start()
|
330
|
+
{
|
331
|
+
rearm_orphan_reporter();
|
332
|
+
rearm_threshold_reporter();
|
333
|
+
}
|
334
|
+
|
335
|
+
~threshold_logging_tracer() override
|
336
|
+
{
|
337
|
+
emit_orphan_report_.cancel();
|
338
|
+
emit_threshold_report_.cancel();
|
339
|
+
log_orphan_report();
|
340
|
+
log_threshold_report();
|
341
|
+
}
|
342
|
+
|
343
|
+
request_span* start_span(std::string name, request_span* /* parent */) override
|
344
|
+
{
|
345
|
+
return new threshold_logging_span(name, this);
|
346
|
+
}
|
347
|
+
|
348
|
+
void report(threshold_logging_span* span)
|
349
|
+
{
|
350
|
+
if (span->orphan()) {
|
351
|
+
add_orphan(span);
|
352
|
+
} else {
|
353
|
+
check_threshold(span);
|
354
|
+
}
|
355
|
+
}
|
356
|
+
};
|
357
|
+
|
358
|
+
void
|
359
|
+
threshold_logging_span::end()
|
360
|
+
{
|
361
|
+
duration_ = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start_);
|
362
|
+
tracer_->report(this);
|
363
|
+
delete this;
|
364
|
+
}
|
365
|
+
|
366
|
+
} // namespace couchbase::tracing
|
@@ -357,6 +357,26 @@ extract_options(connection_string& connstr)
|
|
357
357
|
} else if (param.second == "false" || param.second == "no" || param.second == "off") {
|
358
358
|
connstr.options.enable_compression = false;
|
359
359
|
}
|
360
|
+
} else if (param.first == "enable_tracing") {
|
361
|
+
/**
|
362
|
+
* true - use threshold_logging_tracer
|
363
|
+
* false - use noop_tracer
|
364
|
+
*/
|
365
|
+
if (param.second == "true" || param.second == "yes" || param.second == "on") {
|
366
|
+
connstr.options.enable_tracing = true;
|
367
|
+
} else if (param.second == "false" || param.second == "no" || param.second == "off") {
|
368
|
+
connstr.options.enable_tracing = false;
|
369
|
+
}
|
370
|
+
} else if (param.first == "enable_metrics") {
|
371
|
+
/**
|
372
|
+
* true - use logging_meter
|
373
|
+
* false - use noop_meter
|
374
|
+
*/
|
375
|
+
if (param.second == "true" || param.second == "yes" || param.second == "on") {
|
376
|
+
connstr.options.enable_metrics = true;
|
377
|
+
} else if (param.second == "false" || param.second == "no" || param.second == "off") {
|
378
|
+
connstr.options.enable_metrics = false;
|
379
|
+
}
|
360
380
|
} else {
|
361
381
|
spdlog::warn(R"(unknown parameter "{}" in connection string (value "{}"))", param.first, param.second);
|
362
382
|
}
|
@@ -388,7 +408,7 @@ parse_connection_string(const std::string& input)
|
|
388
408
|
try {
|
389
409
|
connection_string::node node{};
|
390
410
|
tao::json::pegtl::parse<priv::grammar, priv::action>(in, res, node);
|
391
|
-
} catch (tao::json::pegtl::parse_error& e) {
|
411
|
+
} catch (const tao::json::pegtl::parse_error& e) {
|
392
412
|
for (const auto& position : e.positions()) {
|
393
413
|
if (position.source == __FUNCTION__) {
|
394
414
|
res.error = fmt::format(
|