2019-02-03 09:57:12 +00:00
|
|
|
#include "TraceCollector.h"
|
2019-02-09 21:40:10 +00:00
|
|
|
|
2019-02-03 21:30:45 +00:00
|
|
|
#include <common/Backtrace.h>
|
2019-02-03 09:57:12 +00:00
|
|
|
#include <common/logger_useful.h>
|
|
|
|
#include <IO/ReadHelpers.h>
|
2019-02-09 21:40:10 +00:00
|
|
|
#include <IO/ReadBufferFromFileDescriptor.h>
|
|
|
|
#include <Common/Exception.h>
|
2019-03-04 13:03:32 +00:00
|
|
|
#include <Common/QueryProfiler.h>
|
|
|
|
#include <Interpreters/TraceLog.h>
|
2019-02-03 21:30:45 +00:00
|
|
|
|
2019-02-03 09:57:12 +00:00
|
|
|
|
2019-02-09 22:40:47 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
2019-02-09 21:40:10 +00:00
|
|
|
LazyPipe trace_pipe;
|
2019-02-03 09:57:12 +00:00
|
|
|
|
2019-02-09 21:40:10 +00:00
|
|
|
TraceCollector::TraceCollector(TraceLog * trace_log, std::future<void>&& stop_future)
|
2019-02-03 09:57:12 +00:00
|
|
|
: log(&Logger::get("TraceCollector"))
|
2019-02-03 21:30:45 +00:00
|
|
|
, trace_log(trace_log)
|
2019-02-09 21:40:10 +00:00
|
|
|
, stop_future(std::move(stop_future))
|
2019-02-03 09:57:12 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void TraceCollector::run()
|
|
|
|
{
|
2019-02-09 21:40:10 +00:00
|
|
|
DB::ReadBufferFromFileDescriptor in(trace_pipe.fds_rw[0]);
|
2019-02-03 09:57:12 +00:00
|
|
|
|
2019-02-09 21:40:10 +00:00
|
|
|
while (stop_future.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout)
|
2019-02-03 09:57:12 +00:00
|
|
|
{
|
2019-02-03 21:30:45 +00:00
|
|
|
ucontext_t context;
|
2019-02-09 21:40:10 +00:00
|
|
|
std::string query_id;
|
2019-03-04 13:03:32 +00:00
|
|
|
TimerType timer_type;
|
2019-02-09 21:40:10 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
DB::readPODBinary(context, in);
|
|
|
|
DB::readStringBinary(query_id, in);
|
2019-03-04 13:03:32 +00:00
|
|
|
DB::readIntBinary(timer_type, in);
|
2019-02-09 22:40:47 +00:00
|
|
|
}
|
2019-03-04 13:03:32 +00:00
|
|
|
catch (Exception&)
|
2019-02-09 22:40:47 +00:00
|
|
|
{
|
2019-02-09 21:40:10 +00:00
|
|
|
/// Pipe was closed - looks like server is about to shutdown
|
|
|
|
/// Let us wait for stop_future
|
|
|
|
continue;
|
|
|
|
}
|
2019-02-03 21:30:45 +00:00
|
|
|
|
2019-02-09 22:40:47 +00:00
|
|
|
if (trace_log != nullptr)
|
|
|
|
{
|
2019-02-03 21:30:45 +00:00
|
|
|
std::vector<void *> frames = getBacktraceFrames(context);
|
|
|
|
std::vector<UInt64> trace;
|
|
|
|
trace.reserve(frames.size());
|
2019-02-09 22:40:47 +00:00
|
|
|
for (void * frame : frames)
|
2019-02-03 21:30:45 +00:00
|
|
|
trace.push_back(reinterpret_cast<uintptr_t>(frame));
|
|
|
|
|
2019-03-04 13:03:32 +00:00
|
|
|
TraceLogElement element{std::time(nullptr), timer_type, query_id, trace};
|
2019-02-03 21:30:45 +00:00
|
|
|
|
|
|
|
trace_log->add(element);
|
|
|
|
}
|
2019-02-03 09:57:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|