couchbase 3.5.7 → 3.6.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 +1 -1
- data/ext/cache/extconf_include.rb +3 -3
- data/ext/cache/mozilla-ca-bundle.crt +3 -165
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/CMakeLists.txt +14 -10
- data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy.cc +7 -4
- data/ext/couchbase/CMakeLists.txt +12 -1
- data/ext/couchbase/cmake/Profiler.cmake +15 -0
- data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +2 -2
- data/ext/couchbase/cmake/couchbase_cxx_client.pc.in +1 -1
- data/ext/couchbase/core/app_telemetry_address.cxx +55 -0
- data/ext/couchbase/core/app_telemetry_address.hxx +39 -0
- data/ext/couchbase/core/app_telemetry_meter.cxx +753 -0
- data/ext/couchbase/core/app_telemetry_meter.hxx +198 -0
- data/ext/couchbase/core/app_telemetry_reporter.cxx +895 -0
- data/ext/couchbase/core/app_telemetry_reporter.hxx +59 -0
- data/ext/couchbase/core/bucket.cxx +77 -35
- data/ext/couchbase/core/bucket.hxx +17 -10
- data/ext/couchbase/core/cluster.cxx +54 -16
- data/ext/couchbase/core/cluster_credentials.cxx +27 -0
- data/ext/couchbase/core/cluster_credentials.hxx +36 -0
- data/ext/couchbase/core/cluster_options.hxx +12 -0
- data/ext/couchbase/core/collections_component.cxx +7 -5
- data/ext/couchbase/core/http_component.cxx +6 -0
- data/ext/couchbase/core/impl/binary_collection.cxx +4 -0
- data/ext/couchbase/core/impl/bucket_manager.cxx +2 -0
- data/ext/couchbase/core/impl/cluster.cxx +9 -0
- data/ext/couchbase/core/impl/collection.cxx +2 -0
- data/ext/couchbase/core/impl/error.cxx +1 -0
- data/ext/couchbase/core/impl/logger.cxx +51 -0
- data/ext/couchbase/core/impl/replica_utils.cxx +1 -1
- data/ext/couchbase/core/impl/transaction_get_multi_replicas_from_preferred_server_group_spec.cxx +32 -0
- data/ext/couchbase/core/impl/transaction_get_multi_spec.cxx +30 -0
- data/ext/couchbase/core/impl/transaction_op_error_category.cxx +2 -0
- data/ext/couchbase/core/io/config_tracker.cxx +6 -6
- data/ext/couchbase/core/io/http_command.hxx +35 -11
- data/ext/couchbase/core/io/http_session.cxx +10 -0
- data/ext/couchbase/core/io/http_session.hxx +4 -0
- data/ext/couchbase/core/io/http_session_manager.hxx +83 -34
- data/ext/couchbase/core/io/mcbp_command.hxx +41 -2
- data/ext/couchbase/core/io/mcbp_session.cxx +52 -19
- data/ext/couchbase/core/io/mcbp_session.hxx +3 -0
- data/ext/couchbase/core/logger/logger.cxx +46 -0
- data/ext/couchbase/core/logger/logger.hxx +41 -1
- data/ext/couchbase/core/management/bucket_settings.hxx +1 -0
- data/ext/couchbase/core/management/bucket_settings_json.hxx +4 -0
- data/ext/couchbase/core/meta/features.hxx +32 -0
- data/ext/couchbase/core/operations/document_analytics.cxx +9 -9
- data/ext/couchbase/core/operations/document_append.cxx +1 -0
- data/ext/couchbase/core/operations/document_append.hxx +1 -0
- data/ext/couchbase/core/operations/document_get_all_replicas.hxx +10 -2
- data/ext/couchbase/core/operations/document_lookup_in.cxx +4 -0
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +14 -2
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +4 -0
- data/ext/couchbase/core/operations/document_mutate_in.cxx +4 -0
- data/ext/couchbase/core/operations/document_mutate_in.hxx +1 -0
- data/ext/couchbase/core/operations/document_prepend.cxx +1 -0
- data/ext/couchbase/core/operations/document_prepend.hxx +1 -0
- data/ext/couchbase/core/operations/document_query.cxx +12 -10
- data/ext/couchbase/core/operations/http_noop.cxx +1 -0
- data/ext/couchbase/core/operations/management/bucket_create.cxx +3 -0
- data/ext/couchbase/core/operations/management/bucket_update.cxx +3 -0
- data/ext/couchbase/core/origin.cxx +0 -5
- data/ext/couchbase/core/origin.hxx +2 -11
- data/ext/couchbase/core/platform/random.cc +6 -3
- data/ext/couchbase/core/platform/random.h +2 -2
- data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +9 -0
- data/ext/couchbase/core/timeout_defaults.hxx +4 -0
- data/ext/couchbase/core/topology/configuration.cxx +10 -13
- data/ext/couchbase/core/topology/configuration.hxx +14 -15
- data/ext/couchbase/core/topology/configuration_json.hxx +6 -0
- data/ext/couchbase/core/transactions/async_attempt_context.hxx +22 -2
- data/ext/couchbase/core/transactions/attempt_context.hxx +25 -7
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +688 -238
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +91 -12
- data/ext/couchbase/core/transactions/exceptions.cxx +5 -0
- data/ext/couchbase/core/transactions/exceptions.hxx +20 -0
- data/ext/couchbase/core/transactions/exceptions_fmt.hxx +3 -0
- data/ext/couchbase/core/transactions/forward_compat.cxx +71 -6
- data/ext/couchbase/core/transactions/forward_compat.hxx +45 -59
- data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +616 -0
- data/ext/couchbase/core/transactions/get_multi_orchestrator.hxx +61 -0
- data/ext/couchbase/core/transactions/internal/doc_record.cxx +8 -0
- data/ext/couchbase/core/transactions/internal/doc_record.hxx +16 -5
- data/ext/couchbase/core/transactions/internal/exceptions_internal.hxx +12 -0
- data/ext/couchbase/core/transactions/internal/transaction_context.hxx +13 -0
- data/ext/couchbase/core/transactions/internal/transaction_fields.hxx +1 -0
- data/ext/couchbase/core/transactions/staged_mutation.cxx +277 -96
- data/ext/couchbase/core/transactions/staged_mutation.hxx +28 -76
- data/ext/couchbase/core/transactions/transaction_context.cxx +33 -0
- data/ext/couchbase/core/transactions/transaction_get_multi_mode.hxx +28 -0
- data/ext/couchbase/core/transactions/transaction_get_multi_replicas_from_preferred_server_group_mode.hxx +27 -0
- data/ext/couchbase/core/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +71 -0
- data/ext/couchbase/core/transactions/transaction_get_multi_result.hxx +66 -0
- data/ext/couchbase/core/transactions/transaction_links.hxx +10 -0
- data/ext/couchbase/core/transactions/transactions.cxx +8 -3
- data/ext/couchbase/core/utils/connection_string.cxx +4 -0
- data/ext/couchbase/core/utils/url_codec.cxx +26 -0
- data/ext/couchbase/core/utils/url_codec.hxx +11 -0
- data/ext/couchbase/core/websocket_codec.cxx +647 -0
- data/ext/couchbase/core/websocket_codec.hxx +77 -0
- data/ext/couchbase/couchbase/analytics_options.hxx +70 -6
- data/ext/couchbase/couchbase/application_telemetry_options.hxx +124 -0
- data/ext/couchbase/couchbase/cluster_options.hxx +17 -0
- data/ext/couchbase/couchbase/error_codes.hxx +1 -0
- data/ext/couchbase/couchbase/logger.hxx +16 -0
- data/ext/couchbase/couchbase/management/bucket_settings.hxx +1 -0
- data/ext/couchbase/couchbase/query_options.hxx +70 -6
- data/ext/couchbase/couchbase/transactions/async_attempt_context.hxx +29 -5
- data/ext/couchbase/couchbase/transactions/attempt_context.hxx +24 -7
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_mode.hxx +47 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_options.hxx +44 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_mode.hxx +46 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_options.hxx +48 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +109 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_spec.hxx +47 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +102 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_spec.hxx +45 -0
- data/ext/rcb_buckets.cxx +26 -0
- data/lib/active_support/cache/couchbase_store.rb +1 -1
- data/lib/couchbase/cluster.rb +1 -1
- data/lib/couchbase/collection.rb +1 -1
- data/lib/couchbase/collection_options.rb +2 -2
- data/lib/couchbase/management/analytics_index_manager.rb +4 -4
- data/lib/couchbase/management/bucket_manager.rb +8 -2
- data/lib/couchbase/protostellar/cluster.rb +2 -2
- data/lib/couchbase/protostellar/collection.rb +1 -1
- data/lib/couchbase/protostellar/management/collection_query_index_manager.rb +1 -1
- data/lib/couchbase/protostellar/request_generator/admin/bucket.rb +4 -4
- data/lib/couchbase/protostellar/request_generator/admin/collection.rb +6 -6
- data/lib/couchbase/protostellar/request_generator/admin/query.rb +13 -13
- data/lib/couchbase/protostellar/request_generator/kv.rb +25 -25
- data/lib/couchbase/protostellar/request_generator/query.rb +4 -4
- data/lib/couchbase/protostellar/request_generator/search.rb +25 -25
- data/lib/couchbase/protostellar/response_converter/search.rb +1 -1
- data/lib/couchbase/protostellar/retry/reason.rb +1 -1
- data/lib/couchbase/protostellar/timeouts.rb +1 -1
- data/lib/couchbase/scope.rb +1 -1
- data/lib/couchbase/transcoder_flags.rb +1 -1
- data/lib/couchbase/utils/stdlib_logger_adapter.rb +1 -1
- data/lib/couchbase/version.rb +1 -1
- metadata +47 -19
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/COPYING +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/cmake/SnappyConfig.cmake.in +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/cmake/config.h.in +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-c.cc +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-c.h +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-internal.h +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-sinksource.cc +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-sinksource.h +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-stubs-internal.cc +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-stubs-internal.h +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-stubs-public.h.in +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy.h +0 -0
@@ -19,6 +19,7 @@
|
|
19
19
|
|
20
20
|
#include <couchbase/build_config.hxx>
|
21
21
|
|
22
|
+
#include "core/app_telemetry_meter.hxx"
|
22
23
|
#include "core/config_listener.hxx"
|
23
24
|
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
24
25
|
#include "core/columnar/bootstrap_notification_subscriber.hxx"
|
@@ -74,6 +75,11 @@ public:
|
|
74
75
|
meter_ = std::move(meter);
|
75
76
|
}
|
76
77
|
|
78
|
+
void set_app_telemetry_meter(std::shared_ptr<core::app_telemetry_meter> app_telemetry_meter)
|
79
|
+
{
|
80
|
+
app_telemetry_meter_ = std::move(app_telemetry_meter);
|
81
|
+
}
|
82
|
+
|
77
83
|
auto configuration_capabilities() const -> configuration_capabilities
|
78
84
|
{
|
79
85
|
std::scoped_lock config_lock(config_mutex_);
|
@@ -203,7 +209,7 @@ public:
|
|
203
209
|
std::uint16_t port = node.port_or(options_.network, type, options_.enable_tls, 0);
|
204
210
|
if (port != 0) {
|
205
211
|
const auto& hostname = node.hostname_for(options_.network);
|
206
|
-
auto session = create_session(type, credentials, hostname, port);
|
212
|
+
auto session = create_session(type, credentials, hostname, port, node.node_uuid);
|
207
213
|
if (session->is_connected()) {
|
208
214
|
std::scoped_lock lock(sessions_mutex_);
|
209
215
|
busy_sessions_[type].push_back(session);
|
@@ -217,11 +223,17 @@ public:
|
|
217
223
|
request,
|
218
224
|
tracer_,
|
219
225
|
meter_,
|
226
|
+
app_telemetry_meter_,
|
220
227
|
options_.default_timeout_for(request.type),
|
221
228
|
dispatch_timeout_);
|
222
229
|
#else
|
223
230
|
auto cmd = std::make_shared<operations::http_command<operations::http_noop_request>>(
|
224
|
-
ctx_,
|
231
|
+
ctx_,
|
232
|
+
request,
|
233
|
+
tracer_,
|
234
|
+
meter_,
|
235
|
+
app_telemetry_meter_,
|
236
|
+
options_.default_timeout_for(request.type));
|
225
237
|
#endif
|
226
238
|
|
227
239
|
cmd->start([start = std::chrono::steady_clock::now(),
|
@@ -283,6 +295,7 @@ public:
|
|
283
295
|
error });
|
284
296
|
self->check_in(type, cmd->session_);
|
285
297
|
});
|
298
|
+
|
286
299
|
cmd->set_command_session(session);
|
287
300
|
if (!session->is_connected()) {
|
288
301
|
connect_then_send(session, cmd, {}, true);
|
@@ -300,10 +313,13 @@ public:
|
|
300
313
|
const std::string& undesired_node = {})
|
301
314
|
-> std::pair<std::error_code, std::shared_ptr<http_session>>
|
302
315
|
{
|
316
|
+
std::string node_uuid{};
|
317
|
+
|
303
318
|
if (preferred_node.empty() && !undesired_node.empty()) {
|
304
|
-
auto [hostname, port] = pick_random_node(type, undesired_node);
|
319
|
+
auto [hostname, port, uuid] = pick_random_node(type, undesired_node);
|
305
320
|
if (port != 0) {
|
306
321
|
preferred_node = fmt::format("{}:{}", hostname, port);
|
322
|
+
node_uuid = uuid;
|
307
323
|
}
|
308
324
|
}
|
309
325
|
|
@@ -343,7 +359,7 @@ public:
|
|
343
359
|
break;
|
344
360
|
}
|
345
361
|
} else {
|
346
|
-
session = create_session(type, credentials, hostname, port);
|
362
|
+
session = create_session(type, credentials, hostname, port, node_uuid);
|
347
363
|
break;
|
348
364
|
}
|
349
365
|
}
|
@@ -355,12 +371,12 @@ public:
|
|
355
371
|
session.reset();
|
356
372
|
}
|
357
373
|
if (!session) {
|
358
|
-
auto [hostname, port] =
|
374
|
+
auto [hostname, port, uuid] =
|
359
375
|
preferred_node.empty() ? next_node(type) : lookup_node(type, preferred_node);
|
360
376
|
if (port == 0) {
|
361
377
|
return { errc::common::service_not_available, nullptr };
|
362
378
|
}
|
363
|
-
session = create_session(type, credentials, hostname, port);
|
379
|
+
session = create_session(type, credentials, hostname, port, uuid);
|
364
380
|
}
|
365
381
|
if (session->is_connected()) {
|
366
382
|
busy_sessions_[type].push_back(session);
|
@@ -472,13 +488,19 @@ public:
|
|
472
488
|
request,
|
473
489
|
tracer_,
|
474
490
|
meter_,
|
491
|
+
app_telemetry_meter_,
|
475
492
|
options_.default_timeout_for(request.type),
|
476
493
|
dispatch_timeout_);
|
477
494
|
cmd->start([self = shared_from_this(), cmd, handler = std::forward<Handler>(handler)](
|
478
495
|
error_union err, io::http_response&& msg) mutable {
|
479
496
|
#else
|
480
497
|
auto cmd = std::make_shared<operations::http_command<Request>>(
|
481
|
-
ctx_,
|
498
|
+
ctx_,
|
499
|
+
request,
|
500
|
+
tracer_,
|
501
|
+
meter_,
|
502
|
+
app_telemetry_meter_,
|
503
|
+
options_.default_timeout_for(request.type));
|
482
504
|
cmd->start([self = shared_from_this(), cmd, handler = std::forward<Handler>(handler)](
|
483
505
|
std::error_code ec, io::http_response&& msg) mutable {
|
484
506
|
#endif
|
@@ -571,15 +593,15 @@ public:
|
|
571
593
|
|
572
594
|
// stop this session and create a new one w/ new hostname + port
|
573
595
|
session->stop();
|
574
|
-
auto [hostname, port] = preferred_node.empty()
|
575
|
-
|
576
|
-
|
596
|
+
auto [hostname, port, node_uuid] = preferred_node.empty()
|
597
|
+
? self->next_node(session->type())
|
598
|
+
: self->lookup_node(session->type(), preferred_node);
|
577
599
|
if (port == 0) {
|
578
600
|
cb(errc::common::service_not_available, {});
|
579
601
|
return;
|
580
602
|
}
|
581
603
|
auto new_session =
|
582
|
-
self->create_session(session->type(), session->credentials(), hostname, port);
|
604
|
+
self->create_session(session->type(), session->credentials(), hostname, port, node_uuid);
|
583
605
|
if (new_session->is_connected()) {
|
584
606
|
{
|
585
607
|
const std::scoped_lock inner_lock(self->sessions_mutex_);
|
@@ -679,15 +701,15 @@ private:
|
|
679
701
|
}
|
680
702
|
// stop this session and create a new one w/ new hostname + port
|
681
703
|
session->stop();
|
682
|
-
auto [hostname, port] = preferred_node.empty()
|
683
|
-
|
684
|
-
|
704
|
+
auto [hostname, port, node_uuid] = preferred_node.empty()
|
705
|
+
? self->next_node(session->type())
|
706
|
+
: self->lookup_node(session->type(), preferred_node);
|
685
707
|
if (port == 0) {
|
686
708
|
cmd->invoke_handler(errc::common::service_not_available, {});
|
687
709
|
return;
|
688
710
|
}
|
689
711
|
auto new_session =
|
690
|
-
self->create_session(session->type(), session->credentials(), hostname, port);
|
712
|
+
self->create_session(session->type(), session->credentials(), hostname, port, node_uuid);
|
691
713
|
cmd->set_command_session(new_session);
|
692
714
|
if (new_session->is_connected()) {
|
693
715
|
std::scoped_lock inner_lock(self->sessions_mutex_);
|
@@ -707,13 +729,15 @@ private:
|
|
707
729
|
auto create_session(service_type type,
|
708
730
|
const couchbase::core::cluster_credentials& credentials,
|
709
731
|
const std::string& hostname,
|
710
|
-
std::uint16_t port
|
732
|
+
std::uint16_t port,
|
733
|
+
const std::string& node_uuid) -> std::shared_ptr<http_session>
|
711
734
|
{
|
712
735
|
std::shared_ptr<http_session> session;
|
713
736
|
if (options_.enable_tls) {
|
714
737
|
session = std::make_shared<http_session>(
|
715
738
|
type,
|
716
739
|
client_id_,
|
740
|
+
node_uuid,
|
717
741
|
ctx_,
|
718
742
|
tls_,
|
719
743
|
credentials,
|
@@ -724,6 +748,7 @@ private:
|
|
724
748
|
session = std::make_shared<http_session>(
|
725
749
|
type,
|
726
750
|
client_id_,
|
751
|
+
node_uuid,
|
727
752
|
ctx_,
|
728
753
|
credentials,
|
729
754
|
hostname,
|
@@ -763,6 +788,7 @@ private:
|
|
763
788
|
request,
|
764
789
|
tracer_,
|
765
790
|
meter_,
|
791
|
+
app_telemetry_meter_,
|
766
792
|
options_.default_timeout_for(request.type),
|
767
793
|
dispatch_timeout_);
|
768
794
|
cmd->start([self = shared_from_this(), cmd, handler = std::forward<Handler>(handler)](
|
@@ -852,7 +878,7 @@ private:
|
|
852
878
|
}
|
853
879
|
#endif
|
854
880
|
|
855
|
-
auto next_node(service_type type) -> std::
|
881
|
+
auto next_node(service_type type) -> std::tuple<std::string, std::uint16_t, std::string>
|
856
882
|
{
|
857
883
|
std::scoped_lock lock(config_mutex_);
|
858
884
|
auto candidates = config_.nodes.size();
|
@@ -863,10 +889,18 @@ private:
|
|
863
889
|
next_index_ = (next_index_ + 1) % config_.nodes.size();
|
864
890
|
std::uint16_t port = node.port_or(options_.network, type, options_.enable_tls, 0);
|
865
891
|
if (port != 0) {
|
866
|
-
return {
|
892
|
+
return {
|
893
|
+
node.hostname_for(options_.network),
|
894
|
+
port,
|
895
|
+
node.node_uuid,
|
896
|
+
};
|
867
897
|
}
|
868
898
|
}
|
869
|
-
return {
|
899
|
+
return {
|
900
|
+
"",
|
901
|
+
static_cast<std::uint16_t>(0U),
|
902
|
+
"",
|
903
|
+
};
|
870
904
|
}
|
871
905
|
|
872
906
|
auto split_host_port(const std::string& address) -> std::pair<std::string, std::uint16_t>
|
@@ -880,24 +914,30 @@ private:
|
|
880
914
|
return { hostname, port };
|
881
915
|
}
|
882
916
|
|
883
|
-
auto lookup_node(service_type type,
|
884
|
-
|
917
|
+
auto lookup_node(service_type type, const std::string& preferred_node)
|
918
|
+
-> std::tuple<std::string, std::uint16_t, std::string>
|
885
919
|
{
|
886
920
|
std::scoped_lock lock(config_mutex_);
|
887
921
|
auto [hostname, port] = split_host_port(preferred_node);
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
922
|
+
for (const auto& node : config_.nodes) {
|
923
|
+
if (node.hostname_for(options_.network) == hostname &&
|
924
|
+
node.port_or(options_.network, type, options_.enable_tls, 0) == port) {
|
925
|
+
return {
|
926
|
+
hostname,
|
927
|
+
port,
|
928
|
+
node.node_uuid,
|
929
|
+
};
|
930
|
+
}
|
895
931
|
}
|
896
|
-
return {
|
932
|
+
return {
|
933
|
+
"",
|
934
|
+
static_cast<std::uint16_t>(0U),
|
935
|
+
"",
|
936
|
+
};
|
897
937
|
}
|
898
938
|
|
899
|
-
auto pick_random_node(service_type type,
|
900
|
-
|
939
|
+
auto pick_random_node(service_type type, const std::string& undesired_node)
|
940
|
+
-> std::tuple<std::string, std::uint16_t, std::string>
|
901
941
|
{
|
902
942
|
std::vector<topology::configuration::node> candidate_nodes{};
|
903
943
|
{
|
@@ -913,7 +953,11 @@ private:
|
|
913
953
|
|
914
954
|
if (candidate_nodes.empty()) {
|
915
955
|
// Could not find any other nodes
|
916
|
-
return {
|
956
|
+
return {
|
957
|
+
"",
|
958
|
+
static_cast<std::uint16_t>(0U),
|
959
|
+
"",
|
960
|
+
};
|
917
961
|
}
|
918
962
|
|
919
963
|
std::vector<topology::configuration::node> selected{};
|
@@ -922,8 +966,12 @@ private:
|
|
922
966
|
std::back_inserter(selected),
|
923
967
|
1,
|
924
968
|
std::mt19937{ std::random_device{}() });
|
925
|
-
|
926
|
-
|
969
|
+
const auto& first_selected = selected.at(0);
|
970
|
+
return {
|
971
|
+
first_selected.hostname_for(options_.network),
|
972
|
+
first_selected.port_or(options_.network, type, options_.enable_tls, 0),
|
973
|
+
first_selected.node_uuid,
|
974
|
+
};
|
927
975
|
}
|
928
976
|
|
929
977
|
std::string client_id_;
|
@@ -931,6 +979,7 @@ private:
|
|
931
979
|
asio::ssl::context& tls_;
|
932
980
|
std::shared_ptr<tracing::tracer_wrapper> tracer_{ nullptr };
|
933
981
|
std::shared_ptr<metrics::meter_wrapper> meter_{ nullptr };
|
982
|
+
std::shared_ptr<core::app_telemetry_meter> app_telemetry_meter_{ nullptr };
|
934
983
|
cluster_options options_{};
|
935
984
|
|
936
985
|
topology::configuration config_{};
|
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
#pragma once
|
19
19
|
|
20
|
+
#include "core/app_telemetry_meter.hxx"
|
20
21
|
#include "core/document_id_fmt.hxx"
|
21
22
|
#include "core/error_context/key_value_error_map_info.hxx"
|
22
23
|
#include "core/metrics/meter_wrapper.hxx"
|
@@ -146,7 +147,12 @@ struct mcbp_command : public std::enable_shared_from_this<mcbp_command<Manager,
|
|
146
147
|
span_ = nullptr;
|
147
148
|
}
|
148
149
|
if (handler) {
|
150
|
+
const auto& node_uuid = session_ ? session_->node_uuid() : "";
|
151
|
+
auto telemetry_recorder =
|
152
|
+
manager_->app_telemetry_meter()->value_recorder(node_uuid, manager_->name());
|
153
|
+
telemetry_recorder->update_counter(app_telemetry_counter::kv_r_total);
|
149
154
|
if (ec == errc::common::unambiguous_timeout || ec == errc::common::ambiguous_timeout) {
|
155
|
+
telemetry_recorder->update_counter(app_telemetry_counter::kv_r_timedout);
|
150
156
|
auto time_left = deadline.expiry() - std::chrono::steady_clock::now();
|
151
157
|
CB_LOG_TRACE(R"([{}] timeout operation id="{}", {}, key="{}", partition={}, time_left={})",
|
152
158
|
session_ ? session_->log_prefix() : manager_->log_prefix(),
|
@@ -155,6 +161,8 @@ struct mcbp_command : public std::enable_shared_from_this<mcbp_command<Manager,
|
|
155
161
|
request.id,
|
156
162
|
request.partition,
|
157
163
|
time_left);
|
164
|
+
} else if (ec == errc::common::request_canceled) {
|
165
|
+
telemetry_recorder->update_counter(app_telemetry_counter::kv_r_canceled);
|
158
166
|
}
|
159
167
|
handler(ec, std::move(msg));
|
160
168
|
}
|
@@ -267,6 +275,35 @@ struct mcbp_command : public std::enable_shared_from_this<mcbp_command<Manager,
|
|
267
275
|
retry_reason reason,
|
268
276
|
io::mcbp_message&& msg,
|
269
277
|
std::optional<key_value_error_map_info> /* error_info */) mutable {
|
278
|
+
{
|
279
|
+
auto latency = std::chrono::duration_cast<std::chrono::milliseconds>(
|
280
|
+
std::chrono::steady_clock::now() - start);
|
281
|
+
auto category = app_telemetry_latency::kv_retrieval;
|
282
|
+
switch (encoded_request_type::body_type::opcode) {
|
283
|
+
case protocol::client_opcode::upsert:
|
284
|
+
case protocol::client_opcode::insert:
|
285
|
+
case protocol::client_opcode::replace:
|
286
|
+
case protocol::client_opcode::remove:
|
287
|
+
case protocol::client_opcode::increment:
|
288
|
+
case protocol::client_opcode::decrement:
|
289
|
+
case protocol::client_opcode::append:
|
290
|
+
case protocol::client_opcode::prepend:
|
291
|
+
category = app_telemetry_latency::kv_mutation_nondurable;
|
292
|
+
if constexpr (io::mcbp_traits::supports_durability_v<Request>) {
|
293
|
+
if (self->request.durability_level != durability_level::none) {
|
294
|
+
category = app_telemetry_latency::kv_mutation_durable;
|
295
|
+
}
|
296
|
+
}
|
297
|
+
break;
|
298
|
+
default:
|
299
|
+
break;
|
300
|
+
}
|
301
|
+
|
302
|
+
auto telemetry_recorder = self->manager_->app_telemetry_meter()->value_recorder(
|
303
|
+
self->session_->node_uuid(), self->manager_->name());
|
304
|
+
telemetry_recorder->record_latency(category, latency);
|
305
|
+
}
|
306
|
+
|
270
307
|
metrics::metric_attributes attrs{
|
271
308
|
service_type::key_value,
|
272
309
|
self->request.observability_identifier,
|
@@ -279,16 +316,18 @@ struct mcbp_command : public std::enable_shared_from_this<mcbp_command<Manager,
|
|
279
316
|
|
280
317
|
self->retry_backoff.cancel();
|
281
318
|
if (ec == asio::error::operation_aborted) {
|
282
|
-
if (self->span_->uses_tags())
|
319
|
+
if (self->span_->uses_tags()) {
|
283
320
|
self->span_->add_tag(tracing::attributes::orphan, "aborted");
|
321
|
+
}
|
284
322
|
return self->invoke_handler(make_error_code(self->request.retries.idempotent()
|
285
323
|
? errc::common::unambiguous_timeout
|
286
324
|
: errc::common::ambiguous_timeout));
|
287
325
|
}
|
288
326
|
if (ec == errc::common::request_canceled) {
|
289
327
|
if (!self->request.retries.idempotent() && !allows_non_idempotent_retry(reason)) {
|
290
|
-
if (self->span_->uses_tags())
|
328
|
+
if (self->span_->uses_tags()) {
|
291
329
|
self->span_->add_tag(tracing::attributes::orphan, "canceled");
|
330
|
+
}
|
292
331
|
return self->invoke_handler(ec);
|
293
332
|
}
|
294
333
|
return io::retry_orchestrator::maybe_retry(self->manager_, self, reason, ec);
|
@@ -414,10 +414,11 @@ class mcbp_session_impl
|
|
414
414
|
const protocol::client_response<protocol::sasl_list_mechs_response_body> resp(
|
415
415
|
std::move(msg));
|
416
416
|
if (resp.status() != key_value_status_code::success) {
|
417
|
-
auto error_msg =
|
418
|
-
|
419
|
-
|
420
|
-
|
417
|
+
auto error_msg = fmt::format(
|
418
|
+
"unexpected message status during bootstrap: {} (opaque={}, context={})",
|
419
|
+
resp.error_message(),
|
420
|
+
resp.opaque(),
|
421
|
+
resp.error_info() ? resp.error_info()->context() : "");
|
421
422
|
last_bootstrap_error_ = { errc::common::authentication_failure,
|
422
423
|
std::move(error_msg),
|
423
424
|
session_->bootstrap_hostname(),
|
@@ -443,8 +444,11 @@ class mcbp_session_impl
|
|
443
444
|
req.body().sasl_data(sasl_payload);
|
444
445
|
session_->write_and_flush(req.data());
|
445
446
|
} else {
|
446
|
-
auto error_msg =
|
447
|
-
"unable to authenticate: (sasl_code={}, opaque={})",
|
447
|
+
auto error_msg =
|
448
|
+
fmt::format("unable to authenticate: (sasl_code={}, opaque={}, context={})",
|
449
|
+
sasl_code,
|
450
|
+
resp.opaque(),
|
451
|
+
resp.error_info() ? resp.error_info()->context() : "");
|
448
452
|
last_bootstrap_error_ = { errc::common::authentication_failure,
|
449
453
|
std::move(error_msg),
|
450
454
|
session_->bootstrap_hostname(),
|
@@ -453,11 +457,12 @@ class mcbp_session_impl
|
|
453
457
|
return complete(errc::common::authentication_failure);
|
454
458
|
}
|
455
459
|
} else {
|
456
|
-
auto error_msg =
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
460
|
+
auto error_msg = fmt::format(
|
461
|
+
"{} unexpected message status during bootstrap: {} (opaque={}, context={})",
|
462
|
+
session_->log_prefix_,
|
463
|
+
resp.error_message(),
|
464
|
+
resp.opaque(),
|
465
|
+
resp.error_info() ? resp.error_info()->context() : "");
|
461
466
|
last_bootstrap_error_ = { errc::common::authentication_failure,
|
462
467
|
std::move(error_msg),
|
463
468
|
session_->bootstrap_hostname(),
|
@@ -473,10 +478,11 @@ class mcbp_session_impl
|
|
473
478
|
return auth_success();
|
474
479
|
}
|
475
480
|
auto error_msg =
|
476
|
-
fmt::format("unable to authenticate (opcode={}, status={}, opaque={})",
|
481
|
+
fmt::format("unable to authenticate (opcode={}, status={}, opaque={}, context={})",
|
477
482
|
opcode,
|
478
483
|
resp.status(),
|
479
|
-
resp.opaque()
|
484
|
+
resp.opaque(),
|
485
|
+
resp.error_info() ? resp.error_info()->context() : "");
|
480
486
|
last_bootstrap_error_ = { errc::common::authentication_failure,
|
481
487
|
std::move(error_msg),
|
482
488
|
session_->bootstrap_hostname(),
|
@@ -858,19 +864,21 @@ class mcbp_session_impl
|
|
858
864
|
public:
|
859
865
|
mcbp_session_impl() = delete;
|
860
866
|
mcbp_session_impl(std::string_view client_id,
|
867
|
+
std::string_view node_uuid,
|
861
868
|
asio::io_context& ctx,
|
862
869
|
couchbase::core::origin origin,
|
863
870
|
std::shared_ptr<impl::bootstrap_state_listener> state_listener,
|
864
871
|
std::optional<std::string> bucket_name = {},
|
865
872
|
std::vector<protocol::hello_feature> known_features = {})
|
866
873
|
: client_id_(client_id)
|
874
|
+
, node_uuid_(node_uuid)
|
867
875
|
, ctx_(ctx)
|
868
876
|
, resolver_(ctx_)
|
869
877
|
, stream_(std::make_unique<plain_stream_impl>(ctx_))
|
870
878
|
, bootstrap_deadline_(ctx_)
|
871
879
|
, connection_deadline_(ctx_)
|
872
880
|
, retry_backoff_(ctx_)
|
873
|
-
,
|
881
|
+
, ping_timeout_(ctx_)
|
874
882
|
, origin_{ std::move(origin) }
|
875
883
|
, bucket_name_{ std::move(bucket_name) }
|
876
884
|
, supported_features_{ std::move(known_features) }
|
@@ -883,6 +891,7 @@ public:
|
|
883
891
|
}
|
884
892
|
|
885
893
|
mcbp_session_impl(std::string_view client_id,
|
894
|
+
std::string_view node_uuid,
|
886
895
|
asio::io_context& ctx,
|
887
896
|
asio::ssl::context& tls,
|
888
897
|
couchbase::core::origin origin,
|
@@ -890,13 +899,14 @@ public:
|
|
890
899
|
std::optional<std::string> bucket_name = {},
|
891
900
|
std::vector<protocol::hello_feature> known_features = {})
|
892
901
|
: client_id_(client_id)
|
902
|
+
, node_uuid_(node_uuid)
|
893
903
|
, ctx_(ctx)
|
894
904
|
, resolver_(ctx_)
|
895
905
|
, stream_(std::make_unique<tls_stream_impl>(ctx_, tls))
|
896
906
|
, bootstrap_deadline_(ctx_)
|
897
907
|
, connection_deadline_(ctx_)
|
898
908
|
, retry_backoff_(ctx_)
|
899
|
-
,
|
909
|
+
, ping_timeout_(ctx_)
|
900
910
|
, origin_(std::move(origin))
|
901
911
|
, bucket_name_(std::move(bucket_name))
|
902
912
|
, supported_features_(std::move(known_features))
|
@@ -998,8 +1008,8 @@ public:
|
|
998
1008
|
error,
|
999
1009
|
});
|
1000
1010
|
});
|
1001
|
-
|
1002
|
-
|
1011
|
+
ping_timeout_.expires_after(timeout.value_or(origin_.options().key_value_timeout));
|
1012
|
+
ping_timeout_.async_wait(
|
1003
1013
|
[self = this->shared_from_this(), opaque = req.opaque()](std::error_code ec) {
|
1004
1014
|
if (ec == asio::error::operation_aborted) {
|
1005
1015
|
return;
|
@@ -1154,6 +1164,11 @@ public:
|
|
1154
1164
|
return id_;
|
1155
1165
|
}
|
1156
1166
|
|
1167
|
+
[[nodiscard]] auto node_uuid() const -> const std::string&
|
1168
|
+
{
|
1169
|
+
return node_uuid_;
|
1170
|
+
}
|
1171
|
+
|
1157
1172
|
[[nodiscard]] auto is_stopped() const -> bool
|
1158
1173
|
{
|
1159
1174
|
return stopped_;
|
@@ -1194,7 +1209,7 @@ public:
|
|
1194
1209
|
bootstrap_deadline_.cancel();
|
1195
1210
|
connection_deadline_.cancel();
|
1196
1211
|
retry_backoff_.cancel();
|
1197
|
-
|
1212
|
+
ping_timeout_.cancel();
|
1198
1213
|
resolver_.cancel();
|
1199
1214
|
stream_->close([](std::error_code) {
|
1200
1215
|
});
|
@@ -1711,6 +1726,13 @@ private:
|
|
1711
1726
|
if (ec) {
|
1712
1727
|
return stop(retry_reason::node_not_available);
|
1713
1728
|
}
|
1729
|
+
if (node_uuid_.empty() && config_.has_value()) {
|
1730
|
+
for (const auto& node : config_.value().nodes) {
|
1731
|
+
if (node.this_node) {
|
1732
|
+
node_uuid_ = node.node_uuid;
|
1733
|
+
}
|
1734
|
+
}
|
1735
|
+
}
|
1714
1736
|
state_ = diag::endpoint_state::connected;
|
1715
1737
|
const std::scoped_lock lock(pending_buffer_mutex_);
|
1716
1738
|
bootstrapped_ = true;
|
@@ -2020,6 +2042,7 @@ private:
|
|
2020
2042
|
}
|
2021
2043
|
|
2022
2044
|
const std::string client_id_;
|
2045
|
+
std::string node_uuid_;
|
2023
2046
|
const std::string id_{ uuid::to_string(uuid::random()) };
|
2024
2047
|
asio::io_context& ctx_;
|
2025
2048
|
asio::ip::tcp::resolver resolver_;
|
@@ -2027,7 +2050,7 @@ private:
|
|
2027
2050
|
asio::steady_timer bootstrap_deadline_;
|
2028
2051
|
asio::steady_timer connection_deadline_;
|
2029
2052
|
asio::steady_timer retry_backoff_;
|
2030
|
-
asio::steady_timer
|
2053
|
+
asio::steady_timer ping_timeout_;
|
2031
2054
|
couchbase::core::origin origin_;
|
2032
2055
|
std::optional<std::string> bucket_name_;
|
2033
2056
|
mcbp_parser parser_;
|
@@ -2092,12 +2115,14 @@ private:
|
|
2092
2115
|
};
|
2093
2116
|
|
2094
2117
|
mcbp_session::mcbp_session(const std::string& client_id,
|
2118
|
+
const std::string& node_uuid,
|
2095
2119
|
asio::io_context& ctx,
|
2096
2120
|
core::origin origin,
|
2097
2121
|
std::shared_ptr<impl::bootstrap_state_listener> state_listener,
|
2098
2122
|
std::optional<std::string> bucket_name,
|
2099
2123
|
std::vector<protocol::hello_feature> known_features)
|
2100
2124
|
: impl_{ std::make_shared<mcbp_session_impl>(client_id,
|
2125
|
+
node_uuid,
|
2101
2126
|
ctx,
|
2102
2127
|
std::move(origin),
|
2103
2128
|
std::move(state_listener),
|
@@ -2107,6 +2132,7 @@ mcbp_session::mcbp_session(const std::string& client_id,
|
|
2107
2132
|
}
|
2108
2133
|
|
2109
2134
|
mcbp_session::mcbp_session(const std::string& client_id,
|
2135
|
+
const std::string& node_uuid,
|
2110
2136
|
asio::io_context& ctx,
|
2111
2137
|
asio::ssl::context& tls,
|
2112
2138
|
core::origin origin,
|
@@ -2114,6 +2140,7 @@ mcbp_session::mcbp_session(const std::string& client_id,
|
|
2114
2140
|
std::optional<std::string> bucket_name,
|
2115
2141
|
std::vector<protocol::hello_feature> known_features)
|
2116
2142
|
: impl_{ std::make_shared<mcbp_session_impl>(client_id,
|
2143
|
+
node_uuid,
|
2117
2144
|
ctx,
|
2118
2145
|
tls,
|
2119
2146
|
std::move(origin),
|
@@ -2177,6 +2204,12 @@ mcbp_session::id() const -> const std::string&
|
|
2177
2204
|
return impl_->id();
|
2178
2205
|
}
|
2179
2206
|
|
2207
|
+
auto
|
2208
|
+
mcbp_session::node_uuid() const -> const std::string&
|
2209
|
+
{
|
2210
|
+
return impl_->node_uuid();
|
2211
|
+
}
|
2212
|
+
|
2180
2213
|
auto
|
2181
2214
|
mcbp_session::bootstrap_address() const -> const std::string&
|
2182
2215
|
{
|
@@ -90,6 +90,7 @@ public:
|
|
90
90
|
auto operator=(mcbp_session&& other) -> mcbp_session& = default;
|
91
91
|
|
92
92
|
mcbp_session(const std::string& client_id,
|
93
|
+
const std::string& node_uuid,
|
93
94
|
asio::io_context& ctx,
|
94
95
|
couchbase::core::origin origin,
|
95
96
|
std::shared_ptr<impl::bootstrap_state_listener> state_listener,
|
@@ -97,6 +98,7 @@ public:
|
|
97
98
|
std::vector<protocol::hello_feature> known_features = {});
|
98
99
|
|
99
100
|
mcbp_session(const std::string& client_id,
|
101
|
+
const std::string& node_uuid,
|
100
102
|
asio::io_context& ctx,
|
101
103
|
asio::ssl::context& tls,
|
102
104
|
couchbase::core::origin origin,
|
@@ -115,6 +117,7 @@ public:
|
|
115
117
|
[[nodiscard]] auto supports_feature(protocol::hello_feature feature) -> bool;
|
116
118
|
[[nodiscard]] auto supported_features() const -> std::vector<protocol::hello_feature>;
|
117
119
|
[[nodiscard]] auto id() const -> const std::string&;
|
120
|
+
[[nodiscard]] auto node_uuid() const -> const std::string&;
|
118
121
|
[[nodiscard]] auto remote_address() const -> std::string;
|
119
122
|
[[nodiscard]] auto local_address() const -> std::string;
|
120
123
|
[[nodiscard]] auto bootstrap_address() const -> const std::string&;
|
@@ -59,6 +59,10 @@ std::shared_ptr<spdlog::logger> file_logger{};
|
|
59
59
|
std::mutex file_logger_mutex;
|
60
60
|
std::atomic_int file_logger_version{ 0 };
|
61
61
|
|
62
|
+
std::shared_ptr<couchbase::core::logger::log_callback> log_callback{};
|
63
|
+
std::mutex log_callback_mutex;
|
64
|
+
std::atomic_int log_callback_version{ 0 };
|
65
|
+
|
62
66
|
auto
|
63
67
|
get_file_logger() -> std::shared_ptr<spdlog::logger>
|
64
68
|
{
|
@@ -72,6 +76,27 @@ get_file_logger() -> std::shared_ptr<spdlog::logger>
|
|
72
76
|
return logger;
|
73
77
|
}
|
74
78
|
|
79
|
+
auto
|
80
|
+
get_custom_callback() -> std::shared_ptr<couchbase::core::logger::log_callback>
|
81
|
+
{
|
82
|
+
thread_local std::shared_ptr<couchbase::core::logger::log_callback> callback{ nullptr };
|
83
|
+
thread_local int version{ -1 };
|
84
|
+
if (version != log_callback_version) {
|
85
|
+
const std::scoped_lock lock(log_callback_mutex);
|
86
|
+
callback = log_callback;
|
87
|
+
version = log_callback_version;
|
88
|
+
}
|
89
|
+
return callback;
|
90
|
+
}
|
91
|
+
|
92
|
+
void
|
93
|
+
update_callback_logger(const std::shared_ptr<couchbase::core::logger::log_callback>& new_callback)
|
94
|
+
{
|
95
|
+
const std::scoped_lock lock(log_callback_mutex);
|
96
|
+
log_callback = new_callback;
|
97
|
+
++log_callback_version;
|
98
|
+
}
|
99
|
+
|
75
100
|
void
|
76
101
|
update_file_logger(const std::shared_ptr<spdlog::logger>& new_logger)
|
77
102
|
{
|
@@ -181,6 +206,14 @@ log(const char* file, int line, const char* function, level lvl, std::string_vie
|
|
181
206
|
spdlog::source_loc{ file, line, function }, translate_level(lvl), msg);
|
182
207
|
}
|
183
208
|
}
|
209
|
+
|
210
|
+
void
|
211
|
+
log_custom_logger(const char* file, int line, const char* function, level lvl, std::string_view msg)
|
212
|
+
{
|
213
|
+
if (auto callback = get_custom_callback()) {
|
214
|
+
(*callback)(msg, lvl, { file, function, line });
|
215
|
+
}
|
216
|
+
}
|
184
217
|
} // namespace detail
|
185
218
|
|
186
219
|
void
|
@@ -396,6 +429,19 @@ create_console_logger()
|
|
396
429
|
update_file_logger(new_logger);
|
397
430
|
}
|
398
431
|
|
432
|
+
void
|
433
|
+
register_log_callback(log_callback callback)
|
434
|
+
{
|
435
|
+
auto new_callback = std::make_shared<log_callback>(std::move(callback));
|
436
|
+
update_callback_logger(new_callback);
|
437
|
+
}
|
438
|
+
|
439
|
+
void
|
440
|
+
unregister_log_callback()
|
441
|
+
{
|
442
|
+
update_callback_logger(nullptr);
|
443
|
+
}
|
444
|
+
|
399
445
|
void
|
400
446
|
register_spdlog_logger(const std::shared_ptr<spdlog::logger>& l)
|
401
447
|
{
|