#ifndef QLOGMANAGER_H #define QLOGMANAGER_H #include #include #include #include #include #include #include #include #include #include #include #include class QLogManager : public QObject { Q_OBJECT public: enum LogLevel { SQ_DEBUG = 0, SQ_INFO, SQ_WARNING, SQ_ERROR, SQ_FATAL }; static QLogManager* Instance(); static void destroyInstance(); void setLogLevel(LogLevel level); void log(LogLevel level, const QString& message, const QString& module = QString()); void flush(); signals: void newLog(LogLevel level, const QString& message); protected: explicit QLogManager(QObject* parent = nullptr); ~QLogManager() override; private: void processLogs(); void writeToFile(LogLevel level, const QString& logLine); void rotateLogFile(LogLevel level); void cleanOldLogs(); QString getLogFileName(LogLevel level); struct LogEntry { LogLevel level; QString message; qint64 timestamp; }; class ThreadSafeQueue { public: void enqueue(const LogEntry& entry) { QMutexLocker locker(&m_mutex); m_queue.enqueue(entry); } bool dequeue(LogEntry& entry) { QMutexLocker locker(&m_mutex); if (m_queue.isEmpty()) { return false; } entry = m_queue.dequeue(); return true; } bool isEmpty() const { QMutexLocker locker(&m_mutex); return m_queue.isEmpty(); } private: QQueue m_queue; mutable QMutex m_mutex; }; static QBasicAtomicPointer s_instance; static QMutex s_mutex; QDir m_logDirectory; LogLevel m_minLevel; QThread* m_workerThread; QSemaphore m_queueSemaphore; ThreadSafeQueue m_logQueue; QMap> m_openFiles; bool m_running; static const int MAX_LOG_DAYS = 7; static const qint64 MAX_FILE_SIZE = 10 * 1024 * 1024; static const int TIMESTAMP_CACHE_DURATION_MS = 100; }; #define LOG_DEBUG(message) QLogManager::Instance()->log(QLogManager ::SQ_DEBUG, message, QString("%1::%2").arg(__FILE__).arg(__LINE__)) #define LOG_INFO(message) QLogManager::Instance()->log(QLogManager ::SQ_INFO, message) #define LOG_WARNING(message) QLogManager::Instance()->log(QLogManager ::SQ_WARNING, message) #define LOG_ERROR(message) QLogManager::Instance()->log(QLogManager ::SQ_ERROR, message) #define LOG_FATAL(message) QLogManager::Instance()->log(QLogManager ::SQ_FATAL, message) #endif