diff --git a/CMakeLists.txt b/CMakeLists.txt index 90f175a..bb1f31f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,6 +167,13 @@ add_executable( ${SOURCE_FILES} ) +if (CMAKE_BUILD_TYPE) + string(TOLOWER ${CMAKE_BUILD_TYPE} BUILD_TYPE) + if (${BUILD_TYPE} STREQUAL "debug") + target_compile_definitions(${PROJECT_NAME} PRIVATE UKUI_MENU_LOG_FILE_DISABLE) + endif () +endif () + target_compile_definitions(${PROJECT_NAME} PRIVATE $<$,$>:QT_QML_DEBUG>) target_link_libraries(${PROJECT_NAME} PRIVATE diff --git a/src/main.cpp b/src/main.cpp index d5e3120..45e2a0f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,12 +3,127 @@ #include #include #include +#include +#include +#include #include "qtsingleapplication.h" #include "ukui-menu-application.h" +#define LOG_FILE_COUNT 2 +#define MAX_LOG_FILE_SIZE 4194304 +#define MAX_LOG_CHECK_INTERVAL 43200000 + +static int logFileId = -1; +static QString logFile = "ukui-menu.log"; +static QString logFilePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.log/ukui-menu/"; +static QString logFileName = logFilePath + "ukui-menu-%1.log"; +static quint64 startupTime; + +bool checkFileSize(const QString &fileName) { + return QFile(fileName).size() < MAX_LOG_FILE_SIZE; +} + +void clearFile(const QString &fileName) { + QFile file(fileName); + file.open(QIODevice::WriteOnly); + file.write(""); + file.flush(); + file.close(); +} + +void initLogFile() { + QDir dir; + if (!dir.exists(logFilePath)) { + if (!dir.mkpath(logFilePath)) { + qWarning() << "Unable to create" << logFilePath; + return; + } + } + + for (int i = 0; i < LOG_FILE_COUNT; ++i) { + logFile = logFileName.arg(i); + if (QFile::exists(logFile)) { + if (checkFileSize(logFile)) { + logFileId = i; + break; + } + } else { + QFile file(logFile); + file.open(QIODevice::WriteOnly); + file.close(); + } + } + + if (logFileId < 0) { + logFileId = 0; + logFile = logFileName.arg(logFileId); + clearFile(logFile); + } + + qInfo() << "init log file:" << logFile; +} + +void checkLogFile() { + quint64 logTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + quint64 spacing = std::max(logTime, startupTime) - std::min(logTime, startupTime); + + if (spacing <= MAX_LOG_CHECK_INTERVAL || checkFileSize(logFile)) { + return; + } + + logFileId = ((logFileId + 1) % LOG_FILE_COUNT); + logFile = logFileName.arg(logFileId); + if (!checkFileSize(logFile)) { + clearFile(logFile); + } +} + +void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + checkLogFile(); + + QByteArray localMsg = msg.toLocal8Bit(); + QByteArray currentTime = QTime::currentTime().toString().toLocal8Bit(); + const char *file = context.file ? context.file : ""; + const char *function = context.function ? context.function : ""; + + FILE *log_file = fopen(logFile.toLocal8Bit().constData(), "a+"); + + switch (type) { + case QtDebugMsg: + if (!log_file) { + break; + } + fprintf(log_file, "Debug: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtInfoMsg: + fprintf(log_file? log_file: stdout, "Info: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtWarningMsg: + fprintf(log_file? log_file: stderr, "Warning: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtCriticalMsg: + fprintf(log_file? log_file: stderr, "Critical: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtFatalMsg: + fprintf(log_file? log_file: stderr, "Fatal: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + } + + if (log_file) { + fclose(log_file); + } +} + int main(int argc, char *argv[]) { + startupTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + initLogFile(); +#ifndef UKUI_MENU_LOG_FILE_DISABLE + qInstallMessageHandler(messageOutput); +#endif + #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) // SideBarApplication::setAttribute(Qt::AA_DisableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); @@ -49,5 +164,7 @@ int main(int argc, char *argv[]) QObject::connect(&app, &QtSingleApplication::messageReceived, &messageProcessor, &UkuiMenu::MenuMessageProcessor::processMessage); + qInfo() << "ukui-menu startup time:" << (QDateTime::currentDateTime().toMSecsSinceEpoch() - startupTime) + << ",date:" << QDateTime::currentDateTime().toString(); return QtSingleApplication::exec(); } diff --git a/src/ukui-menu-application.cpp b/src/ukui-menu-application.cpp index 63e2718..d8f6d89 100644 --- a/src/ukui-menu-application.cpp +++ b/src/ukui-menu-application.cpp @@ -17,6 +17,7 @@ */ #include "ukui-menu-application.h" +#include "menu-dbus-service.h" #include "settings.h" #include "commons.h" #include "model-manager.h" @@ -33,6 +34,7 @@ #include #include #include +#include #include using namespace UkuiMenu; diff --git a/src/ukui-menu-application.h b/src/ukui-menu-application.h index b7b346e..da1d71e 100644 --- a/src/ukui-menu-application.h +++ b/src/ukui-menu-application.h @@ -19,15 +19,16 @@ #ifndef UKUI_MENU_UKUI_MENU_APPLICATION_H #define UKUI_MENU_UKUI_MENU_APPLICATION_H -#include "menu-dbus-service.h" -#include +#include +class QQmlEngine; class QCommandLineOption; namespace UkuiMenu { class MenuMessageProcessor; class MenuWindow; +class MenuDbusService; class UkuiMenuApplication : public QObject {