[Development] (long) thoughts on categorized logging (qLog)

kai.koehne at nokia.com kai.koehne at nokia.com
Thu Feb 23 17:32:05 CET 2012


> -----Original Message-----
> From: development-bounces+kai.koehne=nokia.com at qt-project.org
> [mailto:development-bounces+kai.koehne=nokia.com at qt-project.org] On
> Behalf Of Ramsay Lincoln (Nokia-MP/Brisbane)
> Sent: Wednesday, February 22, 2012 7:37 AM
> To: qt-development
> Subject: [Development] (long) thoughts on categorized logging (qLog)
> 
> Hi all,

Hi Lincoln,
 
> There seems to be some confusion over what qLog is and is not. I suspect
> that the direction was perhaps mis-aligned slightly. Please allow me to try to
> summarize things. This is more of a vision thing and in writing this, parts of
> the implementation have been identified that should be updated. Writing
> this led to much discussion here, this represents something we are happy
> with and I'm hoping it matches the expectations of others too. Note that
> some different names are being proposed here, the changes to functionality
> suggested the names but as before, they're not set in stone yet.

Thank you for describing in such a clear way where this is heading.
I personally like both the mission as well as the ideas for implementation :)

> First a mission statement:
> 
> The categorized logging feature is intended as a replacement for qDebug and
> qWarning. With logging statements in an app/library, a developer can turn on
> the statements they care about and turn off the ones they don't.
> They can do all this without re-compiling the app and in some cases, without
> restarting the app. The categorized logging feature is intended to have as
> small an impact as possible until it has been explicitly enabled.
> 
>
> The categorized logging feature is made up of several parts.
> 
> 
> PART 1: The logging statements.
> 
> To keep the code compact (and for performance reasons), categories are
> identified locally by a short (locally-unique) token. The short tokens are
> mapped onto longer, (globally-unique) identifiers. Categories must be
> declared before use.
> 
> QT_LOG_CATEGORY(PLUGIN, "com.nokia.qt.plugins")
> 
> For a library, I'd expect to see a header that declares the categories used by
> that library but it's also possible to just drop the macro in the top of .cpp files
> as required. (impl detail: might need a "declare"
> and a "implement" macro for libs to avoid duplicate symbols)
> 
> The actual logging statements use the category token.
> 
> qCDebug(PLUGIN) << "Scanning for plugins in" << paths;
> qCWarning(PLUGIN) << "Could not load plugin" << loader->errorString();
> 
> As can be seen, we're differentiating between debug (defualt off) and
> warning (default on) statements. To identify these when turning categories
> on/off there is a .debug or .warning suffix added to the identifier (more on
> this later).
> 
> It's important to note that logging statements should not have side effects
> because they may not be called.
> 
> 
> PART 2: Compatibility with qDebug/qWarning
> 
> qDebug() and qWarning() will be re-implemented as categorized logging
> statements. Both will use the same, hard-coded category.
> 
> qDebug() << "debug";
> qWarning() << "warning";
> 
> Is almost equivalent to:
> 
> QT_LOG_CATEGORY(LEGACY, "legacy")
> qCDebug(LEGACY) << "debug";
> qCWarning(LEGACY) << "warning";
> 
> I say "almost equivalent" because qDebug() defaults on (while
> categorized debugs default off).
> 
> The older qDebug("debug") and qWarning("warning") syntax will also work
> and will be treated the same way.
> 
> For display purposes, qFatal will also have a category but it won't be
> influenced by the logging configuration.

It's probably the easiest to just default to have an empty string as 'legacy'
category. This preserves the output of qDebug(), even if %{category} is printed by default
as suggested below.

> PART 3: Turning statements on/off.
> 
> As mentioned, debug statements (except for qDebug) default off and
> warning statements default on. Logging statements can be enabled or
> disabled using rules. Rules specify a category identifier, optionally
> using a global-style * to match multiple categories.
> 
> eg.
> # Turn on Qt plugin debug
> com.nokia.qt.plugins.debug = true
> # Turn off network warnings
> com.nokia.qt.network.warning = false
> # Turn on all webkit debug
> org.webkit.*.debug = true
> # Turn off all legacy qDebug/qWarning
> legacy.* = false
> 
> For apps that want to provide a UI for logging and for future expansion
> possibilities (eg. add-ons that allow turning logging on/off via some
> novel means), there will be a C++ API to set the rules.
> 
> qSetCategoryRules(const QByteArray &rules);
> 
> However, since there are likley to be many apps that don't care about
> logging (or may not expose a way to turn on logging in a third party
> library) there will also be a text-based config file that the user can
> create. Where should this file be located? Either the app sets the
> location of this file by calling qSetLoggingConfigFile() or the user
> sets the QT_LOGGING_CONFIG environment variable (which overrides the
> app's default). If the config file exists, the C++ API has no effect.
> QFileWatcher will be used to monitor the config file so that categories
> can be turned on/off while the program is running by updating the file.

Just wanted to point out that the current environment variable for configuring
the output is called QT_MESSAGE_PATTERN. So it should be either QT_MESSAGE_CONFIG,
or we should quickly rename QT_LOGGING_PATTERN ...

[snip]

Kai



More information about the Development mailing list