123 lines
3.2 KiB
C++
123 lines
3.2 KiB
C++
#include "PerformanceLogger.h"
|
|
|
|
PerformanceLogger &PerformanceLogger::instance()
|
|
{
|
|
static PerformanceLogger logger;
|
|
return logger;
|
|
}
|
|
|
|
void PerformanceLogger::beginSession(const QString &sessionName)
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
m_sessionName = sessionName;
|
|
m_sessionActive = true;
|
|
}
|
|
|
|
void PerformanceLogger::endSession()
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
m_sessionActive = false;
|
|
}
|
|
|
|
void PerformanceLogger::log(const QString &category, const QString &name, qint64 elapsedMs)
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
Record rec;
|
|
rec.category = category;
|
|
rec.name = name;
|
|
rec.elapsedMs = elapsedMs;
|
|
rec.timestamp = QDateTime::currentDateTime();
|
|
m_records.append(rec);
|
|
}
|
|
|
|
QVector<PerformanceLogger::Record> PerformanceLogger::records() const
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
return m_records;
|
|
}
|
|
|
|
void PerformanceLogger::clear()
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
m_records.clear();
|
|
}
|
|
|
|
QString PerformanceLogger::reportString() const
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
QString report;
|
|
QTextStream ts(&report);
|
|
|
|
ts << "==================================================\n";
|
|
ts << "Performance Report";
|
|
if (!m_sessionName.isEmpty())
|
|
ts << " - " << m_sessionName;
|
|
ts << "\n";
|
|
ts << "Generated: " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << "\n";
|
|
ts << "==================================================\n";
|
|
|
|
if (m_records.isEmpty()) {
|
|
ts << "No records.\n";
|
|
return report;
|
|
}
|
|
|
|
// Group by category
|
|
QString currentCategory;
|
|
qint64 categoryTotal = 0;
|
|
for (const auto &rec : m_records) {
|
|
if (rec.category != currentCategory) {
|
|
if (!currentCategory.isEmpty()) {
|
|
ts << " [Category Total: " << categoryTotal << " ms]\n\n";
|
|
}
|
|
currentCategory = rec.category;
|
|
categoryTotal = 0;
|
|
ts << "[" << currentCategory << "]\n";
|
|
}
|
|
ts << " " << rec.name << ": " << rec.elapsedMs << " ms\n";
|
|
categoryTotal += rec.elapsedMs;
|
|
}
|
|
if (!currentCategory.isEmpty()) {
|
|
ts << " [Category Total: " << categoryTotal << " ms]\n";
|
|
}
|
|
|
|
ts << "\n==================================================\n";
|
|
ts << "Grand Total: ";
|
|
qint64 grandTotal = 0;
|
|
for (const auto &rec : m_records)
|
|
grandTotal += rec.elapsedMs;
|
|
ts << grandTotal << " ms\n";
|
|
ts << "==================================================\n";
|
|
|
|
return report;
|
|
}
|
|
|
|
void PerformanceLogger::printReport() const
|
|
{
|
|
const QString report = reportString();
|
|
qDebug().noquote() << report;
|
|
}
|
|
|
|
void PerformanceLogger::saveToFile(const QString &filePath) const
|
|
{
|
|
QFile file(filePath);
|
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) {
|
|
qDebug() << "PerformanceLogger: failed to open" << filePath;
|
|
return;
|
|
}
|
|
QTextStream ts(&file);
|
|
ts << reportString();
|
|
file.close();
|
|
}
|
|
|
|
ScopedPerfTimer::ScopedPerfTimer(const QString &category, const QString &name)
|
|
: m_category(category), m_name(name)
|
|
{
|
|
m_timer.start();
|
|
}
|
|
|
|
ScopedPerfTimer::~ScopedPerfTimer()
|
|
{
|
|
const qint64 elapsed = m_timer.elapsed();
|
|
PerformanceLogger::instance().log(m_category, m_name, elapsed);
|
|
}
|