Renamed profiling to tracing
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "utils/Exception.hpp"
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/AuthToken.hpp"
|
||||
@@ -190,7 +190,7 @@ namespace Database
|
||||
|
||||
void Session::analyze()
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("Database", "Analyze");
|
||||
LMS_SCOPED_TRACE_DETAILED("Database", "Analyze");
|
||||
LMS_LOG(DB, INFO, "Analyzing database...");
|
||||
{
|
||||
auto transaction{ createWriteTransaction() };
|
||||
@@ -201,7 +201,7 @@ namespace Database
|
||||
|
||||
void Session::optimize()
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("Database", "Optimize");
|
||||
LMS_SCOPED_TRACE_DETAILED("Database", "Optimize");
|
||||
LMS_LOG(DB, INFO, "Optimizing database...");
|
||||
{
|
||||
auto transaction{ createWriteTransaction() };
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <Wt/WDateTime.h>
|
||||
|
||||
#include "database/Types.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
|
||||
namespace Database::Utils
|
||||
{
|
||||
@@ -48,7 +48,7 @@ namespace Database::Utils
|
||||
template <typename ResultType, typename Query>
|
||||
RangeResults<ResultType> execQuery(Query& query, std::optional<Range> range)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("Database", "ExecQueryRange");
|
||||
LMS_SCOPED_TRACE_DETAILED("Database", "ExecQueryRange");
|
||||
|
||||
RangeResults<ResultType> res;
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace Database::Utils
|
||||
|
||||
for (const auto& res : query.resultList())
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("Database", "ExecQueryResult");
|
||||
LMS_SCOPED_TRACE_DETAILED("Database", "ExecQueryResult");
|
||||
func(res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <Wt/Dbo/Dbo.h>
|
||||
#include <Wt/Dbo/SqlConnectionPool.h>
|
||||
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
#include "utils/RecursiveSharedMutex.hpp"
|
||||
#include "database/Object.hpp"
|
||||
#include "database/TransactionChecker.hpp"
|
||||
@@ -42,7 +42,7 @@ namespace Database
|
||||
WriteTransaction& operator=(const WriteTransaction&) = delete;
|
||||
|
||||
std::unique_lock<RecursiveSharedMutex> _lock;
|
||||
profiling::ScopedEvent _profilingEvent{ "Database", profiling::Level::Detailed, "WriteTransaction" }; // before actual transaction
|
||||
tracing::ScopedTrace _trace{ "Database", tracing::Level::Detailed, "WriteTransaction" }; // before actual transaction
|
||||
Wt::Dbo::Transaction _transaction;
|
||||
};
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Database
|
||||
ReadTransaction(const ReadTransaction&) = delete;
|
||||
ReadTransaction& operator=(const ReadTransaction&) = delete;
|
||||
|
||||
profiling::ScopedEvent _profilingEvent{ "Database", profiling::Level::Detailed, "ReadTransaction" }; // before actual transaction
|
||||
tracing::ScopedTrace _trace{ "Database", tracing::Level::Detailed, "ReadTransaction" }; // before actual transaction
|
||||
Wt::Dbo::Transaction _transaction;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#include "metadata/Exception.hpp"
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
#include "utils/String.hpp"
|
||||
|
||||
namespace MetaData
|
||||
@@ -173,7 +173,7 @@ namespace MetaData
|
||||
|
||||
TagLib::FileRef parseFile(const std::filesystem::path& p, ParserReadStyle parserReadStyle)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("MetaData", "TagLibParseFile");
|
||||
LMS_SCOPED_TRACE_DETAILED("MetaData", "TagLibParseFile");
|
||||
|
||||
return TagLib::FileRef{ p.string().c_str()
|
||||
, true // read audio properties
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "utils/IConfig.hpp"
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/Path.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
|
||||
namespace Scanner
|
||||
{
|
||||
@@ -257,7 +257,7 @@ namespace Scanner
|
||||
|
||||
_scanContext.post([=, this]
|
||||
{
|
||||
LMS_SCOPED_PROFILE_OVERVIEW("Scanner", "AudioFileParseJob");
|
||||
LMS_SCOPED_TRACE_OVERVIEW("Scanner", "AudioFileParseJob");
|
||||
|
||||
std::unique_ptr<MetaData::Track> track;
|
||||
|
||||
@@ -315,7 +315,7 @@ namespace Scanner
|
||||
|
||||
void ScanStepScanFiles::MetadataScanQueue::wait(std::size_t maxScanRequestCount)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_OVERVIEW("Scanner", "WaitParseResults");
|
||||
LMS_SCOPED_TRACE_OVERVIEW("Scanner", "WaitParseResults");
|
||||
|
||||
std::unique_lock lock{ _mutex };
|
||||
_condVar.wait(lock, [=, this] { return _ongoingScanCount <= maxScanRequestCount; });
|
||||
@@ -349,7 +349,7 @@ namespace Scanner
|
||||
{
|
||||
PathUtils::exploreFilesRecursive(mediaLibrary.rootDirectory, [&](std::error_code ec, const std::filesystem::path& path)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("Scanner", "OnExploreFile");
|
||||
LMS_SCOPED_TRACE_DETAILED("Scanner", "OnExploreFile");
|
||||
|
||||
if (_abortScan)
|
||||
return false;
|
||||
@@ -444,7 +444,7 @@ namespace Scanner
|
||||
|
||||
void ScanStepScanFiles::processMetaDataScanResults(ScanContext& context, std::span<const MetaDataScanResult> scanResults, const ScannerSettings::MediaLibraryInfo& libraryInfo)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_OVERVIEW("Scanner", "ProcessScanResults");
|
||||
LMS_SCOPED_TRACE_OVERVIEW("Scanner", "ProcessScanResults");
|
||||
|
||||
Database::Session& dbSession{ _db.getTLSSession() };
|
||||
auto transaction{ dbSession.createWriteTransaction() };
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "utils/LiteralString.hpp"
|
||||
#include "utils/IConfig.hpp"
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
#include "utils/Service.hpp"
|
||||
#include "utils/String.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
@@ -311,7 +311,7 @@ namespace API::Subsonic
|
||||
auto itEntryPoint{ requestEntryPoints.find(requestPath) };
|
||||
if (itEntryPoint != requestEntryPoints.end())
|
||||
{
|
||||
LMS_SCOPED_PROFILE_OVERVIEW("Subsonic", itEntryPoint->first);
|
||||
LMS_SCOPED_TRACE_OVERVIEW("Subsonic", itEntryPoint->first);
|
||||
|
||||
if (itEntryPoint->second.checkFunc)
|
||||
itEntryPoint->second.checkFunc();
|
||||
@@ -319,12 +319,12 @@ namespace API::Subsonic
|
||||
checkUserTypeIsAllowed(requestContext, itEntryPoint->second.allowedUserTypes);
|
||||
|
||||
const Response resp{ [&] {
|
||||
LMS_SCOPED_PROFILE_DETAILED("Subsonic", "HandleRequest");
|
||||
LMS_SCOPED_TRACE_DETAILED("Subsonic", "HandleRequest");
|
||||
return itEntryPoint->second.func(requestContext);
|
||||
}()};
|
||||
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("Subsonic", "WriteResponse");
|
||||
LMS_SCOPED_TRACE_DETAILED("Subsonic", "WriteResponse");
|
||||
|
||||
resp.write(response.out(), format);
|
||||
response.setMimeType(std::string{ ResponseFormatToMimeType(format) });
|
||||
@@ -337,7 +337,7 @@ namespace API::Subsonic
|
||||
auto itStreamHandler{ mediaRetrievalHandlers.find(requestPath) };
|
||||
if (itStreamHandler != mediaRetrievalHandlers.end())
|
||||
{
|
||||
LMS_SCOPED_PROFILE_OVERVIEW("Subsonic", itStreamHandler->first);
|
||||
LMS_SCOPED_TRACE_OVERVIEW("Subsonic", itStreamHandler->first);
|
||||
|
||||
itStreamHandler->second(requestContext, request, response);
|
||||
LMS_LOG(API_SUBSONIC, DEBUG, "Request " << requestId << " '" << requestPath << "' handled!");
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "database/User.hpp"
|
||||
#include "services/feedback/IFeedbackService.hpp"
|
||||
#include "services/scrobbling/IScrobblingService.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
#include "utils/Service.hpp"
|
||||
#include "utils/String.hpp"
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace API::Subsonic
|
||||
|
||||
Response::Node createAlbumNode(RequestContext& context, const Release::pointer& release, const User::pointer& user, bool id3)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("Subsonic", "CreateAlbum");
|
||||
LMS_SCOPED_TRACE_DETAILED("Subsonic", "CreateAlbum");
|
||||
|
||||
Response::Node albumNode;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "database/TrackArtistLink.hpp"
|
||||
#include "database/User.hpp"
|
||||
#include "services/feedback/IFeedbackService.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
#include "utils/Service.hpp"
|
||||
#include "utils/String.hpp"
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace API::Subsonic
|
||||
|
||||
Response::Node createArtistNode(RequestContext& context, const Artist::pointer& artist, const User::pointer& user, bool id3)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("Subsonic", "CreateArtist");
|
||||
LMS_SCOPED_TRACE_DETAILED("Subsonic", "CreateArtist");
|
||||
|
||||
Response::Node artistNode{ createArtistNode(artist) };
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "database/User.hpp"
|
||||
#include "services/feedback/IFeedbackService.hpp"
|
||||
#include "services/scrobbling/IScrobblingService.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
#include "utils/Service.hpp"
|
||||
#include "utils/String.hpp"
|
||||
#include "responses/Artist.hpp"
|
||||
@@ -97,7 +97,7 @@ namespace API::Subsonic
|
||||
|
||||
Response::Node createSongNode(RequestContext& context, const Track::pointer& track, const User::pointer& user)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("Subsonic", "CreateSong");
|
||||
LMS_SCOPED_TRACE_DETAILED("Subsonic", "CreateSong");
|
||||
|
||||
Response::Node trackResponse;
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ add_library(lmsutils SHARED
|
||||
impl/Logger.cpp
|
||||
impl/NetAddress.cpp
|
||||
impl/Path.cpp
|
||||
impl/Profiler.cpp
|
||||
impl/Random.cpp
|
||||
impl/RecursiveSharedMutex.cpp
|
||||
impl/StreamLogger.cpp
|
||||
impl/String.cpp
|
||||
impl/TraceLogger.cpp
|
||||
impl/UUID.cpp
|
||||
impl/WtLogger.cpp
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
add_executable(bench-utils
|
||||
ProfilerBench.cpp
|
||||
TraceLoggerBench.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(bench-utils PRIVATE
|
||||
|
||||
@@ -22,32 +22,32 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
#include "utils/StreamLogger.hpp"
|
||||
|
||||
|
||||
// Profiler is meant to built/destroyed once
|
||||
// The trace logger is meant to built/destroyed once
|
||||
Service<ILogger> logger{ std::make_unique<StreamLogger>(std::cout, StreamLogger::allSeverities) };
|
||||
Service<profiling::IProfiler> profiler{ profiling::createProfiler(::profiling::Level::Overview) };
|
||||
Service<tracing::ITraceLogger> traceLogger{ tracing::createTraceLogger(::tracing::Level::Overview) };
|
||||
|
||||
static void BM_Profiler_Overview(benchmark::State& state)
|
||||
static void BM_TraceLogger_Overview(benchmark::State& state)
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_OVERVIEW("Cat", "Test");
|
||||
LMS_SCOPED_TRACE_OVERVIEW("Cat", "Test");
|
||||
}
|
||||
}
|
||||
|
||||
static void BM_Profiler_Detailed(benchmark::State& state)
|
||||
static void BM_TraceLogger_Detailed(benchmark::State& state)
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
// Should do nothing
|
||||
LMS_SCOPED_PROFILE_DETAILED("Cat", "Test");
|
||||
LMS_SCOPED_TRACE_DETAILED("Cat", "Test");
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_Profiler_Overview)->Threads(1)->Threads(std::thread::hardware_concurrency());
|
||||
BENCHMARK(BM_Profiler_Detailed)->Threads(1)->Threads(std::thread::hardware_concurrency());
|
||||
BENCHMARK(BM_TraceLogger_Overview)->Threads(1)->Threads(std::thread::hardware_concurrency());
|
||||
BENCHMARK(BM_TraceLogger_Detailed)->Threads(1)->Threads(std::thread::hardware_concurrency());
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <cstdlib>
|
||||
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
|
||||
IOContextRunner::IOContextRunner(boost::asio::io_service& ioService, std::size_t threadCount, std::string_view name)
|
||||
: _ioService{ ioService }
|
||||
@@ -43,8 +43,8 @@ IOContextRunner::IOContextRunner(boost::asio::io_service& ioService, std::size_t
|
||||
{
|
||||
if (!threadName.empty())
|
||||
{
|
||||
if (auto * profiler{ Service<profiling::IProfiler>::get() })
|
||||
profiler->setThreadName(std::this_thread::get_id(), threadName);
|
||||
if (auto * traceLogger{ Service<tracing::ITraceLogger>::get() })
|
||||
traceLogger->setThreadName(std::this_thread::get_id(), threadName);
|
||||
}
|
||||
|
||||
try
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Profiler.hpp"
|
||||
#include "TraceLogger.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
@@ -25,58 +25,58 @@
|
||||
#include "utils/Exception.hpp"
|
||||
#include "utils/ILogger.hpp"
|
||||
|
||||
namespace profiling
|
||||
namespace tracing
|
||||
{
|
||||
namespace
|
||||
{
|
||||
class CurrentThreadUnregisterer
|
||||
{
|
||||
public:
|
||||
CurrentThreadUnregisterer(Profiler* profiler) : _profiler{ profiler } {}
|
||||
CurrentThreadUnregisterer(TraceLogger* logger) : _logger{ logger } {}
|
||||
~CurrentThreadUnregisterer()
|
||||
{
|
||||
if (_profiler)
|
||||
_profiler->onThreadPreDestroy();
|
||||
if (_logger)
|
||||
_logger->onThreadPreDestroy();
|
||||
}
|
||||
|
||||
private:
|
||||
CurrentThreadUnregisterer(const CurrentThreadUnregisterer&) = delete;
|
||||
CurrentThreadUnregisterer& operator=(const CurrentThreadUnregisterer&) = delete;
|
||||
|
||||
Profiler* _profiler;
|
||||
TraceLogger* _logger;
|
||||
};
|
||||
}
|
||||
|
||||
thread_local Profiler::Buffer* Profiler::_currentBuffer{};
|
||||
thread_local TraceLogger::Buffer* TraceLogger::_currentBuffer{};
|
||||
|
||||
std::unique_ptr<IProfiler> createProfiler(Level minLevel, std::size_t bufferSizeInMbytes)
|
||||
std::unique_ptr<ITraceLogger> createTraceLogger(Level minLevel, std::size_t bufferSizeInMbytes)
|
||||
{
|
||||
return std::make_unique<Profiler>(minLevel, bufferSizeInMbytes);
|
||||
return std::make_unique<TraceLogger>(minLevel, bufferSizeInMbytes);
|
||||
}
|
||||
|
||||
Profiler::Profiler(Level minLevel, std::size_t bufferSizeinMBytes)
|
||||
TraceLogger::TraceLogger(Level minLevel, std::size_t bufferSizeinMBytes)
|
||||
: _minLevel{ minLevel }
|
||||
, _start{ clock::now() }
|
||||
, _creatorThreadId{ std::this_thread::get_id() }
|
||||
, _buffers((bufferSizeinMBytes * 1024 * 1024) / BufferSize)
|
||||
{
|
||||
if (bufferSizeinMBytes < MinBufferSizeInMBytes)
|
||||
throw LmsException{ "Profiler must be configured with at least " + std::to_string(MinBufferSizeInMBytes) + " MBytes" };
|
||||
throw LmsException{ "TraceLogger must be configured with at least " + std::to_string(MinBufferSizeInMBytes) + " MBytes" };
|
||||
|
||||
setThreadName(_creatorThreadId, "MainThread");
|
||||
|
||||
for (Buffer& buffer : _buffers)
|
||||
_freeBuffers.push_back(&buffer);
|
||||
|
||||
LMS_LOG(UTILS, INFO, "Profiler: using " << _buffers.size() << " buffers. Buffer size = " << std::to_string(BufferSize));
|
||||
LMS_LOG(UTILS, INFO, "TraceLogger: using " << _buffers.size() << " buffers. Buffer size = " << std::to_string(BufferSize));
|
||||
}
|
||||
|
||||
bool Profiler::isLevelActive(Level level) const
|
||||
bool TraceLogger::isLevelActive(Level level) const
|
||||
{
|
||||
return static_cast<std::underlying_type_t<Level>>(level) <= static_cast<std::underlying_type_t<Level>>(_minLevel);
|
||||
}
|
||||
|
||||
void Profiler::write(const CompleteEvent& event)
|
||||
void TraceLogger::write(const CompleteEvent& event)
|
||||
{
|
||||
if (!_currentBuffer)
|
||||
_currentBuffer = acquireBuffer();
|
||||
@@ -91,21 +91,21 @@ namespace profiling
|
||||
}
|
||||
}
|
||||
|
||||
void Profiler::onThreadPreDestroy()
|
||||
void TraceLogger::onThreadPreDestroy()
|
||||
{
|
||||
if (_currentBuffer)
|
||||
releaseBuffer(_currentBuffer);
|
||||
}
|
||||
|
||||
Profiler::Buffer* Profiler::acquireBuffer()
|
||||
TraceLogger::Buffer* TraceLogger::acquireBuffer()
|
||||
{
|
||||
// We consider the creator thread will survive the profiler (thus we don't want to release anything on thread destruction)
|
||||
// We consider the creator thread will survive the trace logger (thus we don't want to release anything on thread destruction)
|
||||
static thread_local CurrentThreadUnregisterer currentThreadUnregister{ _creatorThreadId == std::this_thread::get_id() ? nullptr : this };
|
||||
|
||||
std::scoped_lock lock{ _mutex };
|
||||
assert(!_freeBuffers.empty());
|
||||
|
||||
Profiler::Buffer* buffer{ _freeBuffers.front() };
|
||||
TraceLogger::Buffer* buffer{ _freeBuffers.front() };
|
||||
_freeBuffers.pop_front();
|
||||
|
||||
// Empty new buffer only now (we want to keep history on released buffers since we dump them)
|
||||
@@ -113,7 +113,7 @@ namespace profiling
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void Profiler::releaseBuffer(Buffer* buffer)
|
||||
void TraceLogger::releaseBuffer(Buffer* buffer)
|
||||
{
|
||||
assert(buffer);
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace profiling
|
||||
_freeBuffers.push_back(buffer);
|
||||
}
|
||||
|
||||
void Profiler::dumpCurrentBuffer(std::ostream& os)
|
||||
void TraceLogger::dumpCurrentBuffer(std::ostream& os)
|
||||
{
|
||||
os << "{" << std::endl;
|
||||
os << "\t\"traceEvents\": [" << std::endl;
|
||||
@@ -154,10 +154,12 @@ namespace profiling
|
||||
|
||||
for (Buffer& buffer : _buffers)
|
||||
{
|
||||
// Looks like tracing viewer is not pleased when nested event start at the same timestamp
|
||||
for (std::size_t i{}; i < buffer.currentDurationIndex; ++i)
|
||||
{
|
||||
// Looks like tracing viewer is not pleased when nested event start at the same timestamp
|
||||
// Hence the double representation as the microsecond unit is not precise enough
|
||||
using clockMicro = std::chrono::duration<double, std::micro>;
|
||||
|
||||
const CompleteEvent& event{ buffer.durationEvents[i] };
|
||||
|
||||
if (first)
|
||||
@@ -184,7 +186,7 @@ namespace profiling
|
||||
os << "}" << std::endl;
|
||||
}
|
||||
|
||||
void Profiler::setThreadName(std::thread::id id, std::string_view threadName)
|
||||
void TraceLogger::setThreadName(std::thread::id id, std::string_view threadName)
|
||||
{
|
||||
std::scoped_lock lock{ _threadNameMutex };
|
||||
_threadNames.emplace(id, threadName);
|
||||
@@ -26,14 +26,14 @@
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
|
||||
namespace profiling
|
||||
namespace tracing
|
||||
{
|
||||
class Profiler : public IProfiler
|
||||
class TraceLogger : public ITraceLogger
|
||||
{
|
||||
public:
|
||||
Profiler(Level minLevel, std::size_t bufferSizeinMBytes);
|
||||
TraceLogger(Level minLevel, std::size_t bufferSizeinMBytes);
|
||||
|
||||
void onThreadPreDestroy();
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "utils/Exception.hpp"
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
#include "utils/String.hpp"
|
||||
|
||||
#define LOG(sev, message) LMS_LOG(SCROBBLING, sev, "[Http SendQueue] - " << message)
|
||||
@@ -118,7 +118,7 @@ namespace Http
|
||||
bool
|
||||
SendQueue::sendRequest(const ClientRequest& request)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("SendQueue", "SendRequest");
|
||||
LMS_SCOPED_TRACE_DETAILED("SendQueue", "SendRequest");
|
||||
|
||||
std::string url {_baseUrl + request.getParameters().relativeUrl};
|
||||
LOG(DEBUG, "Sending request to url '" << url << "'");
|
||||
@@ -144,7 +144,7 @@ namespace Http
|
||||
void
|
||||
SendQueue::onClientDone(Wt::AsioWrapper::error_code ec, const Wt::Http::Message& msg)
|
||||
{
|
||||
LMS_SCOPED_PROFILE_DETAILED("SendQueue", "OnClientDone");
|
||||
LMS_SCOPED_TRACE_DETAILED("SendQueue", "OnClientDone");
|
||||
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
{
|
||||
|
||||
+22
-22
@@ -28,22 +28,22 @@
|
||||
#include "LiteralString.hpp"
|
||||
#include "Service.hpp"
|
||||
|
||||
#define LMS_ENABLE_PROFILING 1
|
||||
#define LMS_SUPPORT_TRACING 1
|
||||
|
||||
#define LMS_CONCAT_IMPL(x, y) x##y
|
||||
#define LMS_CONCAT(x, y) LMS_CONCAT_IMPL(x, y)
|
||||
|
||||
#if LMS_ENABLE_PROFILING
|
||||
#define LMS_SCOPED_PROFILE(CATEGORY, LEVEL, NAME) ::profiling::ScopedEvent LMS_CONCAT(scopedEvent_, __LINE__){ CATEGORY, LEVEL, NAME }
|
||||
#if LMS_SUPPORT_TRACING
|
||||
#define LMS_SCOPED_TRACE(CATEGORY, LEVEL, NAME) ::tracing::ScopedTrace LMS_CONCAT(ScopedTrace_, __LINE__){ CATEGORY, LEVEL, NAME }
|
||||
|
||||
#else
|
||||
#define LMS_SCOPED_PROFILE(CATEGORY, LEVEL, NAME) (void)0
|
||||
#define LMS_SCOPED_TRACE(CATEGORY, LEVEL, NAME) (void)0
|
||||
#endif
|
||||
|
||||
#define LMS_SCOPED_PROFILE_OVERVIEW(CATEGORY, NAME) LMS_SCOPED_PROFILE(CATEGORY, ::profiling::Level::Overview, NAME)
|
||||
#define LMS_SCOPED_PROFILE_DETAILED(CATEGORY, NAME) LMS_SCOPED_PROFILE(CATEGORY, ::profiling::Level::Detailed, NAME)
|
||||
#define LMS_SCOPED_TRACE_OVERVIEW(CATEGORY, NAME) LMS_SCOPED_TRACE(CATEGORY, ::tracing::Level::Overview, NAME)
|
||||
#define LMS_SCOPED_TRACE_DETAILED(CATEGORY, NAME) LMS_SCOPED_TRACE(CATEGORY, ::tracing::Level::Detailed, NAME)
|
||||
|
||||
namespace profiling
|
||||
namespace tracing
|
||||
{
|
||||
using clock = std::chrono::steady_clock;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace profiling
|
||||
Detailed,
|
||||
};
|
||||
|
||||
class IProfiler
|
||||
class ITraceLogger
|
||||
{
|
||||
public:
|
||||
struct CompleteEvent
|
||||
@@ -65,7 +65,7 @@ namespace profiling
|
||||
LiteralString category;
|
||||
};
|
||||
|
||||
virtual ~IProfiler() = default;
|
||||
virtual ~ITraceLogger() = default;
|
||||
|
||||
virtual bool isLevelActive(Level level) const = 0;
|
||||
virtual void write(const CompleteEvent& entry) = 0;
|
||||
@@ -74,16 +74,16 @@ namespace profiling
|
||||
};
|
||||
|
||||
static constexpr std::size_t MinBufferSizeInMBytes = 16;
|
||||
std::unique_ptr<IProfiler> createProfiler(Level minLevel = Level::Overview, std::size_t bufferSizeInMbytes = MinBufferSizeInMBytes);
|
||||
std::unique_ptr<ITraceLogger> createTraceLogger(Level minLevel = Level::Overview, std::size_t bufferSizeInMbytes = MinBufferSizeInMBytes);
|
||||
|
||||
class ScopedEvent
|
||||
class ScopedTrace
|
||||
{
|
||||
public:
|
||||
ScopedEvent(LiteralString category, Level level, LiteralString name, IProfiler* profiler = Service<IProfiler>::get())
|
||||
ScopedTrace(LiteralString category, Level level, LiteralString name, ITraceLogger* traceLogger = Service<ITraceLogger>::get())
|
||||
{
|
||||
if (profiler && profiler->isLevelActive(level))
|
||||
if (traceLogger && traceLogger->isLevelActive(level))
|
||||
{
|
||||
_profiler = profiler;
|
||||
_traceLogger = traceLogger;
|
||||
|
||||
_event.start = clock::now();
|
||||
_event.threadId = std::this_thread::get_id();
|
||||
@@ -92,24 +92,24 @@ namespace profiling
|
||||
}
|
||||
else
|
||||
{
|
||||
_profiler = nullptr;
|
||||
_traceLogger = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
~ScopedEvent()
|
||||
~ScopedTrace()
|
||||
{
|
||||
if (_profiler)
|
||||
if (_traceLogger)
|
||||
{
|
||||
_event.duration = clock::now() - _event.start;
|
||||
_profiler->write(_event);
|
||||
_traceLogger->write(_event);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ScopedEvent(const ScopedEvent&) = delete;
|
||||
ScopedEvent& operator=(const ScopedEvent&) = delete;
|
||||
ScopedTrace(const ScopedTrace&) = delete;
|
||||
ScopedTrace& operator=(const ScopedTrace&) = delete;
|
||||
|
||||
IProfiler* _profiler;
|
||||
IProfiler::CompleteEvent _event;
|
||||
ITraceLogger* _traceLogger;
|
||||
ITraceLogger::CompleteEvent _event;
|
||||
};
|
||||
}
|
||||
@@ -4,9 +4,9 @@ add_executable(test-utils
|
||||
EnumSet.cpp
|
||||
LiteralString.cpp
|
||||
Path.cpp
|
||||
Profiler.cpp
|
||||
RecursiveSharedMutex.cpp
|
||||
String.cpp
|
||||
TraceLogger.cpp
|
||||
Utils.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -21,22 +21,22 @@
|
||||
#include <thread>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "utils/IProfiler.hpp"
|
||||
#include "utils/ITraceLogger.hpp"
|
||||
|
||||
namespace profiling::tests
|
||||
namespace tracing::tests
|
||||
{
|
||||
// not much can be tested with this implementation
|
||||
TEST(Profiler, MultipleThreads)
|
||||
TEST(TraceLogger, MultipleThreads)
|
||||
{
|
||||
auto profiler{ createProfiler(Level::Overview) };
|
||||
auto traceLogger{ createTraceLogger(Level::Overview) };
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
for (std::size_t i{}; i < 16; ++i)
|
||||
{
|
||||
threads.emplace_back([&]
|
||||
{
|
||||
ScopedEvent loggedEvent{ "MyCategory", Level::Overview, "MyEventLogged", profiler.get() };
|
||||
ScopedEvent notLoggedEvent{ "MyCategory", Level::Detailed, "MyEventNotLogged", profiler.get() };
|
||||
ScopedTrace loggedEvent{ "MyCategory", Level::Overview, "MyEventLogged", traceLogger.get() };
|
||||
ScopedTrace notLoggedEvent{ "MyCategory", Level::Detailed, "MyEventNotLogged", traceLogger.get() };
|
||||
});
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace profiling::tests
|
||||
t.join();
|
||||
|
||||
std::ostringstream oss;
|
||||
profiler->dumpCurrentBuffer(oss);
|
||||
traceLogger->dumpCurrentBuffer(oss);
|
||||
|
||||
EXPECT_NE(oss.str().find("MyEventLogged"), std::string::npos);
|
||||
EXPECT_EQ(oss.str().find("MyEventNotLogged"), std::string::npos);
|
||||
Reference in New Issue
Block a user