SoFunction
Updated on 2025-03-04

Qt implements scrolling writing of log files

Qt Scrolling writing of log files

flyfish

Scrolling writing function of log files. Create a new log file when the log file reaches 10MB, and start overwriting the earliest log file when the total log file size reaches 10GB

Take monitoring the writing logs of a folder as an example

Log file creation and management

Initialize log file: In the constructor of the FileMonitor class, the first log file will be created. The naming format of the log file is "file_monitor_serial number.log", and the initial sequence number is 0.

Scrolling writing mechanism

Single log file size limit: When writing content to the current log file so that its size reaches 10MB (set through the logFileSizeLimit variable, the value is 10 * 1024 * 1024 bytes), the current log file is closed, the log file index is added, and a new log file is created for subsequent logging.

Total log file size limit

At the same time, the overall size of all log files will be monitored. When the total size reaches 10GB (set through the totalLogSizeLimit variable, the value is 10 * 1024 * 1024 bytes), the earliest created log file will be deleted (by calculating the file name of the earliest log file and determining whether it exists, and delete it if it exists) to ensure that the total log file size does not grow unlimitedly.

Log content record

For events such as file creation, deletion, and modification, the current date and time of the event (format is "yyyy-MM-dd hh:mm:ss"), event type (such as "File created", "File deleted", "File modified") and related file path information will be written to the currently used log file in a specific format. And the buffer will be refreshed immediately after each write to ensure that the log content is written to the file in time. At the same time, the current log file size information will be updated in real time to determine whether the single log file size limit is reached.

#include <QCoreApplication>
#include <QFileSystemWatcher>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QDir>
#include <QFileInfo>
#include <QSet>
#include <iostream>

// The FileMonitor class inherits from QObject, is used to monitor file changes in the specified folder and record related logsclass FileMonitor : public QObject {
    Q_OBJECT

public:
    // Constructor, used to initialize file monitor-related parameters    explicit FileMonitor(const QString &path, QObject *parent = nullptr)
        : QObject(parent),
          // Create a file system monitor object and use it as a child object of the current object          watcher(new QFileSystemWatcher(this)),
          rootPath(path),
          // Set the size limit of a single log file to 10MB, here to convert 10MB to bytes          logFileSizeLimit(static_cast<quint64>(10) * 1024 * 1024),
          // Set the total log file size limit to 10GB, and convert it to bytes.          totalLogSizeLimit(static_cast<quint64>(10) * 1024 * 1024 * 1024),
          currentLogFileIndex(0),
          currentLogFileSize(0) {

        // Add the specified monitoring path to the file system monitor        watcher->addPath(rootPath);

        // Get the initial file list under the monitoring path        QDir dir(rootPath);
        initialFiles = (QDir::Files);

        // Connect the directory change signal of the file system monitor to the corresponding slot function        connect(watcher, &QFileSystemWatcher::directoryChanged, this, &FileMonitor::onDirectoryChanged);
        // Connect the file change signal of the file system monitor to the corresponding slot function        connect(watcher, &QFileSystemWatcher::fileChanged, this, &FileMonitor::onFileChanged);

        // Initialize the log file and create the first log file        createNewLogFile();
    }

private slots:
    // The slot function called when the monitored directory changes    void onDirectoryChanged(const QString &path) {
        std::cout << "Directory changed: " << qPrintable(path) << std::endl;

        // Get the file list in the current monitoring directory        QDir dir(rootPath);
        QStringList currentFiles = (QDir::Files);

        // Find out the newly added files and implement them through collection operations        QSet<QString> newFiles = QSet<QString>((), ()).subtract(QSet<QString>((), ()));
        // traverse the newly added files and record the file creation events to the log        for (const QString &file : newFiles) {
            logEvent("File created", (file));
        }

        // Find the deleted file, and use the same set operation        QSet<QString> deletedFiles = QSet<QString>((), ()).subtract(QSet<QString>((), ()));
        // traverse the deleted files and record file deletion events to the log        for (const QString &file : deletedFiles) {
            logEvent("File deleted", (file));
        }

        // Update the initial file list to the current file list so that the file changes will be detected next time        initialFiles = currentFiles;
    }

    // The slot function called when the monitored file changes    void onFileChanged(const QString &path) {
        std::cout << "File changed: " << qPrintable(path) << std::endl;
        // Record file modification events to log        logEvent("File modified", path);
    }

private:
    // Function to create a new log file    void createNewLogFile() {
        // Construct a new log file name, format: file_monitor_serial number.log        QString logFileName = "file_monitor_" + QString::number(currentLogFileIndex) + ".log";
        (logFileName);

        // If the log file already exists, get its size and update the current log file size variable        if (()) {
            currentLogFileSize = ();
        } else {
            currentLogFileSize = 0;
        }

        // Open or create a log file, and output an error message if it fails        if (!(QIODevice::Append | QIODevice::Text)) {
            std::cerr << "Failed to open/create log file: " << qPrintable(logFileName) << std::endl;
        }
    }

    // Function to record log events    void logEvent(const QString &event, const QString &path) {
        // Create a text stream object to write content to the current log file        QTextStream out(&currentLogFile);
        // Write current date, event type and file path information to the log file        out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")
            << " - " << event << ": " << path << "\n";
        ();

        // Calculate the size of the log string just written, and read the contents in the text stream first        QString logString = ();
        // If the read is empty, it may be because the write has not been cached yet. Reconstruct the log string.        if (()) {
            logString = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")
                        + " - " + event + ": " + path + "\n";
        }

        // Update the size of the current log file, convert the log string to UTF-8 encoding and calculate its bytes and accumulate it to the current log file size variable        currentLogFileSize += logString.toUtf8().size();

        // Check whether the current log file size reaches the single log file size limit        if (currentLogFileSize >= logFileSizeLimit) {
            // Close the current log file            ();

            // Add log file index to create the next new log file            ++currentLogFileIndex;

            // Check whether the total log file size limit is exceeded. If it exceeds, delete the earliest log file            if (currentLogFileIndex * logFileSizeLimit > totalLogSizeLimit) {
                QString oldestLogFileName = "file_monitor_" + QString::number(currentLogFileIndex - totalLogSizeLimit / logFileSizeLimit) + ".doc";
                if (QFile::exists(oldestLogFileName)) {
                    QFile::remove(oldestLogFileName);
                }
            }

            // Create a new log file            createNewLogFile();
        }
    }

    // File system monitor object, used to monitor file and directory changes under specified paths    QFileSystemWatcher *watcher;
    // The root path of monitoring    QString rootPath;
    // The initial file list is used to compare and detect files' addition and deletion    QStringList initialFiles;

    // The following are the newly added log management related member variables
    // The log file object currently in use    QFile currentLogFile;
    // The size limit of a single log file, in bytes    quint64 logFileSizeLimit;
    // Total log file size limit, unit in bytes    quint64 totalLogSizeLimit;
    // The index of the current log file is used to distinguish different log files    quint64 currentLogFileIndex;
    // The current log file size is bytes, used to monitor whether the file size reaches the limit in real time    quint64 currentLogFileSize;
};

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // Get command line parameters, if there are parameters, use them as monitoring path, otherwise the default monitoring root directory is monitored    QString watchPath = (argc > 1)? QString::fromLocal8Bit(argv[1]) : "/";

    // Create a file monitoring object and pass it in the monitoring path    FileMonitor monitor(watchPath);

    // Run the application event loop, start monitoring file and directory changes and logging    return ();
}

#include ""

This is the end of this article about Qt implementing scroll writing of log files. For more relevant Qt log files, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!