diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 99ac68c..162b826 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -11,6 +11,8 @@ qt_add_executable(EventConfigurator mainwindow.cpp mainwindow.h mainwindow.ui + logger.h logger.cpp + settings.h settings.cpp ) target_link_libraries(EventConfigurator diff --git a/apps/conf/config.ini b/apps/conf/config.ini new file mode 100644 index 0000000..139597f --- /dev/null +++ b/apps/conf/config.ini @@ -0,0 +1,2 @@ + + diff --git a/apps/logger.cpp b/apps/logger.cpp new file mode 100644 index 0000000..1b33928 --- /dev/null +++ b/apps/logger.cpp @@ -0,0 +1,59 @@ +#include "logger.h" +#include "settings.h" +#include +#include + +QString Logging::fileName = "../logs/EventConfigurator.log"; +qint64 Logging::maxFileSize = 1024 *1024 * 10; +int Logging::maxBackupFiles = 5; +QString Logging::messagePattern = "[%{time yyyyMMdd h:mm:ss.zzz ttt} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}"; +QtMessageHandler Logging::originalHandler = nullptr; + +void Logging::setupLogging() +{ + fileName = Settings::instance().value("Log", "logFile").toString(); + messagePattern = Settings::instance().value("Log", "pattern").toString(); + maxFileSize = Settings::instance().value("Log", "maxSize").toLongLong(); + maxBackupFiles = Settings::instance().value("Log", "backups").toInt(); + qSetMessagePattern(messagePattern); + originalHandler = qInstallMessageHandler(Logging::logMessageHandler); +} + +void Logging::logMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + QString message = qFormatLogMessage(type, context, msg); + static FILE *f = fopen(Logging::fileName.toLocal8Bit().constData(), "a"); + if (f) { + fprintf(f, "%s\n", qPrintable(message)); + fflush(f); + } + else { + f = fopen(Logging::fileName.toLocal8Bit().constData(), "a"); + if (f) { + fprintf(f, "%s\n", qPrintable(message)); + fflush(f); + } + } + + struct stat st; + stat(Logging::fileName.toLocal8Bit().constData(), &st); + auto fileSize = st.st_size; + if(fileSize > Logging::maxFileSize) { + if (f) { + fclose(f); + f = nullptr; + } + rollLogFiles(); + } + + if (originalHandler) + (*originalHandler)(type, context, msg); +} + +void Logging::rollLogFiles() +{ + QFile::remove(QString("%1.%2").arg(Logging::fileName).arg(Logging::maxBackupFiles)); + for(int i = Logging::maxBackupFiles - 1; i > 0; i--) + QFile::rename(QString("%1.%2").arg(Logging::fileName).arg(i), QString("%1.%2").arg(Logging::fileName).arg(i + 1)); + QFile::rename(Logging::fileName, QString("%1.1").arg(Logging::fileName)); +} diff --git a/apps/logger.h b/apps/logger.h new file mode 100644 index 0000000..7020d2c --- /dev/null +++ b/apps/logger.h @@ -0,0 +1,35 @@ +#ifndef LOGGER_H +#define LOGGER_H + +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(Application) +Q_DECLARE_LOGGING_CATEGORY(Window) + + +class Logging: public QObject +{ + Q_OBJECT + +public: + static void setupLogging(); + static void logMessageHandler(QtMsgType, const QMessageLogContext &, const QString &); + +private: + static void rollLogFiles(); + +private: + static qint64 maxFileSize; + static int maxBackupFiles; + +private: + static QString fileName; + static QString messagePattern; + static QtMessageHandler originalHandler; + +}; + +#endif // LOGGER_H diff --git a/apps/main.cpp b/apps/main.cpp index fd3e533..050320a 100644 --- a/apps/main.cpp +++ b/apps/main.cpp @@ -1,10 +1,20 @@ +#include "logger.h" +#include "settings.h" #include "mainwindow.h" #include +Q_LOGGING_CATEGORY(Application, "Application") + int main(int argc, char *argv[]) { QApplication a(argc, argv); + + Logging::setupLogging(); + // qCInfo(Application) << "Application starts 程序启动"; + qCInfo(Application, "Application starts 程序启动"); + Settings::instance(); + MainWindow w; w.show(); return a.exec(); diff --git a/apps/mainwindow.cpp b/apps/mainwindow.cpp index 2740a6e..47ce592 100644 --- a/apps/mainwindow.cpp +++ b/apps/mainwindow.cpp @@ -1,10 +1,14 @@ +#include "logger.h" #include "mainwindow.h" #include "ui_mainwindow.h" +Q_LOGGING_CATEGORY(Window, "Window") + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { + qCDebug(Window) << "Window starts 窗口构建"; ui->setupUi(this); } diff --git a/apps/settings.cpp b/apps/settings.cpp new file mode 100644 index 0000000..9e95612 --- /dev/null +++ b/apps/settings.cpp @@ -0,0 +1,84 @@ +#include "settings.h" + +#include +#include +#include + +Settings& Settings::instance() +{ + static Settings instance; + return instance; +} + +Settings::Settings() +{ + m_settingsFile = QDir::cleanPath(QCoreApplication::applicationDirPath() + "/../conf/config.ini"); + + QFile file(m_settingsFile); + if (file.open(QIODevice::ReadWrite)) { + m_isVaildSettingsFile = true; + m_settings = new QSettings(m_settingsFile, QSettings::IniFormat); + } + else { + m_isVaildSettingsFile = false; + } +} + +Settings::~Settings() +{ + if (m_isVaildSettingsFile) { + delete m_settings; + } +} + +QVariant Settings::getDefaultValue(const QString& group, const QString& name) +{ + if(group == "Log" && name == "logFile") + return QDir::cleanPath(QCoreApplication::applicationDirPath() + "/../logs/EventConfigurator.log"); + else if(group == "Log" && name == "pattern") + return "[%{time yyyyMMdd h:mm:ss.zzz ttt} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}"; + else if(group == "Log" && name == "level") + return "DEBUG"; + else if(group == "Log" && name == "maxSize") + return 10485760; + else if(group == "Log" && name == "backups") + return 5; + else if(group == "Log" && name == "consoleOutput") + return "false"; + else if(group == "Log" && name == "fileOutput") + return "true"; + else + return QVariant(); +} + +void Settings::setValue(const QString& group, const QString& name, const QVariant& value) +{ + if(!m_isVaildSettingsFile) + return; + + m_settings->beginGroup(group); + m_settings->setValue(name, value); + m_settings->endGroup(); +} + +QVariant Settings::value(const QString& group, const QString& name) +{ + QVariant defaultVaule = getDefaultValue(group, name); + if(!m_isVaildSettingsFile) + return defaultVaule; + + QVariant value = m_settings->value(group + "/" + name, defaultVaule); + return value; +} + +void Settings::clearValue(const QString& group, const QString& name) +{ + m_settings->beginGroup(group); + m_settings->remove(name); + m_settings->endGroup(); +} + +bool Settings::contains(const QString& group, const QString& name) +{ + return m_settings->contains(group + "/" + name); +} diff --git a/apps/settings.h b/apps/settings.h new file mode 100644 index 0000000..3d34cea --- /dev/null +++ b/apps/settings.h @@ -0,0 +1,33 @@ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include +#include + +class Settings +{ +public: + static Settings& instance(); + +public: + void setValue(const QString& group, const QString& name, const QVariant& value); + QVariant value(const QString& group, const QString& name); + void clearValue(const QString& group, const QString& name); + bool contains(const QString& group, const QString& name); + +private: + QVariant getDefaultValue(const QString& group, const QString& name); + +private: + explicit Settings(); + ~Settings(); + Settings(const Settings&) = delete; + Settings& operator=(const Settings&) = delete; + +private: + QSettings* m_settings; + QString m_settingsFile; + bool m_isVaildSettingsFile; +}; + +#endif // SETTINGS_H