Logging In Qt

Qt doesn't have a native mechanism for logging. We can use the qDebug() for debug purposes, but it's not written to a file nor does it provide us with a clear separation of log levels. Luckily, some open source solutions are available.

In this article, I will present two such solutions: QsLog, which is a dedicated logging solution for Qt, and QxtLib, a more general extension library.
Because the interface is not too different between the two, I suggest you use QsLog if all you need is logging, but check out Qxtlib for it may have additional features that you find useful.

Using QsLog

This simple logging framework supports different log destinations using a single log interface. Here's a sample of how it works:

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

   // init the logging mechanism
   QsLogging::Logger& logger = QsLogging::Logger::instance();

   // set minimum log level and file name
   logger.setLoggingLevel(QsLogging::TraceLevel);
   const QString sLogPath(QDir(a.applicationDirPath()).filePath("log.txt"));

   // Create log destinations
   QsLogging::DestinationPtr fileDestination(
      QsLogging::DestinationFactory::MakeFileDestination(sLogPath) );
   QsLogging::DestinationPtr debugDestination(
      QsLogging::DestinationFactory::MakeDebugOutputDestination() );

   // set log destinations on the logger
   logger.addDestination(debugDestination.get());
   logger.addDestination(fileDestination.get());

// write an info message
   QLOG_INFO() << "Program started";  
   return 0;
}

Code is divided to an initialization section and a usage example. The initialization part defines logging destinations using one file and one debug output. All log messages will be written to both qDebug() and the log.txt file.

One thing to keep in mind, log destinations' ownership is not transferred to Logger, so log destinations must not be freed while the program is running. That's the reason they are created in main. If you intend to put it in a dedicated function, use new to create the destinations.

Writing to the log is performed with one of 6 macros:

QLOG_TRACE()
QLOG_DEBUG()
QLOG_INFO()
QLOG_WARN()
QLOG_ERROR()
QLOG_FATAL()

QsLog is a simple BSD licensed library, which gets the job done but has limited functionality. It is a good solution for small-medium sized projects.
Full source code is available from the project's bitbucket repository at: https://bitbucket.org/razvanpetru/qt-components/wiki/QsLog

Logging With QxtLib

The idea of libxqt is to provide the classes and abilities that are "missing" in Nokia's Qt core distribution. It is an external library that needs to be installed separately from Qt, but it is worth the time.

Here's how to use libxqt logging facilities to provide customizable Logger for your Qt application.

#include <QtCore/QCoreApplication>
#include <QxtBasicFileLoggerEngine>
#include <QxtLogger>

void setupLogger()
{
    QxtBasicFileLoggerEngine *dbg  = new QxtBasicFileLoggerEngine("debug.log");
    QxtBasicFileLoggerEngine *info = new QxtBasicFileLoggerEngine("info.log");

    // qxtLog takes ownership of dbg - no need to manage its memory
    qxtLog->addLoggerEngine("dbg", dbg);
    qxtLog->addLoggerEngine("app", info);

    qxtLog->disableAllLogLevels();

    qxtLog->enableLogLevels("dbg", QxtLogger::AllLevels);
    qxtLog->enableLogLevels("app",  QxtLogger::InfoLevel | QxtLogger::WarningLevel | QxtLogger::ErrorLevel | QxtLogger::CriticalLevel | QxtLogger::FatalLevel | QxtLogger::WriteLevel );
}

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

    setupLogger();

    // now we have a dbg logger, here's how to use it
    qxtLog->debug("Hello World !");
    qxtLog->info("App Started OK");

    qxtLog->debug("----- dbg x = 7");

    return a.exec();
}

For more info/doc on the library, visit its Bitbucket Page at: http://dev.libqxt.org/libqxt/wiki/user_guide