== Problematic ==
Qt 5.3 and dev are currently able to send the output of qDebug, qWarning and 
the rest of the logging framework to somewhere other than stderr. That's done 
on Windows, BlackBerry, Android, and on Linux systems with journald. 
Additionally, there's a pending patch for OS X to use the Apple System Log [5] 
and I had a patch for MeeGo that made it go to the standard Unix syslog.

We have a problem of wanting a cake and eating it too:

1) we want applications to send their logging to the system log where 
possible, which usually logs more information like the log level, time, 
application name and PID. Such a system is searchable and may allow us to add 
additional information, like the category (for category logging), file name, 
line number, function context, etc.

2) we also want to see the output when we run applications from the terminal 
or capture the output with QProcess.

The absence of output causes bug reports like [2] and [4].

== Solutions ==
=== Log to both ===
Aside from the extra overhead, this causes systems that capture both stderr 
and the system log to record and display the same message twice. That's the 
source of task [3].

This is not an option.

=== Log to stderr only ===
That results in loss of information, since the system logs are richer and more 

What's more, on Windows that would result in no output at all for GUI 
applications. I can't find a lot of information on whether GUI applications 
launched from an open command prompt would show anything. IIRC, they don't.

This is not an option.

=== Log to system logs only ===
This causes reports like [4]. But note that the bug is actually in Creator, 
for failing to read the log store and display the data, like it does on 
Windows with the debug output.

This is an option.

=== Heuristically determine at runtime where to send the log ===
Which is what I'm trying to do above.

On Windows, we check whether we have a console and whether stderr is not NUL.

On Unix, I have implemented the same checks.

We can also use the fact of whether the main application is in debug mode or 

== Summary of systems ==

 - default stderr: what is stderr connected to when launched from the GUI menu
 - system logging: if there's an API and whether non-privileged users can read
   from the log
 - is stderr useful: whether there are conditions under which writing to 
   stderr is useful

 - default stderr: /dev/null
 - system logging: available
 - is stderr useful: barely, it requires a rooted device

 - default stderr: /dev/null
 - system logging: available
 - is stderr useful: I don't know, it's possible d5a4732c applies to non-BB 
QNX only

OS X and iOS:
 - default stderr: captured into system log
 - system logging: available
 - is stderr useful: yes on OS X, running applications from the terminal

 - default stderr: captured into the wrong system log
 - system logging: available
 - is stderr useful: yes, for remote debugging applications

Current Linux desktops with journald:
 - default stderr: captured into ~/.xsession-errors
 - system logging available: available
 - is stderr useful: yes, for launching from terminal
[when Linux desktops start using user-mode systemd, it will be as below]

System services on Linux with journald:
 - default stderr: captured into system log
 - system logging: available
 - is stderr useful: yes, for launching from terminal

Unix without journald:
 - default stderr: irrelevant
 - system logging: not available (non-root users may not be able to read it)
 - is stderr useful: yes, mandatory

Windows GUI apps:
 - default stderr: NUL
 - system logging: available
 - is stderr useful: yes

Windows console apps:
 - default stderr: console
 - system logging: available
 - is stderr useful: yes

== History ==
In the dawn of time, qDebug printed to stderr. 

But then came Windows with GUI applications that don't have a console and 
stderr is NUL. So Qt applications that did not use CONFIG += console would use 
OutputDebugString, which we'd detect by the use or not of Qt's WinMain 
function. That was the first "system log" API.

During Qt 5.0 development, we added logging to BlackBerry's slog2. That was 
unconditional: all applications, all output.

Similarly for the Android port: when it was introduced, it unconditionally 
logged to the the Android log. But in Qt 5.1, there was a commit (289120f8) 
that added an environment variable allowing logging to stderr.

During 5.2 development, we stopped using WinMain and instead tried to detect 
whether the application has a console window or not. The first two patch sets 
of 7fb3906 [1] only checked for the console, but PS3 added a check for whether 
stderr was valid even if no console window was present.

For 5.3, we added support for journald on Linux, mostly intended for 
SailfishOS. Support was like on Android at the time: an environment variable 
was needed to write to stderr; otherwise, it went to journald.

For 5.3.1, support for the environment variable was added to BlackBerry's 
slog2 too, matching Android and journald-enabled Linux.

And then some desktop Linux distributions decided to enable journald. The 
effect of that is task [6]: Qt Creator shows no output because it goes to 

== References ==
[1] https://codereview.qt-project.org/64599 - merged as 7fb3906 for 5.2
[2] https://bugreports.qt-project.org/browse/QTBUG-32044 - task for [1]
[3] https://bugreports.qt-project.org/browse/QTBUG-34630
[4] https://bugreports.qt-project.org/browse/QTCREATORBUG-12564
[5] https://codereview.qt-project.org/82922 - open for dev
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

Development mailing list

Reply via email to