#include "TraceCollector.h" #include #include #include #include #include #include #include namespace DB { LazyPipe trace_pipe; TraceCollector::TraceCollector(TraceLog * trace_log, std::future&& stop_future) : log(&Logger::get("TraceCollector")) , trace_log(trace_log) , stop_future(std::move(stop_future)) { } void TraceCollector::run() { DB::ReadBufferFromFileDescriptor in(trace_pipe.fds_rw[0]); while (stop_future.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout) { ucontext_t context; std::string query_id; TimerType timer_type; try { DB::readPODBinary(context, in); DB::readStringBinary(query_id, in); DB::readIntBinary(timer_type, in); } catch (Exception&) { /// Pipe was closed - looks like server is about to shutdown /// Let us wait for stop_future continue; } if (trace_log != nullptr) { std::vector frames = getBacktraceFrames(context); std::vector trace; trace.reserve(frames.size()); for (void * frame : frames) trace.push_back(reinterpret_cast(frame)); TraceLogElement element{std::time(nullptr), timer_type, query_id, trace}; trace_log->add(element); } } } }