qt logging framework · 2015-03-17 · 1 qt logging framework all you ever wanted to know about...

71
Vol-xxxx urn:nbn:de:0074-xxx Copyright © 2015 for the individual papers by the papers' authors. Copying permitted for private and academic purposes. This volume is published and copyrighted by its editors. ENVIP'2015 (DRAFT) Environmental Infrastructures and Platforms 2015 - Infrastructures and Platforms for Environmental Crowd Sensing and Big Data Proceedings of the Workshop " Environmental Infrastructures and Platforms 2015 - Infrastructures and Platforms for Environmental Crowd Sensing and Big Data co-located with the European Citizen Science Association General Assembly 2015 (ECSA GA'2015) Barcelona, Spain, October 28-30 October, 2015. Edited by Arne J. Berre * Sven Schade ** Jaume Piera *** * SINTEF, Oslo, Norway ** JRC , Joint Research Centre, Ispra, Italy *** ICM-CSIC , Institute of Marine Sciences, Barcelona, Spain

Upload: others

Post on 11-Jun-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

1

Qt Logging Framework

All you ever wanted to know about QDebug and friends

© 2014 The Qt Company

Page 2: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

2 © 2014 The Qt Company

Kai Köhne

Senior Software Engineer, located in Berlin

Working for Trolltech Nokia Digia The Qt Company

Interests: #qtcreator #mingw #ifw #qtinstaller #qtlogging

Page 3: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

3 © 2014 The Qt Company

Agenda

Generating logging messages

Categorized logging

Formatting log messages

Logging backends

Page 4: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

4 © 2014 The Qt Company

Say Hello!

qDebug("hello");qWarning("hello!!");qCritical("HELLO!?!");qFatal("giving up :(");

Logs message, message type, file, line, function

Macros since Qt 5.0:

#define qDebug \ QMessageLogger(__FILE__, __LINE__, \ Q_FUNC_INFO).debug

qFatal aborts

Page 5: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

5 © 2014 The Qt Company

printf() style logging

© 2014 The Qt Company

// print a QStringQString qstr = "Hello";qDebug("QString: %s", qstr.toUtf8().constData());

// print a std::wstringstd::wstring wstr = L"Hello";qDebug("wstring: %s", QString::fromStdWString( wstr.c_str()) .toUtf8() .constData());

Compiler: system printf

– %s expects local 8 bit encoding

– %ls is wchar_t* (UTF-16 or UTF-16 or...)

Runtime: QString::vsprintf()

– %s expects UTF-8

– %ls needs to be UTF-16 (ushort*)

Page 6: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

6 © 2014 The Qt Company

Stream logging

© 2014 The Qt Company

#include <Qdebug>qDebug() << "Hello World";qWarning() << QDate::currentDate();qCritical() << QRect(0,10,50,40);Hello WorldQDate("2014-09-26")QRect(0,10 50x40)

QString name = "World";qDebug() << "Hello" << name;Hello "World"qDebug().nospace().noquote() << "Hello" << name;HelloWorld

Convenient logging for a lot of Qt types

Tweak the formatting:

– nospace(), space()

– noquote(), quote() (Qt 5.4)

Page 7: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

7 © 2014 The Qt Company

Stream logging

© 2014 The Qt Company

QStringList list;// ...{ QDebug dbg = qDebug(); dbg.nospace().noquote(); dbg << "Contents:"; for (int i = 0; i < list.size(); ++i) dbg << i << '/' << list.at(i) << " ";}

Contents: 0/A 1/B 2/C

qDebug().nospace() << "RGB: " << hex << uppercasedigits << 0xff << 0x33 << 0x33;

RGB: FF3333

Assembling log entry

QTextStream manipulators

Page 8: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

8 © 2014 The Qt Company

Stream logging

© 2014 The Qt Company

#include <QDebug>

struct RgbColor { uchar red, green, blue;};

QDebug operator<<(QDebug dbg, const RgbColor &color){ QDebugStateSaver saver(dbg); dbg.resetFormat(); dbg.nospace() << hex; dbg << "RgbColor(" << color.red << color.green << color.blue << ")"; return dbg;}

QDebugStateSaver (Qt 5.1)

– Saves stream formatting state, and restores

it on destruction

– Adds potential space on destruction

QDebug::resetFormat() (Qt 5.4)

– Immediately resets stream formatting state

Page 9: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

9 © 2014 The Qt Company

QML/JS logging

© 2014 The Qt Company

console.log("testing", name);console.debug("hello?", name);console.info("Hello", name);console.warn("Hello!", name);console.error("no one there", name);

console.assert(answer==="hello" , "invalid answer");

console.trace();console.count(var);

log() QtDebugMsg

debug()

info()

trace()

count()

warn() QtWarningMsg

error() QtCriticalMsg

assert()

Page 10: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

10 © 2014 The Qt Company

Conditional Logging

QT_NO_DEBUG_OUTPUT , QT_NO_WARNING_OUTPUT

– Compile time

– No selection possible

Filter in message handler

– Somewhat complicated

– Expensive

Custom logic

– Environment variables

– Custom macros

– …

Page 11: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

11 © 2014 The Qt Company

Categorized logging (Qt 5.2)

Split up logging messages in hierarchical categories.

Category is identified by it's name

category.subcategory.subsubcategory[...]

Logging of messages can be enabled or disabled based on the category and message type, at runtime.

Page 12: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

12 © 2014 The Qt Company

Categorized logging (Qt 5.2)

QLoggingCategory

– Runtime representation of category

– Configured by registry

Q_DECLARE_LOGGING_CATEGORY, Q_LOGGING_CATEGORY

– Define category in global scope

#include <QLoggingCategory>

QLoggingCategory lcEditor("qtc.editor");

qCDebug(lcEditor) << "hello";qCWarning(lcEditor) << "hello!!";qCCritical(lcEditor) << "HELLO!?!";qCDebug(lcEditor, "%s", "World"); //Qt5.3

Q_DECLARE_LOGGING_CATEGORY(lcEditor)Q_LOGGING_CATEGORY(lcEditor,"qtc.editor")

Page 13: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

13 © 2014 The Qt Company

Categorized logging (Qt 5.2)

#define qCDebug(category, ...) \ for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \ QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).debug(__VA_ARGS__)

#define Q_LOGGING_CATEGORY(name, ...) \ const QLoggingCategory &name() \ { \ static const QLoggingCategory category(__VA_ARGS__); \ return category; \ }

Page 14: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

14 © 2014 The Qt Company

Categorized logging (Qt 5.2)

Category configuration

– Default: Logging of all message types is enabled

– QLoggingCategory(const char *, QtMsgType severityLevel) (Qt 5.4)● Disables message types < severityLevel

– Category filter

– Textual logging rules

Page 15: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

15 © 2014 The Qt Company

Categorized logging (Qt 5.2)

Low level hook to configure categories#include <QLoggingCategory>

QLoggingCategory::CategoryFilter oldFilter = 0;

void filter(QLoggingCategory *cat) { printf("Category registered: '%s'\n", cat->categoryName()); oldFilter(cat);}

// ...

oldFilter = QLoggingCategory::installFilter(filter);

Page 16: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

16 © 2014 The Qt Company

Categorized logging (Qt 5.2)

Logging Rules

<category>[.<type>] = true|false

– '*' wildcard as first and/or last

– Evaluated top to bottom

*=trueqtc.*=falseqtc.editor=trueqtc.editor.debug=false

Page 17: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

17 © 2014 The Qt Company

Categorized logging (Qt 5.2)

Sources

– [Rules] section of QtProject/qtlogging.ini (Qt 5.3)

– QLoggingCategory::setFilterRules(const QString &rules)

– [Rules] section of file set in QT_LOGGING_CONF (Qt 5.3)

– QT_LOGGING_RULES environment variable (Qt 5.3)

Page 18: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

18 © 2014 The Qt Company

Recap

Logging entry consists of

– Type (QtDbgMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg)

– Category name

– Message text

– File, line, function information

Page 19: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

19 © 2014 The Qt Company

Message Formatting (Qt 5.0)

Enrich debug output by printing metadata

– qSetFormatPattern()

– QT_MESSAGE_PATTERN environment variable

Default pattern (Qt 5.2):

%{if-category}%{category}: %{endif}%{message}

Page 20: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

20 © 2014 The Qt Company

Message Formatting (Qt 5.0)

Format placeholders:

%{type} %{category} %{file} %{function} %{line} %{message}

%{appname} %{pid} %{threadid}

%{time [format]} %{backtrace [depth=N] [separator="..."]} (Qt 5.4)

%{if-category} %{if-warning} %{if-critical} %{if-fatal} … %{endif} (Qt 5.1)

%{if-category} … {endif} (Qt 5.2)

Page 21: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

21 © 2014 The Qt Company

Backends

stderr

Windows Debugger Log

QNX slogger2 (Qt 5.0)

journald (Qt 5.3)

Android message handler (Qt 5.1)

Tweak selection with

QT_LOGGING_TO_CONSOLE=0

QT_LOGGING_TO_CONSOLE=1

Page 22: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

22 © 2014 The Qt Company

Custom message handler

void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message){ static QMutex mutex; QMutexLocker lock(&mutex); static std::ofstream logFile("logfile.txt"); if (logFile) { logFile << qPrintable( qFormatLogMessage(type, context, message)) << std::endl; }}

Must be thread-safe!

Recursion

– Checked if compiler supports thread_local

– Option: QThreadLocalStorage

qFormatLogMessage()

– uses message pattern (Qt 5.4)

Page 23: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

23 © 2014 The Qt Company

Custom message handler

qInstallMessageHandler()

– Returns current/default handler

– Message handlers can be chained

static QtMessageHandler originalHandler = 0;

int main(int argc, char *argv[]){ originalHandler = qInstallMessageHandler(messageHandler); // ...}

Page 24: Qt Logging Framework · 2015-03-17 · 1 Qt Logging Framework All you ever wanted to know about QDebug and friends © 2014 The Qt Company

24 © 2014 The Qt Company

Summary

Qt 5 additions

– Logging metadata

– Categorized logging

– New backends (Android, JournalD)

– Customizing message output

Future

– QML/JS API for logging categories

– QtInfoMsg message type

– Log to file