traces: compacted struct + fix bad json export
This commit is contained in:
@@ -68,7 +68,7 @@ namespace lms::core::tracing
|
|||||||
for (Buffer& buffer : _buffers)
|
for (Buffer& buffer : _buffers)
|
||||||
_freeBuffers.push_back(&buffer);
|
_freeBuffers.push_back(&buffer);
|
||||||
|
|
||||||
LMS_LOG(UTILS, INFO, "TraceLogger: using " << _buffers.size() << " buffers. Buffer size = " << std::to_string(BufferSize) << ", entry size = " << sizeof(CompleteEvent) << ", entry count per buffer = " << Buffer::CompleteEventCount);
|
LMS_LOG(UTILS, INFO, "TraceLogger: using " << _buffers.size() << " buffers. Buffer size = " << std::to_string(BufferSize) << ", entry size = " << sizeof(CompleteEventEntry) << ", entry count per buffer = " << Buffer::CompleteEventCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TraceLogger::isLevelActive(Level level) const
|
bool TraceLogger::isLevelActive(Level level) const
|
||||||
@@ -81,7 +81,12 @@ namespace lms::core::tracing
|
|||||||
if (!_currentBuffer)
|
if (!_currentBuffer)
|
||||||
_currentBuffer = acquireBuffer();
|
_currentBuffer = acquireBuffer();
|
||||||
|
|
||||||
_currentBuffer->durationEvents[_currentBuffer->currentDurationIndex] = event;
|
CompleteEventEntry& entry{ _currentBuffer->durationEvents[_currentBuffer->currentDurationIndex] };
|
||||||
|
entry.start = event.start;
|
||||||
|
entry.duration = event.duration;
|
||||||
|
entry.name = event.name.c_str();
|
||||||
|
entry.category = event.category.c_str();
|
||||||
|
entry.arg = event.arg.value_or(invalidHash);
|
||||||
|
|
||||||
// update the index after writing the event, in case another thread wants to dump
|
// update the index after writing the event, in case another thread wants to dump
|
||||||
if (++_currentBuffer->currentDurationIndex == _currentBuffer->durationEvents.size())
|
if (++_currentBuffer->currentDurationIndex == _currentBuffer->durationEvents.size())
|
||||||
@@ -163,7 +168,7 @@ namespace lms::core::tracing
|
|||||||
// Hence the double representation as the microsecond unit is not precise enough
|
// Hence the double representation as the microsecond unit is not precise enough
|
||||||
using clockMicro = std::chrono::duration<double, std::micro>;
|
using clockMicro = std::chrono::duration<double, std::micro>;
|
||||||
|
|
||||||
const CompleteEvent& event{ buffer.durationEvents[i] };
|
const CompleteEventEntry& event{ buffer.durationEvents[i] };
|
||||||
|
|
||||||
if (first)
|
if (first)
|
||||||
first = false;
|
first = false;
|
||||||
@@ -171,24 +176,24 @@ namespace lms::core::tracing
|
|||||||
os << ", " << std::endl;;
|
os << ", " << std::endl;;
|
||||||
|
|
||||||
os << "\t\t{ ";
|
os << "\t\t{ ";
|
||||||
os << "\"name\" : \"" << event.name.c_str() << "\", ";
|
os << "\"name\" : \"" << event.name << "\", ";
|
||||||
os << "\"cat\" : \"" << event.category.c_str() << "\", ";
|
os << "\"cat\" : \"" << event.category << "\", ";
|
||||||
os << "\"pid\": 1, ";
|
os << "\"pid\": 1, ";
|
||||||
os << "\"tid\" : " << threadId << ", ";
|
os << "\"tid\" : " << threadId << ", ";
|
||||||
os << "\"ts\" : " << std::fixed << std::setprecision(3) << std::chrono::duration_cast<clockMicro>(event.start - _start).count() << ", ";
|
os << "\"ts\" : " << std::fixed << std::setprecision(3) << std::chrono::duration_cast<clockMicro>(event.start - _start).count() << ", ";
|
||||||
os << "\"dur\" : " << std::fixed << std::setprecision(3) << std::chrono::duration_cast<clockMicro>(event.duration).count() << ", ";
|
os << "\"dur\" : " << std::fixed << std::setprecision(3) << std::chrono::duration_cast<clockMicro>(event.duration).count() << ", ";
|
||||||
os << "\"ph\" : \"X\"";
|
os << "\"ph\" : \"X\"";
|
||||||
if (event.arg.has_value())
|
if (event.arg != invalidHash)
|
||||||
{
|
{
|
||||||
ArgEntryMap::const_iterator itArgEntry;
|
ArgEntryMap::const_iterator itArgEntry;
|
||||||
{
|
{
|
||||||
std::shared_lock lock{ _argMutex };
|
std::shared_lock lock{ _argMutex };
|
||||||
itArgEntry = _argEntries.find(*event.arg);
|
itArgEntry = _argEntries.find(event.arg);
|
||||||
assert(itArgEntry != _argEntries.cend());
|
assert(itArgEntry != _argEntries.cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
os << ", \"args\" : { \"" << itArgEntry->second.type.c_str() << "\" : \"";
|
os << ", \"args\" : { \"" << itArgEntry->second.type.c_str() << "\" : \"";
|
||||||
stringUtils::writeJSEscapedString(os, std::string_view{ itArgEntry->second.value });
|
stringUtils::writeJsonEscapedString(os, std::string_view{ itArgEntry->second.value });
|
||||||
os << "\" }";
|
os << "\" }";
|
||||||
}
|
}
|
||||||
os << " }";
|
os << " }";
|
||||||
@@ -198,6 +203,7 @@ namespace lms::core::tracing
|
|||||||
|
|
||||||
os << std::endl;
|
os << std::endl;
|
||||||
os << "\t]," << std::endl;
|
os << "\t]," << std::endl;
|
||||||
|
os << "\t\"meta_registered_arg_count\" : " << getRegisteredArgCount() << ", " << std::endl;
|
||||||
os << "\t\"meta_cpu_count\" : " << std::thread::hardware_concurrency() << ", " << std::endl;
|
os << "\t\"meta_cpu_count\" : " << std::thread::hardware_concurrency() << ", " << std::endl;
|
||||||
os << "\t\"meta_build_type\" : ";
|
os << "\t\"meta_build_type\" : ";
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@@ -226,6 +232,7 @@ namespace lms::core::tracing
|
|||||||
TraceLogger::ArgHashType TraceLogger::registerArg(LiteralString argType, std::string_view argValue)
|
TraceLogger::ArgHashType TraceLogger::registerArg(LiteralString argType, std::string_view argValue)
|
||||||
{
|
{
|
||||||
const ArgHashType hash{ computeArgHash(argType, argValue) };
|
const ArgHashType hash{ computeArgHash(argType, argValue) };
|
||||||
|
assert(hash != invalidHash);
|
||||||
|
|
||||||
{
|
{
|
||||||
const std::shared_lock lock{ _argMutex };
|
const std::shared_lock lock{ _argMutex };
|
||||||
@@ -255,6 +262,13 @@ namespace lms::core::tracing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t TraceLogger::getRegisteredArgCount() const
|
||||||
|
{
|
||||||
|
const std::shared_lock lock{ _argMutex };
|
||||||
|
|
||||||
|
return _argEntries.size();
|
||||||
|
}
|
||||||
|
|
||||||
std::uint32_t TraceLogger::toTraceThreadId(std::thread::id threadId)
|
std::uint32_t TraceLogger::toTraceThreadId(std::thread::id threadId)
|
||||||
{
|
{
|
||||||
// Pefetto UI does not accept 64bits thread ids
|
// Pefetto UI does not accept 64bits thread ids
|
||||||
|
|||||||
@@ -44,18 +44,30 @@ namespace lms::core::tracing
|
|||||||
void dumpCurrentBuffer(std::ostream& os) override;
|
void dumpCurrentBuffer(std::ostream& os) override;
|
||||||
void setThreadName(std::thread::id id, std::string_view threadName) override;
|
void setThreadName(std::thread::id id, std::string_view threadName) override;
|
||||||
ArgHashType registerArg(LiteralString argType, std::string_view argValue) override;
|
ArgHashType registerArg(LiteralString argType, std::string_view argValue) override;
|
||||||
|
std::size_t getRegisteredArgCount() const;
|
||||||
|
|
||||||
static ArgHashType computeArgHash(LiteralString type, std::string_view value);
|
static ArgHashType computeArgHash(LiteralString type, std::string_view value);
|
||||||
static std::uint32_t toTraceThreadId(std::thread::id threadId);
|
static std::uint32_t toTraceThreadId(std::thread::id threadId);
|
||||||
|
|
||||||
static constexpr std::size_t BufferSize{ 64 * 1024 };
|
static constexpr std::size_t BufferSize{ 64 * 1024 };
|
||||||
|
|
||||||
|
// Same as ComplteEvent, but compacted
|
||||||
|
struct CompleteEventEntry
|
||||||
|
{
|
||||||
|
clock::time_point start;
|
||||||
|
clock::duration duration;
|
||||||
|
const char* name;
|
||||||
|
const char* category;
|
||||||
|
ArgHashType arg;
|
||||||
|
};
|
||||||
|
static constexpr ArgHashType invalidHash{ 0 };
|
||||||
|
|
||||||
struct alignas(64) Buffer
|
struct alignas(64) Buffer
|
||||||
{
|
{
|
||||||
static constexpr std::size_t CompleteEventCount{ BufferSize / sizeof(CompleteEvent) };
|
static constexpr std::size_t CompleteEventCount{ BufferSize / sizeof(CompleteEventEntry) };
|
||||||
|
|
||||||
std::thread::id threadId;
|
std::thread::id threadId;
|
||||||
std::array<CompleteEvent, CompleteEventCount> durationEvents;
|
std::array<CompleteEventEntry, CompleteEventCount> durationEvents;
|
||||||
std::atomic<std::size_t> currentDurationIndex{};
|
std::atomic<std::size_t> currentDurationIndex{};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -68,7 +80,7 @@ namespace lms::core::tracing
|
|||||||
|
|
||||||
std::vector<Buffer> _buffers; // allocated once during construction
|
std::vector<Buffer> _buffers; // allocated once during construction
|
||||||
|
|
||||||
std::shared_mutex _argMutex;
|
mutable std::shared_mutex _argMutex;
|
||||||
struct ArgEntry
|
struct ArgEntry
|
||||||
{
|
{
|
||||||
LiteralString type;
|
LiteralString type;
|
||||||
|
|||||||
Reference in New Issue
Block a user