1717#include " external_auth_manager_thread.h"
1818#include " front_end_thread.h"
1919#include " settings.h"
20+ #include " top_keys_controller.h"
2021#include " tracing.h"
2122#include " utilities/string_utilities.h"
2223#include < logger/logger.h>
@@ -118,20 +119,6 @@ static cb::engine_errc ioctlGetTopkeysStop(Cookie& cookie,
118119 const StrToStrMap& args,
119120 std::string& value,
120121 cb::mcbp::Datatype& datatype) {
121- std::shared_ptr<cb::trace::topkeys::Collector> collector;
122- FrontEndThread::forEach (
123- [&collector](auto & t) {
124- if (!t.keyTrace ) {
125- return ;
126- }
127-
128- if (!collector) {
129- collector = t.keyTrace ;
130- }
131- t.keyTrace .reset ();
132- },
133- true );
134-
135122 std::size_t limit = 100 ;
136123 if (args.contains (" limit" )) {
137124 try {
@@ -145,25 +132,39 @@ static cb::engine_errc ioctlGetTopkeysStop(Cookie& cookie,
145132 }
146133 }
147134
148- if (!collector) {
149- cookie.setErrorContext (
150- " Failed to collect topkeys - tracing not active" );
151- LOG_WARNING_CTX (" Failed to collect topkeys - tracing not active" ,
152- {" conn_id" , cookie.getConnection ().getId ()});
153- return cb::engine_errc::failed;
135+ cb::uuid::uuid_t uuid;
136+ if (args.contains (" uuid" )) {
137+ try {
138+ uuid = cb::uuid::from_string (args.find (" uuid" )->second );
139+ } catch (const std::exception& exception) {
140+ LOG_ERROR_CTX (" Failed to parse uuid" ,
141+ {" conn_id" , cookie.getConnection ().getId ()},
142+ {" error" , exception.what ()});
143+ return cb::engine_errc::invalid_arguments;
144+ }
154145 }
155146
156- try {
157- nlohmann::json json = collector->getResults (limit);
158- value = json.dump ();
159- } catch (const std::exception& exception) {
160- LOG_ERROR_CTX (" Failed to get trace data" ,
161- {" conn_id" , cookie.getConnection ().getId ()},
162- {" error" , exception.what ()});
163- return cb::engine_errc::failed;
147+ auto [status, json] =
148+ cb::trace::topkeys::Controller::instance ().stop (uuid, limit);
149+ if (status == cb::engine_errc::success) {
150+ try {
151+ value = json.dump ();
152+ } catch (const std::exception& exception) {
153+ LOG_ERROR_CTX (
154+ " Failed to get trace data. Trace data will be discarded" ,
155+ {" conn_id" , cookie.getConnection ().getId ()},
156+ {" error" , exception.what ()});
157+ return cb::engine_errc::failed;
158+ }
159+ datatype = cb::mcbp::Datatype::JSON;
160+ return cb::engine_errc::success;
164161 }
165- datatype = cb::mcbp::Datatype::JSON;
166- return cb::engine_errc::success;
162+
163+ if (json.is_object ()) {
164+ cookie.setErrorJsonExtras (json);
165+ }
166+ cookie.setErrorContext (" Failed to start topkeys collection" );
167+ return status;
167168}
168169
169170cb::engine_errc ioctl_get_property (Cookie& cookie,
@@ -325,7 +326,9 @@ static cb::engine_errc ioctlSetServerlessUnitSize(Cookie& cookie,
325326
326327static cb::engine_errc ioctlSetTopkeysStart (Cookie& cookie,
327328 const StrToStrMap& args,
328- const std::string&) {
329+ const std::string&,
330+ std::string& result,
331+ cb::mcbp::Datatype& datatype) {
329332 std::size_t limit = 10000 ;
330333 if (args.contains (" limit" )) {
331334 try {
@@ -402,27 +405,28 @@ static cb::engine_errc ioctlSetTopkeysStart(Cookie& cookie,
402405 }
403406 }
404407
405- auto expiry_time = cb::time::steady_clock::now () +
406- std::chrono::seconds (expected_duration);
407-
408- auto collector = cb::trace::topkeys::Collector::create (
409- limit, shards, expiry_time, bucket_filter);
410- if (!collector) {
411- cookie.setErrorContext (" Failed to create topkeys collector" );
412- LOG_WARNING_CTX (" Failed to create topkeys collector" ,
413- {" conn_id" , cookie.getConnection ().getId ()});
414- return cb::engine_errc::failed;
408+ const auto [status, uuid] =
409+ cb::trace::topkeys::Controller::instance ().create (
410+ limit,
411+ shards,
412+ std::chrono::seconds (expected_duration),
413+ bucket_filter);
414+ nlohmann::json json = {{" uuid" , to_string (uuid)}};
415+ if (status == cb::engine_errc::success) {
416+ result = json.dump ();
417+ datatype = cb::mcbp::Datatype::JSON;
418+ } else {
419+ cookie.setErrorJsonExtras (json);
420+ cookie.setErrorContext (" Failed to start topkeys collection" );
415421 }
416-
417- FrontEndThread::forEach ([&collector](auto & t) { t.keyTrace = collector; },
418- true );
419-
420- return cb::engine_errc::success;
422+ return status;
421423}
422424
423425cb::engine_errc ioctl_set_property (Cookie& cookie,
424426 const std::string& key,
425- const std::string& value) {
427+ const std::string& value,
428+ std::string& result,
429+ cb::mcbp::Datatype& datatype) {
426430 std::pair<std::string, StrToStrMap> request;
427431
428432 try {
@@ -431,6 +435,9 @@ cb::engine_errc ioctl_set_property(Cookie& cookie,
431435 return cb::engine_errc::invalid_arguments;
432436 }
433437
438+ result.clear ();
439+ datatype = cb::mcbp::Datatype::Raw;
440+
434441 auto & manager = cb::ioctl::Manager::getInstance ();
435442 auto * id = manager.lookup (request.first );
436443 if (id) {
@@ -471,7 +478,8 @@ cb::engine_errc ioctl_set_property(Cookie& cookie,
471478 }
472479 return cb::engine_errc::not_supported;
473480 case cb::ioctl::Id::TopkeysStart:
474- return ioctlSetTopkeysStart (cookie, request.second , value);
481+ return ioctlSetTopkeysStart (
482+ cookie, request.second , value, result, datatype);
475483
476484 case cb::ioctl::Id::TraceDumpBegin: // may only be used with Get
477485 case cb::ioctl::Id::TraceDumpGet: // may only be used with Get
0 commit comments