Directly Embedding spdlog Source Code in Qt Projects

1. Obtaining spdlog Source Files

Download the spdlog repository from GitHub and extract vertion 1.15.3. Copy the include and src directories into a third_party/spdlog folder within your Qt project.

Project structure:

qt_app/
├── qt_app.pro
├── main.cpp
├── ...
└── third_party/
    └── spdlog/
        ├── include/
        │   └── spdlog/
        └── src/

2. Updating the .pro File

Add the following configuration to your .pro file:

CONFIG += c++11

INCLUDEPATH += $$PWD/third_party/spdlog/include

DEFINES += SPDLOG_COMPILED_LIB

SOURCES += \
    third_party/spdlog/src/async.cpp \
    third_party/spdlog/src/bundled_fmtlib_format.cpp \
    third_party/spdlog/src/cfg.cpp \
    third_party/spdlog/src/color_sinks.cpp \
    third_party/spdlog/src/file_sinks.cpp \
    third_party/spdlog/src/spdlog.cpp \
    third_party/spdlog/src/stdout_sinks.cpp \

3. Implementing the Logging Service

3.1 LoggerHeader.h

#ifndef LOGGERHEADER_H
#define LOGGERHEADER_H

#include <QString>
#include <spdlog/spdlog.h>

class LoggerHeader
{
public:
    LoggerHeader();

    void initialize();
    void cleanup();

    inline void trace(const QString &msg)
    {
        spdlog::trace(msg.toStdString().c_str());
    }

    inline void debug(const QString &msg)
    {
        spdlog::debug(msg.toStdString().c_str());
    }

    inline void info(const QString &msg)
    {
        spdlog::info(msg.toStdString().c_str());
    }

    inline void warn(const QString &msg)
    {
        spdlog::warn(msg.toStdString().c_str());
    }

    inline void error(const QString &msg)
    {
        spdlog::error(msg.toStdString().c_str());
    }

    inline void critical(const QString &msg)
    {
        spdlog::critical(msg.toStdString().c_str());
    }
};

#endif // LOGGERHEADER_H

3.2 LoggerHeader.cpp

#include <QDir>
#include <QMessageBox>
#include <QString>

#include <spdlog/spdlog.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/async.h>

#include "LoggerHeader.h"

LoggerHeader::LoggerHeader()
{

}

void LoggerHeader::initialize()
{
    try
    {
        // Ensure log directory exists
        QDir logDirectory("logs");
        if (!logDirectory.exists() && !logDirectory.mkpath("."))
        {
            QMessageBox::critical(nullptr, "Logging Error", "Failed to create logs directory");
            return;
        }

        // Configure thread pool for async operations
        spdlog::init_thread_pool(8192, 1);

        // Auto-flush every 5 seconds
        spdlog::flush_every(std::chrono::seconds(5));

        // Initialize rotating file sink (5MB max per file, 100 files retained)
        auto rotatingSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
                    "logs/application.log", 1024 * 1024 * 5, 100);

        // Initialize colored console output
        auto consoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();

        // Combine both sinks
        std::vector<spdlog::sink_ptr> allSinks{rotatingSink, consoleSink};

        // Create async logger with combined sinks
        auto asyncLogger = std::make_shared<spdlog::async_logger>(
                    "app_logger",
                    allSinks.begin(),
                    allSinks.end(),
                    spdlog::thread_pool(),
                    spdlog::async_overflow_policy::block
                    );

        // Set timestamp format
        asyncLogger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [thread %t] %v");

        // Register as default logger
        spdlog::set_default_logger(asyncLogger);

        // Set log level based on build configuration
#ifdef QT_DEBUG
        spdlog::set_level(spdlog::level::debug);
#else
        spdlog::set_level(spdlog::level::info);
#endif

        // Force immediate write on errors
        asyncLogger->flush_on(spdlog::level::err);

        spdlog::info("====== Application startup ======");
        spdlog::debug("Debug logging is enabled");

        // Display Qt version
        spdlog::info("Current Qt version: {}", qVersion());

        // Display spdlog version
        auto libraryVersion = QString("%1.%2.%3")
            .arg(QString::number(SPDLOG_VER_MAJOR),
                 QString::number(SPDLOG_VER_MINOR),
                 QString::number(SPDLOG_VER_PATCH))
            .toStdString();
        spdlog::info("Current spdlog version: {}", libraryVersion.c_str());
    }
    catch (const spdlog::spdlog_ex &ex)
    {
        QMessageBox::critical(nullptr, "Initialization Error",
                              QString("Failed to initialize logging system: %1").arg(ex.what()));
    }
}

void LoggerHeader::cleanup()
{
    spdlog::info("====== Application shutdown ======");
    spdlog::shutdown();
}

4. Consuming the Logging Service

4.1 PrimaryWindow.h

#ifndef PRIMARYWINDOW_H
#define PRIMARYWINDOW_H

#include <QMainWindow>
#include "LoggerHeader.h"

class PrimaryWindow : public QMainWindow
{
    Q_OBJECT

public:
    PrimaryWindow(QWidget *parent = nullptr);
    ~PrimaryWindow();

private:
    LoggerHeader *m_logger;
};
#endif // PRIMARYWINDOW_H

4.2 PrimaryWindow.cpp

#include "primarywindow.h"

PrimaryWindow::PrimaryWindow(QWidget *parent)
    : QMainWindow(parent)
{
    m_logger = new LoggerHeader();
    m_logger->initialize();
}

PrimaryWindow::~PrimaryWindow()
{
    m_logger->cleanup();
    delete m_logger;
}

Notes

  • spdlog requires C++11 or latter. Ensure your .pro file specifies the appropriate standard.
  • The SPDLOG_COMPILED_LIB define must be set when using source compilation rather than header-only mode.
  • Async logging prevents I/O operations from blocking the main thread.
  • Log files are automatically rotated when reaching the 5MB threshold, with up to 100 backup files retained.

Tags: Qt spdlog logging C++ embedded source

Posted on Sat, 04 Jul 2026 17:13:55 +0000 by efficacious