From 8c63c7ff740e021e25aeb08aa60e437c54bea6e7 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 11 May 2017 12:00:55 +0200 Subject: Avoid recreating the settings object on every log call --- common/log.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'common/log.cpp') diff --git a/common/log.cpp b/common/log.cpp index 045b3cc..4024545 100644 --- a/common/log.cpp +++ b/common/log.cpp @@ -12,12 +12,17 @@ #include #include #include +#include using namespace Sink::Log; -static QSharedPointer config() +QThreadStorage> sSettings; +static QSettings &config() { - return QSharedPointer::create(Sink::configLocation() + "/log.ini", QSettings::IniFormat); + if (!sSettings.hasLocalData()) { + sSettings.setLocalData(QSharedPointer::create(Sink::configLocation() + "/log.ini", QSettings::IniFormat)); + } + return *sSettings.localData(); } static QByteArray sPrimaryComponent; @@ -173,22 +178,22 @@ DebugLevel Sink::Log::debugLevelFromName(const QByteArray &name) void Sink::Log::setDebugOutputLevel(DebugLevel debugLevel) { - config()->setValue("level", debugLevel); + config().setValue("level", debugLevel); } Sink::Log::DebugLevel Sink::Log::debugOutputLevel() { - return static_cast(config()->value("level", Sink::Log::Log).toInt()); + return static_cast(config().value("level", Sink::Log::Log).toInt()); } void Sink::Log::setDebugOutputFilter(FilterType type, const QByteArrayList &filter) { switch (type) { case ApplicationName: - config()->setValue("applicationfilter", QVariant::fromValue(filter)); + config().setValue("applicationfilter", QVariant::fromValue(filter)); break; case Area: - config()->setValue("areafilter", QVariant::fromValue(filter)); + config().setValue("areafilter", QVariant::fromValue(filter)); break; } } @@ -197,9 +202,9 @@ QByteArrayList Sink::Log::debugOutputFilter(FilterType type) { switch (type) { case ApplicationName: - return config()->value("applicationfilter").value(); + return config().value("applicationfilter").value(); case Area: - return config()->value("areafilter").value(); + return config().value("areafilter").value(); default: return QByteArrayList(); } @@ -207,12 +212,12 @@ QByteArrayList Sink::Log::debugOutputFilter(FilterType type) void Sink::Log::setDebugOutputFields(const QByteArrayList &output) { - config()->setValue("outputfields", QVariant::fromValue(output)); + config().setValue("outputfields", QVariant::fromValue(output)); } QByteArrayList Sink::Log::debugOutputFields() { - return config()->value("outputfields").value(); + return config().value("outputfields").value(); } static QByteArray getProgramName() -- cgit v1.2.3 From 35815a20a78fc440bdf79c64ee86cfcd62a23557 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 12 May 2017 08:21:31 +0200 Subject: Fixed build --- common/log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common/log.cpp') diff --git a/common/log.cpp b/common/log.cpp index 4024545..1fbc482 100644 --- a/common/log.cpp +++ b/common/log.cpp @@ -16,7 +16,7 @@ using namespace Sink::Log; -QThreadStorage> sSettings; +static QThreadStorage> sSettings; static QSettings &config() { if (!sSettings.hasLocalData()) { -- cgit v1.2.3 From e61c2cad0451cddf1f84a32ed818b4c3bc7b6b0f Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 12 May 2017 10:03:17 +0200 Subject: Only use the filename as area, not the full path. --- common/log.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'common/log.cpp') diff --git a/common/log.cpp b/common/log.cpp index 1fbc482..e9e16c6 100644 --- a/common/log.cpp +++ b/common/log.cpp @@ -305,6 +305,12 @@ static bool caseInsensitiveContains(const QByteArray &pattern, const QByteArrayL return false; } +static QByteArray getFileName(const char *file) +{ + auto filename = QByteArray(file).split('/').last(); + return filename.split('.').first(); +} + QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, const char *function, const char *debugArea, const char *debugComponent) { static NullStream nullstream; @@ -315,7 +321,7 @@ QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, if (sPrimaryComponent.isEmpty()) { sPrimaryComponent = getProgramName(); } - QString fullDebugArea = sPrimaryComponent + "." + (debugComponent ? (QString::fromLatin1(debugComponent) + ".") : "") + (debugArea ? QString::fromLatin1(debugArea) : ""); + QString fullDebugArea = sPrimaryComponent + "." + (debugComponent ? (QString::fromLatin1(debugComponent) + ".") : "") + (debugArea ? QString::fromLatin1(debugArea) : getFileName(file)); collectDebugArea(fullDebugArea); -- cgit v1.2.3 From 8e91505e656743bd69166b3ba1cf29dfa7cfbea5 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 12 May 2017 10:33:52 +0200 Subject: Allow substring matches on the trace identifier --- common/log.cpp | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'common/log.cpp') diff --git a/common/log.cpp b/common/log.cpp index e9e16c6..d1a3a37 100644 --- a/common/log.cpp +++ b/common/log.cpp @@ -1,6 +1,7 @@ #include "log.h" #include +#include #include #include #include @@ -282,14 +283,16 @@ static bool containsItemStartingWith(const QByteArray &pattern, const QByteArray for (const auto &item : list) { if (item.startsWith('*')) { auto stripped = item.mid(1); - stripped.endsWith('*'); - stripped.chop(1); + if (stripped.endsWith('*')) { + stripped.chop(1); + } if (pattern.contains(stripped)) { return true; } - } - if (pattern.startsWith(item)) { - return true; + } else { + if (pattern.contains(item)) { + return true; + } } } return false; @@ -307,29 +310,39 @@ static bool caseInsensitiveContains(const QByteArray &pattern, const QByteArrayL static QByteArray getFileName(const char *file) { - auto filename = QByteArray(file).split('/').last(); + static char sep = QDir::separator().toLatin1(); + auto filename = QByteArray(file).split(sep).last(); return filename.split('.').first(); } -QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, const char *function, const char *debugArea, const char *debugComponent) +bool isFiltered(DebugLevel debugLevel, const QByteArray &fullDebugArea) { - static NullStream nullstream; if (debugLevel < debugOutputLevel()) { - return QDebug(&nullstream); + return true; } + auto areas = debugOutputFilter(Sink::Log::Area); + if (debugLevel <= Sink::Log::Trace && !areas.isEmpty()) { + if (!containsItemStartingWith(fullDebugArea, areas)) { + return true; + } + } + return false; +} +QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, const char *function, const char *debugArea, const char *debugComponent) +{ if (sPrimaryComponent.isEmpty()) { sPrimaryComponent = getProgramName(); } - QString fullDebugArea = sPrimaryComponent + "." + (debugComponent ? (QString::fromLatin1(debugComponent) + ".") : "") + (debugArea ? QString::fromLatin1(debugArea) : getFileName(file)); + const QByteArray fullDebugArea = sPrimaryComponent + "." + + (debugComponent ? (QByteArray{debugComponent} + ".") : "") + + (debugArea ? QByteArray{debugArea} : getFileName(file)); collectDebugArea(fullDebugArea); - auto areas = debugOutputFilter(Sink::Log::Area); - if (debugLevel <= Sink::Log::Trace && !areas.isEmpty()) { - if (!containsItemStartingWith(fullDebugArea.toUtf8(), areas)) { - return QDebug(&nullstream); - } + static NullStream nullstream; + if (isFiltered(debugLevel, fullDebugArea)) { + return QDebug(&nullstream); } QString prefix; @@ -378,12 +391,12 @@ QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, } static std::atomic maxDebugAreaSize{25}; maxDebugAreaSize = qMax(fullDebugArea.size(), maxDebugAreaSize.load()); - output += QString(" %1 ").arg(fullDebugArea.leftJustified(maxDebugAreaSize, ' ', false)); + output += QString(" %1 ").arg(QString{fullDebugArea}.leftJustified(maxDebugAreaSize, ' ', false)); if (useColor) { output += resetColor; } if (showFunction) { - output += QString(" %3").arg(fullDebugArea.leftJustified(25, ' ', true)); + output += QString(" %3").arg(QString{fullDebugArea}.leftJustified(25, ' ', true)); } if (showLocation) { const auto filename = QString::fromLatin1(file).split('/').last(); -- cgit v1.2.3 From 58b9fa88198eecc224597e52d8bbd7f833fca63b Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 12 May 2017 17:01:25 +0200 Subject: Completely shortcut the stream evaluation if we're not going to use the output Serializing the data is the expensive part, so we want to completely avoid that for the noisier part if we're not going to use it. Additionally we're now using a stringbuilder for the debugarea to try to further improve the situation with temporary memory allocations. --- common/log.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'common/log.cpp') diff --git a/common/log.cpp b/common/log.cpp index d1a3a37..5dfb872 100644 --- a/common/log.cpp +++ b/common/log.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace Sink::Log; @@ -315,13 +316,24 @@ static QByteArray getFileName(const char *file) return filename.split('.').first(); } -bool isFiltered(DebugLevel debugLevel, const QByteArray &fullDebugArea) +static QString assembleDebugArea(const char *debugArea, const char *debugComponent, const char *file) +{ + if (sPrimaryComponent.isEmpty()) { + sPrimaryComponent = getProgramName(); + } + //Using stringbuilder for fewer allocations + return QLatin1String{sPrimaryComponent} % QLatin1String{"."} % + (debugComponent ? (QLatin1String{debugComponent} + QLatin1String{"."}) : QLatin1String{""}) % + (debugArea ? QLatin1String{debugArea} : QLatin1String{getFileName(file)}); +} + +static bool isFiltered(DebugLevel debugLevel, const QByteArray &fullDebugArea) { if (debugLevel < debugOutputLevel()) { return true; } - auto areas = debugOutputFilter(Sink::Log::Area); - if (debugLevel <= Sink::Log::Trace && !areas.isEmpty()) { + const auto areas = debugOutputFilter(Sink::Log::Area); + if ((debugLevel <= Sink::Log::Trace) && !areas.isEmpty()) { if (!containsItemStartingWith(fullDebugArea, areas)) { return true; } @@ -329,19 +341,18 @@ bool isFiltered(DebugLevel debugLevel, const QByteArray &fullDebugArea) return false; } -QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, const char *function, const char *debugArea, const char *debugComponent) +bool Sink::Log::isFiltered(DebugLevel debugLevel, const char *debugArea, const char *debugComponent, const char *file) { - if (sPrimaryComponent.isEmpty()) { - sPrimaryComponent = getProgramName(); - } - const QByteArray fullDebugArea = sPrimaryComponent + "." + - (debugComponent ? (QByteArray{debugComponent} + ".") : "") + - (debugArea ? QByteArray{debugArea} : getFileName(file)); + return isFiltered(debugLevel, assembleDebugArea(debugArea, debugComponent, file).toLatin1()); +} +QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, const char *function, const char *debugArea, const char *debugComponent) +{ + const auto fullDebugArea = assembleDebugArea(debugArea, debugComponent, file); collectDebugArea(fullDebugArea); static NullStream nullstream; - if (isFiltered(debugLevel, fullDebugArea)) { + if (isFiltered(debugLevel, fullDebugArea.toLatin1())) { return QDebug(&nullstream); } @@ -391,12 +402,12 @@ QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, } static std::atomic maxDebugAreaSize{25}; maxDebugAreaSize = qMax(fullDebugArea.size(), maxDebugAreaSize.load()); - output += QString(" %1 ").arg(QString{fullDebugArea}.leftJustified(maxDebugAreaSize, ' ', false)); + output += QString(" %1 ").arg(fullDebugArea.leftJustified(maxDebugAreaSize, ' ', false)); if (useColor) { output += resetColor; } if (showFunction) { - output += QString(" %3").arg(QString{fullDebugArea}.leftJustified(25, ' ', true)); + output += QString(" %3").arg(fullDebugArea.leftJustified(25, ' ', true)); } if (showLocation) { const auto filename = QString::fromLatin1(file).split('/').last(); -- cgit v1.2.3