diff --git a/src/app/puzzle/vpapplication.cpp b/src/app/puzzle/vpapplication.cpp index e2f5b36e3..d25396fc7 100644 --- a/src/app/puzzle/vpapplication.cpp +++ b/src/app/puzzle/vpapplication.cpp @@ -33,12 +33,11 @@ #include "../ifc/exception/vexceptionemptyparameter.h" #include "../ifc/exception/vexceptionobjecterror.h" #include "../ifc/exception/vexceptionwrongid.h" -#include "../vganalytics/def.h" #include "../vganalytics/vganalytics.h" +#include "../vmisc/projectversion.h" #include "../vmisc/qt_dispatch/qt_dispatch.h" #include "../vmisc/theme/vtheme.h" #include "../vmisc/vsysexits.h" -#include "version.h" #include "vpmainwindow.h" #include "vpuzzleshortcutmanager.h" @@ -159,29 +158,55 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con type = QtDebugMsg; } - switch (type) { - case QtDebugMsg: - vStdOut() << QApplication::translate("mNoisyHandler", "DEBUG:") << msg << "\n"; - return; - case QtWarningMsg: - vStdErr() << QApplication::translate("mNoisyHandler", "WARNING:") << msg << "\n"; - break; - case QtCriticalMsg: - vStdErr() << QApplication::translate("mNoisyHandler", "CRITICAL:") << msg << "\n"; - break; - case QtFatalMsg: - vStdErr() << QApplication::translate("mNoisyHandler", "FATAL:") << msg << "\n"; - break; - case QtInfoMsg: - vStdOut() << QApplication::translate("mNoisyHandler", "INFO:") << msg << "\n"; - break; - default: - break; - } + QString debugdate = "["_L1 + QDateTime::currentDateTime().toString(QStringLiteral("yyyy.MM.dd hh:mm:ss")); - vStdOut().flush(); - vStdErr().flush(); + switch (type) + { + case QtDebugMsg: + debugdate += QStringLiteral(":DEBUG:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, msg); + vStdOut() << QApplication::translate("mNoisyHandler", "DEBUG:") << msg << "\n"; + break; + case QtWarningMsg: + debugdate += QStringLiteral(":WARNING:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, msg); + vStdErr() << QApplication::translate("mNoisyHandler", "WARNING:") << msg << "\n"; + break; + case QtCriticalMsg: + debugdate += QStringLiteral(":CRITICAL:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, msg); + vStdErr() << QApplication::translate("mNoisyHandler", "CRITICAL:") << msg << "\n"; + break; + case QtFatalMsg: + debugdate += QStringLiteral(":FATAL:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, msg); + vStdErr() << QApplication::translate("mNoisyHandler", "FATAL:") << msg << "\n"; + break; + case QtInfoMsg: + debugdate += QStringLiteral(":INFO:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, msg); + vStdOut() << QApplication::translate("mNoisyHandler", "INFO:") << msg << "\n"; + break; + default: + break; + } + + vStdOut().flush(); + vStdErr().flush(); + + (*VPApplication::VApp()->LogFile()) << debugdate << Qt::endl; + } if (isGuiThread) { @@ -209,8 +234,6 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con messageBox.setIcon(QMessageBox::Information); break; case QtDebugMsg: - Q_UNREACHABLE(); //-V501 - break; default: break; } @@ -405,10 +428,10 @@ auto VPApplication::NewMainWindow(const VPCommandLinePtr &cmd) -> VPMainWindow * //--------------------------------------------------------------------------------------------------------------------- void VPApplication::InitOptions() { - qInstallMessageHandler(noisyFailureMsgHandler); - OpenSettings(); + StartLogging(); + qCDebug(pApp, "Version: %s", qUtf8Printable(AppVersionStr())); qCDebug(pApp, "Build revision: %s", BUILD_REVISION); qCDebug(pApp, "%s", qUtf8Printable(buildCompatibilityString())); @@ -443,6 +466,22 @@ void VPApplication::InitOptions() m_shortcutManager = new VPuzzleShortcutManager(this); } +//--------------------------------------------------------------------------------------------------------------------- +void VPApplication::StartLogging() +{ + if (CreateLogDir()) + { + BeginLogging(); + ClearOldLogs(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPApplication::LogFile() -> QTextStream * +{ + return m_out.get(); +} + //--------------------------------------------------------------------------------------------------------------------- auto VPApplication::TrVars() -> const VTranslateVars * { @@ -723,6 +762,38 @@ auto VPApplication::SingleStart(const VPCommandLinePtr &cmd, const QStringList & return true; } +//--------------------------------------------------------------------------------------------------------------------- +auto VPApplication::LogPath() -> QString +{ + // Keep in sync with VCrashPaths::GetAttachmentPath + return QStringLiteral("%1/puzzle-pid%2.log").arg(LogDirPath()).arg(applicationPid()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPApplication::BeginLogging() +{ + VlpCreateLock(m_lockLog, LogPath(), []() { return new QFile(LogPath()); }); + + if (m_lockLog->IsLocked()) + { + if (m_lockLog->GetProtected()->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) + { + m_out.reset(new QTextStream(m_lockLog->GetProtected().data())); + qInstallMessageHandler(noisyFailureMsgHandler); + qCDebug(pApp, "Log file %s was locked.", qUtf8Printable(LogPath())); + } + else + { + qCDebug(pApp, "Error opening log file \'%s\'. All debug output redirected to console.", + qUtf8Printable(LogPath())); + } + } + else + { + qCDebug(pApp, "Failed to lock %s", qUtf8Printable(LogPath())); + } +} + //--------------------------------------------------------------------------------------------------------------------- auto VPApplication::CommandLine() -> VPCommandLinePtr { diff --git a/src/app/puzzle/vpapplication.h b/src/app/puzzle/vpapplication.h index 92c8b5164..924606dab 100644 --- a/src/app/puzzle/vpapplication.h +++ b/src/app/puzzle/vpapplication.h @@ -30,6 +30,7 @@ #include "../vmisc/def.h" #include "../vmisc/vabstractapplication.h" +#include "../vmisc/vlockguard.h" #include "vpcommandline.h" #include "vpsettings.h" @@ -62,6 +63,9 @@ public: void InitOptions(); + void StartLogging(); + auto LogFile() -> QTextStream *; + auto TrVars() -> const VTranslateVars * override; void OpenSettings() override; @@ -95,6 +99,8 @@ private: QList> m_mainWindows{}; QLocalServer *m_localServer{nullptr}; QWeakPointer m_preferencesDialog{}; + QSharedPointer> m_lockLog{}; + std::shared_ptr m_out{nullptr}; void Clean(); @@ -102,6 +108,9 @@ private: auto StartWithFiles(const VPCommandLinePtr &cmd, const QStringList &rawLayouts) -> bool; auto SingleStart(const VPCommandLinePtr &cmd, const QStringList &rawLayouts) -> bool; + + static auto LogPath() -> QString; + void BeginLogging(); }; #endif // VPAPPLICATION_H diff --git a/src/app/tape/mapplication.cpp b/src/app/tape/mapplication.cpp index 0c4ac7bd3..4e0f89146 100644 --- a/src/app/tape/mapplication.cpp +++ b/src/app/tape/mapplication.cpp @@ -35,7 +35,6 @@ #include "../ifc/exception/vexceptionwrongid.h" #include "../qmuparser/qmuparsererror.h" #include "../vformat/knownmeasurements/vknownmeasurementsdatabase.h" -#include "../vganalytics/def.h" #include "../vganalytics/vganalytics.h" #include "../vmisc/projectversion.h" #include "../vmisc/qt_dispatch/qt_dispatch.h" @@ -66,7 +65,6 @@ #include #include #include -#include #if !defined(BUILD_REVISION) && defined(QBS_BUILD) #include @@ -197,29 +195,55 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con logMsg = logMsg.remove(VAbstractApplication::warningMessageSignature); } - switch (type) { - case QtDebugMsg: - vStdOut() << QApplication::translate("mNoisyHandler", "DEBUG:") << logMsg << "\n"; - return; - case QtWarningMsg: - vStdErr() << QApplication::translate("mNoisyHandler", "WARNING:") << logMsg << "\n"; - break; - case QtCriticalMsg: - vStdErr() << QApplication::translate("mNoisyHandler", "CRITICAL:") << logMsg << "\n"; - break; - case QtFatalMsg: - vStdErr() << QApplication::translate("mNoisyHandler", "FATAL:") << logMsg << "\n"; - break; - case QtInfoMsg: - vStdOut() << QApplication::translate("mNoisyHandler", "INFO:") << logMsg << "\n"; - break; - default: - break; - } + QString debugdate = "["_L1 + QDateTime::currentDateTime().toString(QStringLiteral("yyyy.MM.dd hh:mm:ss")); - vStdOut().flush(); - vStdErr().flush(); + switch (type) + { + case QtDebugMsg: + debugdate += QStringLiteral(":DEBUG:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, logMsg); + vStdOut() << QApplication::translate("mNoisyHandler", "DEBUG:") << logMsg << "\n"; + break; + case QtWarningMsg: + debugdate += QStringLiteral(":WARNING:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, logMsg); + vStdErr() << QApplication::translate("mNoisyHandler", "WARNING:") << logMsg << "\n"; + break; + case QtCriticalMsg: + debugdate += QStringLiteral(":CRITICAL:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, logMsg); + vStdErr() << QApplication::translate("mNoisyHandler", "CRITICAL:") << logMsg << "\n"; + break; + case QtFatalMsg: + debugdate += QStringLiteral(":FATAL:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, logMsg); + vStdErr() << QApplication::translate("mNoisyHandler", "FATAL:") << logMsg << "\n"; + break; + case QtInfoMsg: + debugdate += QStringLiteral(":INFO:%1(%2)] %3: %4: %5") + .arg(context.file) + .arg(context.line) + .arg(context.function, context.category, logMsg); + vStdOut() << QApplication::translate("mNoisyHandler", "INFO:") << logMsg << "\n"; + break; + default: + break; + } + + vStdOut().flush(); + vStdErr().flush(); + + (*MApplication::VApp()->LogFile()) << debugdate << Qt::endl; + } if (isGuiThread) { @@ -247,8 +271,6 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con messageBox.setIcon(QMessageBox::Information); break; case QtDebugMsg: - Q_UNREACHABLE(); //-V501 - break; default: break; } @@ -450,10 +472,10 @@ auto MApplication::MainTapeWindows() -> QList //--------------------------------------------------------------------------------------------------------------------- void MApplication::InitOptions() { - qInstallMessageHandler(noisyFailureMsgHandler); - OpenSettings(); + StartLogging(); + qCDebug(mApp, "Version: %s", qUtf8Printable(AppVersionStr())); qCDebug(mApp, "Build revision: %s", BUILD_REVISION); qCDebug(mApp, "%s", qUtf8Printable(buildCompatibilityString())); @@ -484,6 +506,22 @@ void MApplication::InitOptions() m_shortcutManager = new VTapeShortcutManager(this); } +//--------------------------------------------------------------------------------------------------------------------- +void MApplication::StartLogging() +{ + if (CreateLogDir()) + { + BeginLogging(); + ClearOldLogs(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +auto MApplication::LogFile() -> QTextStream * +{ + return m_out.get(); +} + //--------------------------------------------------------------------------------------------------------------------- void MApplication::InitTrVars() { @@ -722,6 +760,38 @@ void MApplication::RestartKnownMeasurementsDatabaseWatcher() } } +//--------------------------------------------------------------------------------------------------------------------- +auto MApplication::LogPath() -> QString +{ + // Keep in sync with VCrashPaths::GetAttachmentPath + return QStringLiteral("%1/tape-pid%2.log").arg(LogDirPath()).arg(applicationPid()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void MApplication::BeginLogging() +{ + VlpCreateLock(m_lockLog, LogPath(), []() { return new QFile(LogPath()); }); + + if (m_lockLog->IsLocked()) + { + if (m_lockLog->GetProtected()->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) + { + m_out.reset(new QTextStream(m_lockLog->GetProtected().data())); + qInstallMessageHandler(noisyFailureMsgHandler); + qCDebug(mApp, "Log file %s was locked.", qUtf8Printable(LogPath())); + } + else + { + qCDebug(mApp, "Error opening log file \'%s\'. All debug output redirected to console.", + qUtf8Printable(LogPath())); + } + } + else + { + qCDebug(mApp, "Failed to lock %s", qUtf8Printable(LogPath())); + } +} + //--------------------------------------------------------------------------------------------------------------------- auto MApplication::NewMainTapeWindow() -> TMainWindow * { diff --git a/src/app/tape/mapplication.h b/src/app/tape/mapplication.h index 276fe4e2c..a98f32869 100644 --- a/src/app/tape/mapplication.h +++ b/src/app/tape/mapplication.h @@ -30,6 +30,7 @@ #define MAPPLICATION_H #include "../vmisc/vabstractapplication.h" +#include "../vmisc/vlockguard.h" #include "../vpatterndb/vtranslatevars.h" #include "dialogs/dialogmdatabase.h" #include "vtapesettings.h" @@ -71,6 +72,9 @@ public: void InitOptions(); + void StartLogging(); + auto LogFile() -> QTextStream *; + auto TrVars() -> const VTranslateVars * override; void OpenSettings() override; @@ -113,6 +117,8 @@ private: VKnownMeasurementsDatabase *m_knownMeasurementsDatabase{nullptr}; QFileSystemWatcher *m_knownMeasurementsDatabaseWatcher{nullptr}; QFutureWatcher *m_knownMeasurementsRepopulateWatcher; + QSharedPointer> m_lockLog{}; + std::shared_ptr m_out{nullptr}; void CleanTapeWindows(); void CleanKMWindows(); @@ -131,6 +137,9 @@ private: static void ParseUnitsOption(QCommandLineParser &parser, Unit &unit, bool &flagUnits); void RestartKnownMeasurementsDatabaseWatcher(); + + static auto LogPath() -> QString; + void BeginLogging(); }; //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/valentina/core/vapplication.cpp b/src/app/valentina/core/vapplication.cpp index 1dc9c6695..e6cb7797d 100644 --- a/src/app/valentina/core/vapplication.cpp +++ b/src/app/valentina/core/vapplication.cpp @@ -224,7 +224,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con } { - QString debugdate = "[" + QDateTime::currentDateTime().toString(QStringLiteral("yyyy.MM.dd hh:mm:ss")); + QString debugdate = "["_L1 + QDateTime::currentDateTime().toString(QStringLiteral("yyyy.MM.dd hh:mm:ss")); switch (type) { @@ -572,7 +572,6 @@ void VApplication::InitOptions() { OpenSettings(); - // Run creation log after sending crash report StartLogging(); qDebug() << "Version:" << AppVersionStr();