123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- #include "Logger.h"
- #include <QDebug>
- #include <QDir>
- #include <QFileInfo>
- // Initialize static members
- QScopedPointer<Logger> Logger::m_instance; // Correct: Default constructs to a null pointer
- QMutex Logger::m_instanceMutex;
- Logger& Logger::getInstance(const QString &filePath)
- {
- // Use a QMutexLocker to ensure thread-safe initialization of the singleton
- QMutexLocker locker(&m_instanceMutex);
- if (m_instance.isNull()) {
- if (filePath.isEmpty()) {
- qWarning() << "Logger: No file path provided for initial singleton creation. Logging might be disabled.";
- // Fallback to a default or disable logging, or throw an error.
- // For simplicity, we'll proceed but warn.
- m_instance.reset(new Logger("default.log")); // Provide a default if not given
- } else {
- m_instance.reset(new Logger(filePath));
- }
- }
- return *m_instance;
- }
- // Private constructor
- Logger::Logger(const QString &filePath)
- : m_logFile(filePath),
- m_textStream(&m_logFile),
- m_maxFileSize(10 * 1024 * 1024), // Default to 10 MB
- m_maxBackupFiles(5) // Default to 5 backup files
- {
- QFileInfo fileInfo(filePath);
- QDir dir = fileInfo.absoluteDir();
- if (!dir.exists()) {
- dir.mkpath("."); // Create directory if it doesn't exist
- }
- if (!m_logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
- qWarning() << "Logger: Could not open log file for writing:" << m_logFile.errorString();
- } else {
- info("Logger initialized."); // Log the initialization
- }
- }
- // Private destructor
- Logger::~Logger()
- {
- if (m_logFile.isOpen()) {
- info("Logger shutting down."); // Log shutdown
- m_logFile.close();
- }
- }
- void Logger::debug(const QString &message)
- {
- writeLog(Debug, message);
- }
- void Logger::info(const QString &message)
- {
- writeLog(Info, message);
- }
- void Logger::warn(const QString &message)
- {
- writeLog(Warning, message);
- }
- void Logger::error(const QString &message)
- {
- writeLog(Error, message);
- }
- void Logger::critical(const QString &message)
- {
- writeLog(Critical, message);
- }
- void Logger::writeLog(LogLevel level, const QString &message)
- {
- QMutexLocker locker(&m_mutex);
- if (!m_logFile.isOpen()) {
- qWarning() << "Logger: Log file is not open. Message not written:" << message;
- return;
- }
- if (m_logFile.size() > m_maxFileSize) {
- rotateLogFile();
- }
- QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
- QString logLevelStr = logLevelToString(level);
- m_textStream << QString("[%1] [%2] %3\n").arg(timestamp).arg(logLevelStr).arg(message);
- m_textStream.flush();
- }
- void Logger::setMaxFileSize(qint64 bytes)
- {
- m_maxFileSize = bytes;
- }
- void Logger::setMaxBackupFiles(int count)
- {
- m_maxBackupFiles = count;
- }
- void Logger::rotateLogFile()
- {
- m_logFile.close();
- QFileInfo fileInfo(m_logFile.fileName());
- QString baseName = fileInfo.baseName();
- QString suffix = fileInfo.suffix();
- QString absolutePath = fileInfo.absolutePath();
- for (int i = m_maxBackupFiles - 1; i >= 0; --i) {
- QString oldLogFileName = QString("%1/%2.%3.%4").arg(absolutePath).arg(baseName).arg(i).arg(suffix);
- QFile oldLogFile(oldLogFileName);
- if (oldLogFile.exists()) {
- if (i == m_maxBackupFiles - 1) {
- oldLogFile.remove();
- } else {
- QString newLogFileName = QString("%1/%2.%3.%4").arg(absolutePath).arg(baseName).arg(i + 1).arg(suffix);
- oldLogFile.rename(newLogFileName);
- }
- }
- }
- QString newCurrentLogFileName = QString("%1/%2.%3.%4").arg(absolutePath).arg(baseName).arg(0).arg(suffix);
- m_logFile.rename(newCurrentLogFileName);
- if (!m_logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
- qWarning() << "Logger: Could not reopen log file after rotation:" << m_logFile.errorString();
- }
- }
- QString Logger::logLevelToString(LogLevel level) const
- {
- switch (level) {
- case Debug:
- return "DEBUG";
- case Info:
- return "INFO";
- case Warning:
- return "WARNING";
- case Error:
- return "ERROR";
- case Critical:
- return "CRITICAL";
- default:
- return "UNKNOWN";
- }
- }
|