Discussion:
[Development] QLog ( Work on qDebug and friends)
w***@nokia.com
2012-01-31 05:32:46 UTC
Permalink
Hi there,

I'm finished to make a patch and created the documentation of QLog.
To be sure that all can read the document I've attached it to this EMail.
The main focus on this project is:

1. Logging in a file:
2. Enable or disable logging without recompiling your project.
3. Logging with categories

If you have other ideas, concerns or requirements please feel free to share them on the mailing list.

For those once there are interested to see the patch and have access rights :) have a look at:
I0c784a94 Prepare qLog for Qt integration Project qt/qtbase

--
wbeck
Jordi Pujol
2012-01-31 07:08:03 UTC
Permalink
> Hi there,
>
> I'm finished to make a patch and created the documentation of QLog.
> To be sure that all can read the document I've attached it to this EMail.
> The main focus on this project is:
>
> 1. Logging in a file:
> 2. Enable or disable logging without recompiling your project.
> 3. Logging with categories
>
> If you have other ideas, concerns or requirements please feel free to share them on the mailing list.
>
> For those once there are interested to see the patch and have access rights :) have a look at:
> I0c784a94 Prepare qLog for Qt integration Project qt/qtbase
>
> --
> wbeck

+1 from me

- Crazy idea : allow logging to a socket ? ( remote log/debug )
- More than one logging file ? One file for every category / group of
categories
- Log File rotation

Just my 2 cents.
s***@accenture.com
2012-01-31 10:57:18 UTC
Permalink
>
> +1 from me
>
> - Crazy idea : allow logging to a socket ? ( remote log/debug )
> - More than one logging file ? One file for every category / group of
> categories
> - Log File rotation
>
> Just my 2 cents.
>

Not that crazy an idea - I normally use USB to catch the live debug log from phones.
But this is done on the system level rather than Qt.
The problem is you can't use QTcpSocket to do it, because QtNetwork might itself be printing QDebug messages.


________________________________
Subject to local law, communications with Accenture and its affiliates including telephone calls and emails (including content), may be monitored by our systems for the purposes of security and the assessment of internal compliance with Accenture policy.
______________________________________________________________________________________

www.accenture.com
Keith Gardner
2012-01-31 14:39:33 UTC
Permalink
Couldn't you have the log fill a QIODevice (file or socket) and make a QLogFile class that would perform the log file rotation?

-----Original Message-----
From: development-bounces+kgardner=***@qt-project.org [mailto:development-bounces+kgardner=***@qt-project.org] On Behalf Of ***@accenture.com
Sent: Tuesday, January 31, 2012 4:57 AM
To: ***@gmail.com; ***@nokia.com
Cc: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

>
> +1 from me
>
> - Crazy idea : allow logging to a socket ? ( remote log/debug )
> - More than one logging file ? One file for every category / group of
> categories
> - Log File rotation
>
> Just my 2 cents.
>

Not that crazy an idea - I normally use USB to catch the live debug log from phones.
But this is done on the system level rather than Qt.
The problem is you can't use QTcpSocket to do it, because QtNetwork might itself be printing QDebug messages.


________________________________
Subject to local law, communications with Accenture and its affiliates including telephone calls and emails (including content), may be monitored by our systems for the purposes of security and the assessment of internal compliance with Accenture policy.
______________________________________________________________________________________

www.accenture.com
Lincoln Ramsay
2012-02-01 01:29:11 UTC
Permalink
On 01/31/2012 05:08 PM, ext Jordi Pujol wrote:
> - Crazy idea : allow logging to a socket ? ( remote log/debug )
> - More than one logging file ? One file for every category / group of
> categories
> - Log File rotation

Good ideas... but I think I'm against the idea of shoving all sorts of
clever "output handling" logic into qLog because you can override the
debug message handler and do all sorts of clever stuff in there.

I'm almost tempted to say that qLog should stick to the "categories"
stuff and leave all "output handling" to something else (perhaps living
in an Add-on).

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
BRM
2012-02-01 18:02:00 UTC
Permalink
Getting caught up again...



----- Original Message -----
> From: Lincoln Ramsay <***@nokia.com>
> On 01/31/2012 05:08 PM, ext Jordi Pujol wrote:
>> - Crazy idea : allow logging to a socket ? ( remote log/debug )
>> - More than one logging file ? One file for every category / group of
>> categories
>> - Log File rotation
>
> Good ideas... but I think I'm against the idea of shoving all sorts of
> clever "output handling" logic into qLog because you can override the
> debug message handler and do all sorts of clever stuff in there.

+1. The core logging facility should not have anything to do with output of the data.

For work we wanted to output to syslog; but I use a lot of Qt stuff, and generate logs messages with Signals to a central logging object.
The initial version turned into a mess when someone added support for Windows Event Log and file output; so I rewrote it using C++ to my advantage;
and I had thought several times about proposing something similar for Qt, which this discussion seems to now be doing.

The design was relatively simple: A single log object that dealt with receiving log messages via a Signal, and managed a series of back-end output log modules.
The back-end output log modules had as standard interface defined by an abstract class. The log object had a default back-end selected depending on the platform;
but this could be overridden by the configuration.so that one or more back-ends were in use at the same time; all backends got the same log data in no specific order.
The log object itself didn't care about the output - it just managed getting the log messages; the output was up to the back-end modules.

I did several for our uses: (i) syslog, (ii) Windows EventLog, (iii) C/C++ File logging, (iv) Windows File Logging.

Mine were all compile-time driven - all were compiled in, and then you selected which via the configuration.
For Qt, it'd probably be better to have a platform default built-in, but then also have the ability to load them from a plugin folder as a QPlug-in.

I would also suggest that the plugins use a standard public interface class such as QAbstractLogFacility, like QTcpSocket uses QAbstractSocket - so that people can add their own custom logging output easily; and I would suggest that syslog and Windows EventLog be supported by Qt directly too; though only be available on the platforms that support them - e.g. you can't write to the Windows EventLog from Linux; nor to syslog from Windows (though that would really be useful).

> I'm almost tempted to say that qLog should stick to the  "categories"
> stuff and leave all "output handling" to something else (perhaps living
> in an Add-on).

I did a ENUM for my system that was modeled on syslog; but it would probably be better to do something in the meta-data framework of Qt
and have a sane set of initial values (syslog could probably be a good model there).

$0.02

Ben
David Faure
2012-02-01 21:21:03 UTC
Permalink
On Wednesday 01 February 2012 10:02:00 BRM wrote:
> I would also suggest that the plugins use a standard public interface class
> such as QAbstractLogFacility, like QTcpSocket uses QAbstractSocket - so
> that people can add their own custom logging output easily

This is already available, see qInstallMessageHandler in Qt 5
(qInstallMsgHandler in earlier versions)

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
BRM
2012-02-01 23:03:57 UTC
Permalink
> From: David Faure <***@kdab.com>

> On Wednesday 01 February 2012 10:02:00 BRM wrote:
>> I would also suggest that the plugins use a standard public interface class
>> such as QAbstractLogFacility, like QTcpSocket uses QAbstractSocket - so
>> that people can add their own custom logging output easily
>
> This is already available, see qInstallMessageHandler in Qt 5
> (qInstallMsgHandler in earlier versions)

I am very aware of what is in Qt4 right now (http://doc.qt.nokia.com/5.0-snapshot/qtglobal.html#qInstallMsgHandler - and in Qt5 by extension)
This functionality is very primitive when compared to other facilities like syslog or the Windows EventLog.

It does the job for a very basic logging system, but when you need to start categorizing your log messagse it does not do well at all.
I am talking about something that is far more comprehensive, which is also what I believe they were discussion with respect to what I replied to.

Now, I think the existing qDebug() and friends are nice for built-in stuff and for doing some general easy apps; and they should certainly remain the default.
However, we should also offer a more extensive logging system that can be used instead - which registers a message handler and takes over.

Or what about when you want to record to multiple facilities? E.g. sending to syslog and your own file logging.
(This is useful in distributed logging situations so that you can capture a local log and still send out to the distributed log as well.)

I think Qt can offer a basic logging framework that can be optionally used by those that want to use it. It would make a nice Add-on module.
And why force users to rewrite functionality for some of the most common logging systems (e.g. syslog and Windows EventLog)?

Ben
David Faure
2012-02-02 11:39:59 UTC
Permalink
On Wednesday 01 February 2012 15:03:57 BRM wrote:
> It does the job for a very basic logging system, but when you need to start
> categorizing your log messagse it does not do well at all.

Hence the idea of adding the category to the new QMessageLogContext class
(see global/qlogging.h).

> However, we should also offer a more extensive logging system that can be
> used instead - which registers a message handler and takes over.

Yes. I don't mind multiple "outputs", I just want a single "input", i.e. that
the code uses qDebug() / qDebug(AREA) no matter what output (message handler)
is being used.

> Or what about when you want to record to multiple facilities? E.g. sending
> to syslog and your own file logging.
> (This is useful in distributed logging situations so that you can capture a
> local log and still send out to the distributed log as well.)

Yes, all that can be done by the QLog code, triggered by the qt message
handler which would provide it the info it needs.

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
André Somers
2012-02-02 11:52:38 UTC
Permalink
Op 2-2-2012 0:03, BRM schreef:
>> From: David Faure<***@kdab.com>
>> On Wednesday 01 February 2012 10:02:00 BRM wrote:
>>> I would also suggest that the plugins use a standard public interface class
>>> such as QAbstractLogFacility, like QTcpSocket uses QAbstractSocket - so
>>> that people can add their own custom logging output easily
>> This is already available, see qInstallMessageHandler in Qt 5
>> (qInstallMsgHandler in earlier versions)
> I am very aware of what is in Qt4 right now (http://doc.qt.nokia.com/5.0-snapshot/qtglobal.html#qInstallMsgHandler - and in Qt5 by extension)
> This functionality is very primitive when compared to other facilities like syslog or the Windows EventLog.
>
> It does the job for a very basic logging system, but when you need to start categorizing your log messagse it does not do well at all.
> I am talking about something that is far more comprehensive, which is also what I believe they were discussion with respect to what I replied to.
>
> Now, I think the existing qDebug() and friends are nice for built-in stuff and for doing some general easy apps; and they should certainly remain the default.
> However, we should also offer a more extensive logging system that can be used instead - which registers a message handler and takes over.
>
> Or what about when you want to record to multiple facilities? E.g. sending to syslog and your own file logging.
> (This is useful in distributed logging situations so that you can capture a local log and still send out to the distributed log as well.)
>
> I think Qt can offer a basic logging framework that can be optionally used by those that want to use it. It would make a nice Add-on module.
> And why force users to rewrite functionality for some of the most common logging systems (e.g. syslog and Windows EventLog)?
>
I think there are plenty of implementations doing this already. Take a
look at QxtLogger for instance. It can be used with the output handler
just fine, but it also allows more finegrained access with more than
four levels. It also supports multiple outputs.
I see no need to make all this part of Qt *now*, especially not of core.
The very existence of external libraries that integrate with the current
structure shows that it is exendable enough.

André
David Faure
2012-02-02 12:22:11 UTC
Permalink
On Thursday 02 February 2012 12:52:38 =?ISO-8859-1?Q?Andr=E9?= Somers wrote:
> I think there are plenty of implementations doing this already. Take a
> look at QxtLogger for instance. It can be used with the output handler
> just fine, but it also allows more finegrained access with more than
> four levels. It also supports multiple outputs.
> I see no need to make all this part of Qt *now*, especially not of core.
> The very existence of external libraries that integrate with the current
> structure shows that it is exendable enough.

Well, Qxt and kdelibs are entire frameworks on top of Qt, but this makes the
lib code very inconsistent, and not every little app wants to link to a big
framework, especially for something as small as debug output handling.
I want to get rid of KDE's kDebug so that there is less difference between "a
Qt-based library" and "a KDE-based library". The last hurdle for that is:

1) showing more information (file, line, method, process name and PID) in the
default message handler, probably based on env vars (easy to add now that
QMessageLogContext has the necessary information).

2) support for debug areas. QLog's way of defining areas looks very nice, but
it should be integrated with qDebug, as discussed previously.

Again, this is about standardizing the debug statements in all qt-based libs,
it doesn't prevent external loggers handling for the output in customized ways
in specific apps or frameworks.

In fact, because of the lack of debug areas, Qt code itself can't leave a
single debug statement uncommented. Parts of Qt are full of #ifdefs to disable
debug output by default. This could be done much better by registering an area
and asking for it to be disabled by default. Then people could enable
debugging from e.g. qsslsocket or QNAM or qimagereader without recompiling Qt
[qdbus has a custom solution for this, $QDBUS_DEBUG, showing that is really a
need for this]. I think this clearly shows there is a need for something
better in QtCore. Extra code in external libraries doesn't solve this core
issue.

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
Robin Burchell
2012-02-02 12:56:49 UTC
Permalink
On Thu, Feb 2, 2012 at 2:22 PM, David Faure <***@kdab.com> wrote:
> 1) showing more information (file, line, method, process name and PID) in the
> default message handler, probably based on env vars (easy to add now that
> QMessageLogContext has the necessary information).

Please don't show *all* of that by default. Having it *available* is
useful, but especially for people working on single applications,
things like PID in the console output is completely useless spam.
Making it *available*? Sure. KDE could have a message handler that did
whatever they wanted, without needing kDebug.

Another thing to note is that debugging carries a performance penalty.
You definitely don't want that compiled in in release builds, and
you'd still want to avoid debug in performance-critical areas, even if
output wasn't switched on.

Everything else in your mail gets a +3 "approved; give this guy a payrise" :-)
David Faure
2012-02-02 13:03:03 UTC
Permalink
On Thursday 02 February 2012 14:56:49 Robin Burchell wrote:
> On Thu, Feb 2, 2012 at 2:22 PM, David Faure <***@kdab.com> wrote:
> > 1) showing more information (file, line, method, process name and PID) in
> > the default message handler, probably based on env vars (easy to add now
> > that QMessageLogContext has the necessary information).
>
> Please don't show *all* of that by default. Having it *available* is
> useful, but especially for people working on single applications,
> things like PID in the console output is completely useless spam.
> Making it *available*? Sure. KDE could have a message handler that did
> whatever they wanted, without needing kDebug.

Sure, I didn't mean that this should be on by default.

But it would be so extremely useful to set an env var at session startup and
suddenly make sense of .xsession-errors lines like
"QGridLayoutEngine::addItem: Cell (0, 1) already taken" which don't currently
tell form which app they come from.

> Another thing to note is that debugging carries a performance penalty.
> You definitely don't want that compiled in in release builds

That's already handled by QT_NO_DEBUG_OUTPUT.

> and you'd still want to avoid debug in performance-critical areas, even if
> output wasn't switched on.

Yep, this still has to be done. We have a solution in KDE for that (a quick
"is debug enabled for this area" method that then disabled everything else in
this qdebug object if not), but nothing in Qt yet (we need support for areas
first ;)

> Everything else in your mail gets a +3 "approved; give this guy a payrise"
> :-)

LOL, thanks, I'll forward this to my boss then :)

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
s***@accenture.com
2012-02-02 15:01:02 UTC
Permalink
An important requirement is that it must be easy to enable debugging in Qt libraries without touching the application code.
This is so that we can debug regressions affecting closed source applications.

With the existing qDebug, we need to disable the qInstallMsgHandler call*, and recompile the relevant Qt libraries with debug logs enabled.

*A lot of applications redirect logs to a file, which may be hard to find. Some applications catch and discard qDebug in release builds.

________________________________
Subject to local law, communications with Accenture and its affiliates including telephone calls and emails (including content), may be monitored by our systems for the purposes of security and the assessment of internal compliance with Accenture policy.
______________________________________________________________________________________

www.accenture.com
David Faure
2012-02-02 20:26:12 UTC
Permalink
On Thursday 02 February 2012 15:01:02 ***@accenture.com wrote:
> An important requirement is that it must be easy to enable debugging in Qt
> libraries without touching the application code. This is so that we can
> debug regressions affecting closed source applications.
>
> With the existing qDebug, we need to disable the qInstallMsgHandler call*,
> and recompile the relevant Qt libraries with debug logs enabled.

How about submitting a patch to Qt 5 that makes qInstallMsgHandler a no-op
when an environment variable $QT_NO_MESSAGE_HANDLER is set?

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
Francesco R.(vivo)
2012-02-02 20:15:45 UTC
Permalink
In data giovedì 2 febbraio 2012 14:03:03, David Faure ha scritto:
> On Thursday 02 February 2012 14:56:49 Robin Burchell wrote:
> > On Thu, Feb 2, 2012 at 2:22 PM, David Faure <***@kdab.com> wrote:
> > > 1) showing more information (file, line, method, process name and PID)
> > > in the default message handler, probably based on env vars (easy to
> > > add now that QMessageLogContext has the necessary information).
> >
> > Please don't show *all* of that by default. Having it *available* is
> > useful, but especially for people working on single applications,
> > things like PID in the console output is completely useless spam.
> > Making it *available*? Sure. KDE could have a message handler that did
> > whatever they wanted, without needing kDebug.
>
> Sure, I didn't mean that this should be on by default.
>
> But it would be so extremely useful to set an env var at session startup
> and suddenly make sense of .xsession-errors lines like
> "QGridLayoutEngine::addItem: Cell (0, 1) already taken" which don't
> currently tell form which app they come from.

Is it possible to have a short checksum for the debug/log session which could
be prefixed to all the following line of output?

this way all the redundand stuff like PID, TID, can be outputted only once, at
debugging start.
Also this make multiple sources output to a common file easily greppable.

IMHO .xsession-errors should die and it's `chattr +i` on my desktops, to avoid
some crazy application have a crisys and filling the /home partition (has
happened only twice in ten years but it's disturbing anyway)

and finally has anyone taken a look at systemd "binary logging"? I didn't but
maybe there is interesting stuf in there.

/me goes back in the dark

>
> > Another thing to note is that debugging carries a performance penalty.
> > You definitely don't want that compiled in in release builds
>
> That's already handled by QT_NO_DEBUG_OUTPUT.
>
> > and you'd still want to avoid debug in performance-critical areas, even
> > if output wasn't switched on.
>
> Yep, this still has to be done. We have a solution in KDE for that (a quick
> "is debug enabled for this area" method that then disabled everything else
> in this qdebug object if not), but nothing in Qt yet (we need support for
> areas first ;)
>
> > Everything else in your mail gets a +3 "approved; give this guy a
> > payrise"
> >
> > :-)
>
> LOL, thanks, I'll forward this to my boss then :)
André Somers
2012-02-02 13:56:07 UTC
Permalink
Op 2-2-2012 13:22, David Faure schreef:
> On Thursday 02 February 2012 12:52:38 =?ISO-8859-1?Q?Andr=E9?= Somers wrote:
>> I think there are plenty of implementations doing this already. Take a
>> look at QxtLogger for instance. It can be used with the output handler
>> just fine, but it also allows more finegrained access with more than
>> four levels. It also supports multiple outputs.
>> I see no need to make all this part of Qt *now*, especially not of core.
>> The very existence of external libraries that integrate with the current
>> structure shows that it is exendable enough.
> Well, Qxt and kdelibs are entire frameworks on top of Qt, but this makes the
> lib code very inconsistent, and not every little app wants to link to a big
> framework, especially for something as small as debug output handling.
> I want to get rid of KDE's kDebug so that there is less difference between "a
> Qt-based library" and "a KDE-based library". The last hurdle for that is:
>
> 1) showing more information (file, line, method, process name and PID) in the
> default message handler, probably based on env vars (easy to add now that
> QMessageLogContext has the necessary information).
>
> 2) support for debug areas. QLog's way of defining areas looks very nice, but
> it should be integrated with qDebug, as discussed previously.
>
> Again, this is about standardizing the debug statements in all qt-based libs,
> it doesn't prevent external loggers handling for the output in customized ways
> in specific apps or frameworks.
I did not mean that there is no need for more information or debug
area's. I meant that the whole machinery for having different sinks for
that information (network wat mentioned, rotating file logs, syslogs,
whatever else) can be left to an external library. I think the
_gathering_ of all that data (as an extension to qDebug) does belong in
core, of course, but I think we should not go towards setting up a whole
complicated output mechamism now.

I think you are focussing on making sure the information is all there to
use (debug area's and the likes), so I think we agree. I got the feeling
that BRM (Ben) was more interested in making the output more fancy, and
that is where I object to putting this into Qt Core, or at least to
putting that into Qt Core at this moment.

Sorry if my message was not clear before.

André
BRM
2012-02-02 15:24:21 UTC
Permalink
> From: André Somers <***@familiesomers.nl>
> Op 2-2-2012 13:22, David Faure schreef:
>> On Thursday 02 February 2012 12:52:38 =?ISO-8859-1?Q?Andr=E9?= Somers
> wrote:
>>> I think there are plenty of implementations doing this already. Take a
>>> look at QxtLogger for instance. It can be used with the output handler
>>> just fine, but it also allows more finegrained access with more than
>>> four levels. It also supports multiple outputs.
>>> I see no need to make all this part of Qt *now*, especially not of
> core.
>>> The very existence of external libraries that integrate with the
> current
>>> structure shows that it is exendable enough.
>> Well, Qxt and kdelibs are entire frameworks on top of Qt, but this makes
> the
>> lib code very inconsistent, and not every little app wants to link to a big
>> framework, especially for something as small as debug output handling.
>> I want to get rid of KDE's kDebug so that there is less difference
> between "a
>> Qt-based library" and "a KDE-based library". The last hurdle
> for that is:
>>
>> 1) showing more information (file, line, method, process name and PID) in
> the
>> default message handler, probably based on env vars (easy to add now that
>> QMessageLogContext has the necessary information).
>>
>> 2) support for debug areas. QLog's way of defining areas looks very
> nice, but
>> it should be integrated with qDebug, as discussed previously.
>>
>> Again, this is about standardizing the debug statements in all qt-based
> libs,
>> it doesn't prevent external loggers handling for the output in
> customized ways
>> in specific apps or frameworks.
> I did not mean that there is no need for more information or debug
> area's. I meant that the whole machinery for having different sinks for
> that information (network wat mentioned, rotating file logs, syslogs,
> whatever else) can be left to an external library. I think the
> _gathering_ of all that data (as an extension to qDebug) does belong in
> core, of course, but I think we should not go towards setting up a whole
> complicated output mechamism now.

+1 agreed.
 
> I think you are focussing on making sure the information is all there to
> use (debug area's and the likes), so I think we agree. I got the feeling
> that BRM (Ben) was more interested in making the output more fancy, and
> that is where I object to putting this into Qt Core, or at least to
> putting that into Qt Core at this moment.

Sorry if I was not more clear on this point.

I don't think that the extensible framework I was suggesting should be part of Qt Core.
Rather I think Qt should provide an Add-on module - just like QWidget, QNetwork, etc - that provides that functionality;
where we provide some default outputs for a few well-known used systems and leave the ability for others to extend it.
It should be 100% optional, and like with everyone else be able to pull in the content from qDebug(), et al.

Adding the "AREAS" to qDebug(), et al also enables those extensible frameworks - whether provided by Qt or not - to have more granularity as well.

Ben
Lincoln Ramsay
2012-02-01 01:20:17 UTC
Permalink
On 01/31/2012 03:32 PM, ext ***@nokia.com wrote:
> 1. Logging in a file:
> 2. Enable or disable logging without recompiling your project.

I would like to comment on number 1.

I think it's important that a reasonably-unique default config file
exists for each application. Why? Because without it, number 2 doesn't
actually work.

I think a file name should be created based on the platform, and
QCoreApplication properties like organizationName and applicationName
(similar to QSettings).

On a Mac, you might end up with ~/Library/Application
Support/OrganizationName/ApplicationName/Logging.txt

On Windows, you might end up with %HOMEDRIVE%%HOMEPATH%\App
Data\OrganizationName\ApplicationName\Logging.txt

On Linux, you might end up with
~/.config/OrganizationName/ApplicationName/Logging.txt

If you don't supply the organization or app names then perhaps a
fallback to he binary name.


This then, is the "default" logging config file and we can document it
reliably for each platform.

I think it's probably a good idea to leave in the setConfigFile method
but I'd call it setDefaultConfigFile. This overrides the generated
default and is useful for cases where you want multiple apps to pick up
the same logging config file. It also allows app developers to keep the
logging file with their other config/data if that location differs from
where we used.

Finally, to give the user control, I think we need an environment
variable that overrides both of the above. Say, QLOG_CONFIG_FILE. By
setting this environment variable, the user can be certain that their
logging config file will be used. It can also be used to cause multiple
apps to use the same logging config file. Finally, it ensures the user
can enable logging even if they don't have permission to write to the
default config file.



In summary:
1) Generated default logging config file (for sanity).
2) QLog::setDefaultConfigFile for application writers.
3) QLOG_CONFIG_FILE for users.


Oh, and since there was no link to the change in your email, here it is:
http://codereview.qt-project.org/#change,13226

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
David Faure
2012-02-01 14:53:02 UTC
Permalink
On Wednesday 01 February 2012 11:20:17 Lincoln Ramsay wrote:
> In summary:
> 1) Generated default logging config file (for sanity).

I agree (please use
QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)
as the base directory for it)

> 2) QLog::setDefaultConfigFile for application writers.
> 3) QLOG_CONFIG_FILE for users.
+1

However I would like this to be called qDebug(AREA) rather than qLog(AREA).
Otherwise we are presenting a confusing situation of two competing debug-
output frameworks inside Qt. Couldn't the definition and use of categories be
done in the newly merged corelib/global/qlogging.h, and shipped as part of the
QMessageLogContext class? Then the default message handler can do what your
qlog code is doing, i.e. write the stuff into the right log file, if the app or
the user chose log files (by default I think this should still go to stderr,
logging to files should only be an additional option).

I think this would be a much more integrated solution than asking people to
choose between qDebug (stderr) and qLog (files) at development time, and then
letting no choice to the final user, or to other developers working on the same
code later on.

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
Robin Burchell
2012-02-01 23:50:00 UTC
Permalink
On Wed, Feb 1, 2012 at 4:53 PM, David Faure <***@kdab.com> wrote:
> However I would like this to be called qDebug(AREA) rather than qLog(AREA).
> Otherwise we are presenting a confusing situation of two competing debug-
> output frameworks inside Qt.

Agreed. Extra functionality can be built on top of what is there
already. Adding categories, etc, via overloads is fine, IMO. Things
like file logging, socket logging, etc... need a bit more
consideration, but are also not something that is unthinkable to have
done as extensions of the existing system, which also handily provides
log *levels*, even if not categories. (think: qDebug(SOCKETS) <<
"Socket created"; .... qWarning(SOCKETS) << "Couldn't connect, did
something break?"; type things)

Something related I'd like to stress here (not to anyone in
particular): when you write this stuff in applications, it can be
changed at will. But when it's in Qt, you can't change it for a very,
very, very long time (if ever) if you suddenly decide the
implementation isn't ideal or you could do better. It's better to not
jam the moon on a stick into it from the word go, to take some time,
and do it properly.

My point is: feature requests are great, I'm sure we'd all adore them,
but let's rush into implementing without considering them carefully :)
w***@nokia.com
2012-02-02 23:00:33 UTC
Permalink
I think we can change the current QLog.

Category using qDebug(category) and writing stuff out in an output file.
For me a logging file is much more important than system logs or socket because you can ask the customer that uses your Qt application to send you back the output log file.
Other cool stuff like writing into sockets can be done in an addOn or even in a plugin.

--
WB





-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext Robin Burchell
Sent: Thursday, February 02, 2012 9:50 AM
To: David Faure
Cc: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On Wed, Feb 1, 2012 at 4:53 PM, David Faure <***@kdab.com> wrote:
> However I would like this to be called qDebug(AREA) rather than qLog(AREA).
> Otherwise we are presenting a confusing situation of two competing
> debug- output frameworks inside Qt.

Agreed. Extra functionality can be built on top of what is there already. Adding categories, etc, via overloads is fine, IMO. Things like file logging, socket logging, etc... need a bit more consideration, but are also not something that is unthinkable to have done as extensions of the existing system, which also handily provides log *levels*, even if not categories. (think: qDebug(SOCKETS) << "Socket created"; .... qWarning(SOCKETS) << "Couldn't connect, did something break?"; type things)

Something related I'd like to stress here (not to anyone in
particular): when you write this stuff in applications, it can be changed at will. But when it's in Qt, you can't change it for a very, very, very long time (if ever) if you suddenly decide the implementation isn't ideal or you could do better. It's better to not jam the moon on a stick into it from the word go, to take some time, and do it properly.

My point is: feature requests are great, I'm sure we'd all adore them, but let's rush into implementing without considering them carefully :) _______________________________________________
Development mailing list
***@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development
BRM
2012-02-03 01:33:24 UTC
Permalink
----- Original Message -----
> From: "***@nokia.com" <***@nokia.com>
> To: robin+***@viroteck.net; ***@kdab.com
> Cc: ***@qt-project.org
> Sent: Thursday, February 2, 2012 6:00 PM
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> I think we can change the current QLog.
>
> Category using qDebug(category) and writing stuff out in an output file.
> For me a logging file is much more important than system logs or socket because
> you can ask the customer that uses your Qt application to send you back the
> output log file.
> Other cool stuff like writing into sockets can be done in an addOn or even in a
> plugin.

qDebug() and friends should continue outputting as they currently do. The only difference should be the addition of the category/area (whatever you want to call it);
and even then that should be available to the message handler as additional information that could be used; but the default probably should not do so.


Anything else should be in the add-on as it is a preference for the application usage.
Some instances its better to have a file; others a shared system. It's a decision that should be left up to each application.
That's why it should be in the add-on only.

Ben
w***@nokia.com
2012-02-05 23:20:42 UTC
Permalink
That's exactly right.

Category log is not on at all at default.
If category log is on the default output is used (same of qDebug()).
Only logging in an output log file is active if you explicit set this in your config file.
Activation of category log comes from outside via configuration file and maybe environment variable but no recompiling neccessary.

--
wbeck



-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext BRM
Sent: Friday, February 03, 2012 11:33 AM
To: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

----- Original Message -----
> From: "***@nokia.com" <***@nokia.com>
> To: robin+***@viroteck.net; ***@kdab.com
> Cc: ***@qt-project.org
> Sent: Thursday, February 2, 2012 6:00 PM
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> I think we can change the current QLog.
>
> Category using qDebug(category) and writing stuff out in an output file.
> For me a logging file is much more important than system logs or
> socket because you can ask the customer that uses your Qt application
> to send you back the output log file.
> Other cool stuff like writing into sockets can be done in an addOn or
> even in a plugin.

qDebug() and friends should continue outputting as they currently do. The only difference should be the addition of the category/area (whatever you want to call it); and even then that should be available to the message handler as additional information that could be used; but the default probably should not do so.


Anything else should be in the add-on as it is a preference for the application usage.
Some instances its better to have a file; others a shared system. It's a decision that should be left up to each application.
That's why it should be in the add-on only.

Ben
w***@nokia.com
2012-02-07 06:54:55 UTC
Permalink
I'm working to integrade category log with QMessageLogger & Co and unfortunatelly we can not use
qDebg(<category>) << "my message" because there is already a debug(const char *msg, ...) function
combining with the macro
#define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug.

So I use a new function and macro:
QDebug debug();
QDebug debugCategory(const char *msg);
QDebug warning();
QDebug warningCategory(const char *msg);
QDebug critical();
QDebug criticalCategory(const char *msg);
QDebug fatalCategory(const char *msg);

#define qDebugCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debugCategory(#category)
#define qWarningCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).warningCategory(#category)
#define qCriticalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).criticalCategory(#category)
#define qFatalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).fatalCategory(#category)

Any problems with this naming conventions???

Cheers,
WB
k***@nokia.com
2012-02-07 07:26:53 UTC
Permalink
Hi Wolfgang,

how about making the category a distinct type instead?

struct QMessageCategory {
explicit QMessageCategory(const char *name);
};

class QMessageLogger {
void debug(const char *format, ...);
void debug(QMessageCategory category, const char *format, ...);
}


...
QDebugCategory debugCategory("MyApp"); // You'll typically do this in one place
...
qDebug(debugCategory, "hi there");


Anyhow, you probably don't want to set the category explicitly for every call in e.g. QtCore, so you can also pass it implicitly via a DEFINE:

class QMessageLogger {
QMessageLogger(const char *file, int line, const char *function, const char *defaultCategory) {
}
}

#define Q_DEBUG_CATEGORY "" // empty default
#define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, Q_DEBUG_CATEGORY).debug


And QtCore is then compiled with DEFINES+="Q_DEBUG_CATEGORY=QtCore". IMO both approaches are complementary, passing an explicit category would overwrite the Q_DEBUG_CATEGORY define.

Regards

Kai

________________________________________
From: development-bounces+kai.koehne=***@qt-project.org [development-bounces+kai.koehne=***@qt-project.org] on behalf of Beck Wolfgang (Nokia-MP/Brisbane)
Sent: Tuesday, February 07, 2012 7:54 AM
To: ***@qt-project.org
Subject: [Development] QLog ( Work on qDebug and friends)

I'm working to integrade category log with QMessageLogger & Co and unfortunatelly we can not use
qDebg(<category>) << "my message" because there is already a debug(const char *msg, ...) function
combining with the macro
#define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug.

So I use a new function and macro:
QDebug debug();
QDebug debugCategory(const char *msg);
QDebug warning();
QDebug warningCategory(const char *msg);
QDebug critical();
QDebug criticalCategory(const char *msg);
QDebug fatalCategory(const char *msg);

#define qDebugCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debugCategory(#category)
#define qWarningCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).warningCategory(#category)
#define qCriticalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).criticalCategory(#category)
#define qFatalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).fatalCategory(#category)

Any problems with this naming conventions???

Cheers,
WB
w***@nokia.com
2012-02-09 07:10:39 UTC
Permalink
Hi Kai,

I think this was a very good idea so I've tried it but I've run into one important problem.
If I use this trick I have to call the overloaded function in QMessageLogger:
e.g.
1. void debug(QMessageCategory category, const char *format, ...);
and
2. QDebug debug(QMessageCategory category);

The first function is ok but the 2. one needs to return a QDebug object.
In this case I have to do a lots of overhead e.g. function call and creating object after I can check if the category should be logged or not.
So better having a other named macro which I can do

#define qLog(category) \
If(!logging_enable); \
Else QMessageCategory(....).debug()

Cheers,
WB


-----Original Message-----
From: Koehne Kai (Nokia-MP/Berlin)
Sent: Tuesday, February 07, 2012 5:27 PM
To: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
Subject: RE: QLog ( Work on qDebug and friends)

Hi Wolfgang,

how about making the category a distinct type instead?

struct QMessageCategory {
explicit QMessageCategory(const char *name); };

class QMessageLogger {
void debug(const char *format, ...);
void debug(QMessageCategory category, const char *format, ...); }


...
QDebugCategory debugCategory("MyApp"); // You'll typically do this in one place
...
qDebug(debugCategory, "hi there");


Anyhow, you probably don't want to set the category explicitly for every call in e.g. QtCore, so you can also pass it implicitly via a DEFINE:

class QMessageLogger {
QMessageLogger(const char *file, int line, const char *function, const char *defaultCategory) {
}
}

#define Q_DEBUG_CATEGORY "" // empty default
#define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, Q_DEBUG_CATEGORY).debug


And QtCore is then compiled with DEFINES+="Q_DEBUG_CATEGORY=QtCore". IMO both approaches are complementary, passing an explicit category would overwrite the Q_DEBUG_CATEGORY define.

Regards

Kai

________________________________________
From: development-bounces+kai.koehne=***@qt-project.org [development-bounces+kai.koehne=***@qt-project.org] on behalf of Beck Wolfgang (Nokia-MP/Brisbane)
Sent: Tuesday, February 07, 2012 7:54 AM
To: ***@qt-project.org
Subject: [Development] QLog ( Work on qDebug and friends)

I'm working to integrade category log with QMessageLogger & Co and unfortunatelly we can not use
qDebg(<category>) << "my message" because there is already a debug(const char *msg, ...) function
combining with the macro
#define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug.

So I use a new function and macro:
QDebug debug();
QDebug debugCategory(const char *msg);
QDebug warning();
QDebug warningCategory(const char *msg);
QDebug critical();
QDebug criticalCategory(const char *msg);
QDebug fatalCategory(const char *msg);

#define qDebugCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debugCategory(#category)
#define qWarningCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).warningCategory(#category)
#define qCriticalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).criticalCategory(#category)
#define qFatalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).fatalCategory(#category)

Any problems with this naming conventions???

Cheers,
WB
k***@nokia.com
2012-02-09 09:05:14 UTC
Permalink
> -----Original Message-----
> From: Beck Wolfgang (Nokia-MP/Brisbane)
> Sent: Thursday, February 09, 2012 8:11 AM
> To: Koehne Kai (Nokia-MP/Berlin); ***@qt-project.org
> Subject: RE: QLog ( Work on qDebug and friends)
>
> Hi Kai,


Hi Wolfgang,

> I think this was a very good idea so I've tried it but I've run into one important
> problem.
> If I use this trick I have to call the overloaded function in QMessageLogger:
> e.g.
> 1. void debug(QMessageCategory category, const char *format, ...); and 2.
> QDebug debug(QMessageCategory category);
>
> The first function is ok but the 2. one needs to return a QDebug object.
> In this case I have to do a lots of overhead e.g. function call and creating
> object after I can check if the category should be logged or not.
>
> So better having a other named macro which I can do
>
> #define qLog(category) \
> If(!logging_enable); \
> Else QMessageCategory(....).debug()

I see. You'll indeed need something like that if you want to define which category to log or not with the help of the macro expander.

You might still get half-way there performance wise though by giving QDebug a boolean "active", and check for it in the various operator<<, e.g.

inline QDebug &operator<<(qint64 t) { if (!active) return *this; stream->ts << QString::number(t); return maybeSpace(); }

If everything is inlined, and the various overloads of operator<< that people can implement do the check too, this should mostly come down to just in a couple of if (false) ... being executed.

Anyhow, a more basic question I have is whether we want the filtering by category be done at runtime (e.g. in a central message handler), or at compile time (like your solution seems to be based on). Maybe there's place for both, but I thought the idea for the Qt libraries was to avoid the need for recompiles ...

Regards

Kai Koehne

> Cheers,
> WB
>
>
> -----Original Message-----
> From: Koehne Kai (Nokia-MP/Berlin)
> Sent: Tuesday, February 07, 2012 5:27 PM
> To: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
> Subject: RE: QLog ( Work on qDebug and friends)
>
> Hi Wolfgang,
>
> how about making the category a distinct type instead?
>
> struct QMessageCategory {
> explicit QMessageCategory(const char *name); };
>
> class QMessageLogger {
> void debug(const char *format, ...);
> void debug(QMessageCategory category, const char *format, ...); }
>
>
> ...
> QDebugCategory debugCategory("MyApp"); // You'll typically do this in one
> place ...
> qDebug(debugCategory, "hi there");
>
>
> Anyhow, you probably don't want to set the category explicitly for every call
> in e.g. QtCore, so you can also pass it implicitly via a DEFINE:
>
> class QMessageLogger {
> QMessageLogger(const char *file, int line, const char *function, const char
> *defaultCategory) {
> }
> }
>
> #define Q_DEBUG_CATEGORY "" // empty default #define qDebug
> QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO,
> Q_DEBUG_CATEGORY).debug
>
>
> And QtCore is then compiled with
> DEFINES+="Q_DEBUG_CATEGORY=QtCore". IMO both approaches are
> complementary, passing an explicit category would overwrite the
> Q_DEBUG_CATEGORY define.
>
> Regards
>
> Kai
>
> ________________________________________
> From: development-bounces+kai.koehne=***@qt-project.org
> [development-bounces+kai.koehne=***@qt-project.org] on behalf
> of Beck Wolfgang (Nokia-MP/Brisbane)
> Sent: Tuesday, February 07, 2012 7:54 AM
> To: ***@qt-project.org
> Subject: [Development] QLog ( Work on qDebug and friends)
>
> I'm working to integrade category log with QMessageLogger & Co and
> unfortunatelly we can not use
> qDebg(<category>) << "my message" because there is already a debug(const
> char *msg, ...) function combining with the macro #define qDebug
> QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug.
>
> So I use a new function and macro:
> QDebug debug();
> QDebug debugCategory(const char *msg);
> QDebug warning();
> QDebug warningCategory(const char *msg);
> QDebug critical();
> QDebug criticalCategory(const char *msg);
> QDebug fatalCategory(const char *msg);
>
> #define qDebugCat(category) QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).debugCategory(#category)
> #define qWarningCat(category) QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).warningCategory(#category)
> #define qCriticalCat(category) QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).criticalCategory(#category)
> #define qFatalCat(category) QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).fatalCategory(#category)
>
> Any problems with this naming conventions???
>
> Cheers,
> WB
>
> _______________________________________________
> Development mailing list
> ***@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
BRM
2012-02-09 15:16:29 UTC
Permalink
> From: "***@nokia.com" <***@nokia.com>

>> -----Original Message-----
>> From: Beck Wolfgang (Nokia-MP/Brisbane)
>> I think this was a very good idea so I've tried it but I've run into one important
>> problem.
>> If I use this trick I have to call the overloaded function in QMessageLogger:
>> e.g.
>> 1. void debug(QMessageCategory category, const char *format, ...); and 2.
>> QDebug debug(QMessageCategory category);
>>
>> The first function is ok but the 2. one needs to return a QDebug object.
>> In this case I have to do a lots of overhead e.g. function call and creating
>> object after I can check if the category should be logged or not.
>>
>> So better having a other named macro which I can do
>>
>> #define qLog(category) \
>>    If(!logging_enable);    \
>> Else QMessageCategory(....).debug()
>
>I see. You'll indeed need something like that if you want to define which category to log or not with the help of the macro expander.
>
>You might still get half-way there performance wise though by giving QDebug a boolean "active", and check for it in the various operator<<, e.g.
>
>  inline QDebug &operator<<(qint64 t)        { if (!active) return *this; stream->ts << QString::number(t); return maybeSpace(); }
>
>If everything is inlined, and the various overloads of operator<< that people can implement do the check too, this should mostly come down to just in a couple of if (false) ... being executed.
>
>Anyhow, a more basic question I have is whether we want the filtering by category be done at runtime (e.g. in a central message handler), or at compile time (like your solution seems to be based on). Maybe there's place for both, but I thought the idea for the Qt libraries was to avoid the need for recompiles ...
>

If the performance is not penalized and the logging is not done overboard, then I would suggest doing so at Run Time so that the various categories can be enabled/disabled as desired for debugging purposes.
That said, there may be a place for having a compile time option to entirely disable it too - e.g. for distributions and commercial (Digia) binary releases to be able to completely disable it on release builds.

$0.02

Ben
Lincoln Ramsay
2012-02-09 23:29:59 UTC
Permalink
On 02/10/2012 01:16 AM, ext BRM wrote:
> That said, there may be a place for having a compile time option to
> entirely disable it too - e.g. for distributions and commercial
> (Digia) binary releases to be able to completely disable it on
> release builds.

Removing the logging statement entirely is achieved by expanding the
macro to:
if (1) /*NOP*/; else qDebug()

Technically, you'd have to wrap the logging statement in a #ifdef/#endif
pair to ensure it's completely removed but I think compilers can
correctly determine that the else is never hit (due to the constant in
the if) and so omit that code from the binary. Certainly, that code will
never be run when the macro expands this way.

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
Lincoln Ramsay
2012-02-09 23:25:05 UTC
Permalink
On 02/09/2012 07:05 PM, ext ***@nokia.com wrote:
> I see. You'll indeed need something like that if you want to define
> which category to log or not with the help of the macro expander.

The point here is that a disabled category adds very minimal runtime
overhead. We must get to the "do nothing" case in as few instructions as
possible or performance of Qt will tank (since this is supposed to
facilitate logging statements being left in Qt).

> You might still get half-way there performance wise though by giving
> QDebug a boolean "active", and check for it in the various
> operator<<

Not even close. Ok... maybe if you only ever pass primitive types.
Consider this though:

qLog(category) << some_expensive_function();

The only way to avoid some_expensive_function() is to not execute that
code path at all. Thus the macro expansion:

if (do_nothing) /*NOP*/; else qDebug() << some_expensive_function();

> Anyhow, a more basic question I have is whether we want the filtering
> by category be done at runtime (e.g. in a central message handler),
> or at compile time (like your solution seems to be based on). Maybe
> there's place for both, but I thought the idea for the Qt libraries
> was to avoid the need for recompiles ...

qLog is most certainly a run-time system.

The actual macro looks more like this:

if (!global_enabled() || !category_enabled(cat)) /*NOP*/; else qDebug()

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
David Faure
2012-02-16 15:01:30 UTC
Permalink
On Friday 10 February 2012 09:25:05 Lincoln Ramsay wrote:
> The only way to avoid some_expensive_function() is to not execute that
> code path at all. Thus the macro expansion:
>
> if (do_nothing) /*NOP*/; else qDebug() << some_expensive_function();

I think this is missing the point that qDebug() itself is a macro already
(now, in qt5).

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

So why not *change* the qDebug macro to something like

if (!global_enabled()) /*NOP*/; else QMessageLogger(__FILE__, __LINE__,
Q_FUNC_INFO).debug

and the function/macro that takes categories can add the check for categories
in addition.

The goal: that global_enabled() affects *all* qDebug statements, not only those
with a category, leading to better integration, rather than to two competing
frameworks inside QtCore itself (try to explain to a new developer, the reason
why the global switch to disable debug output only works when a category is
specified...). The only reason is "well, I didn't dare to touch qDebug itself"?
I think it's the right time to touch it :-)

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
Lincoln Ramsay
2012-02-16 23:19:04 UTC
Permalink
On 02/17/2012 01:01 AM, ext David Faure wrote:
> So why not *change* the qDebug macro to something like
>
> if (!global_enabled()) /*NOP*/; else QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).debug

Please see the other thread with BRM. He advocates the same kind of
approach. I'm not going to repeat the reasons why this is not acceptable.

> The goal: that global_enabled() affects *all* qDebug statements, not only those
> with a category

Unlike qLog (which defaults to off), qDebug must be on by default or we
break all existing code. This means a "runtime" switch for qDebug would
only serve to turn all qDebugs off.

Is this really a useful thing? Qt itself has no qDebug statements but
perhaps other, third party libraries have left them in. In that case,
having a runtime disable option may be warranted.

Is that what you meant?

> (try to explain to a new developer, the reason
> why the global switch to disable debug output

There is no "global switch" to "disable debug output" with qLog. Please
read the code before commenting on the implementation.
http://codereview.qt-project.org/#change,13226

>The only reason is "well, I didn't dare to touch qDebug itself"?
> I think it's the right time to touch it :-)

As has already been covered, the C++ language does not let us overload
the qDebug macro with category support and overloading at the function
level results in a potentially large performance hit.


--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
David Faure
2012-02-17 08:23:14 UTC
Permalink
On Friday 17 February 2012 09:19:04 Lincoln Ramsay wrote:
> > The goal: that global_enabled() affects *all* qDebug statements, not only
> > those with a category
>
> Unlike qLog (which defaults to off), qDebug must be on by default or we
> break all existing code. This means a "runtime" switch for qDebug would
> only serve to turn all qDebugs off.

"Breaking existing code" in terms of "changing the default in Qt5" isn't that
big a deal, it's not like people will have to change their code, just to
enable a setting.

But I can see an interesting point here: with your current solution,
qDebug is the one to use for throw-away debug statements added temporarily to
a piece of code one is debugging, while qLog(area) is for debug statements
that will stay into the committed code, and therefore the first one should be
enabled by default (for convenience) and the second one should be disabled by
default (for noise reducing reasons). This is a valid point for the different
default, I can accept it.

> Is this really a useful thing? Qt itself has no qDebug statements but
> perhaps other, third party libraries have left them in. In that case,
> having a runtime disable option may be warranted.
>
> Is that what you meant?

Yes, end users don't like debug statements polluting their terminals and
session log file. With the above reasoning, we could just keep saying "do not
use qDebug in committed code" and the problem would be fixed. But in the
case where developers don't follow that rule, users will appreciate an off
switch :).

> > (try to explain to a new developer, the reason
> > why the global switch to disable debug output
>
> There is no "global switch" to "disable debug output" with qLog.

What's QLog::instance()->isEnabled() then ?

> Please read the code before commenting on the implementation.
> http://codereview.qt-project.org/#change,13226

Hey, I reviewed on that change before I even wrote here. But the global switch
idea comes from your own email from 10/02, which says:
if (!global_enabled() || !category_enabled(cat)) /*NOP*/; else qDebug()"

I didn't make up that notion of global_enabled(), it's from you...

> >The only reason is "well, I didn't dare to touch qDebug itself"?
> >
> > I think it's the right time to touch it :-)
>
> As has already been covered, the C++ language does not let us overload
> the qDebug macro with category support and overloading at the function
> level results in a potentially large performance hit.

Sorry I didn't mean "the qDebug macro/API", but the QDebug implementation.
I'd like qDebug() and qLog() to share as much as possible of the
implementation. I can drop the idea of the global enabled switch affecting
both, for the reason above, but still, QT_MESSAGE_PATTERN should affect both,
qInstallMessageHandler should affect both, etc. More generally, sharing the
same output subsystem (with the addition of logging to files, but that's
downstream from the shared formatting and handler-hook code).

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
Lincoln Ramsay
2012-02-20 02:21:43 UTC
Permalink
On 02/17/2012 06:23 PM, ext David Faure wrote:
>> There is no "global switch" to "disable debug output" with qLog.
>
> What's QLog::instance()->isEnabled() then ?

An optimization from back when you had to call a C++ method to enable
logging and when each category check involved QMap and QString
operations. I have my doubts that this even needs to exist anymore. It
may even hurt performance in a corner case to have this function.

>> Please read the code before commenting on the implementation.
>> http://codereview.qt-project.org/#change,13226
>
> Hey, I reviewed on that change before I even wrote here. But the global switch
> idea comes from your own email from 10/02, which says:
> if (!global_enabled() || !category_enabled(cat)) /*NOP*/; else qDebug()"
>
> I didn't make up that notion of global_enabled(), it's from you...

Ok, but see above. There is no "switch" that controls that anymore.

> Sorry I didn't mean "the qDebug macro/API", but the QDebug implementation.
> I'd like qDebug() and qLog() to share as much as possible of the
> implementation.

So do we :)

There's more merging going on that may not be visible in the change yet.

qLog() and qDebug() will both use QMessageLogger and (unless you've used
qLog to write to a file) the default message handler will be invoked so
the formatting will match.

> QT_MESSAGE_PATTERN should affect both,
> qInstallMessageHandler should affect both, etc.

I wrote the above before I saw this.

> More generally, sharing the
> same output subsystem (with the addition of logging to files, but that's
> downstream from the shared formatting and handler-hook code).

Yes, with one caveat.

We feel the use case of "I have no add-on but I want logs captured to a
file" merits the inclusion of file-writing code into QtCore. This is
turned on via the qlog config file and the formatting for this can be
set in the config file.

But you can most certainly ignore that and do output from a message
handler (or use an add-on that gives you output options, once it exists).

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
Lincoln Ramsay
2012-02-20 02:25:07 UTC
Permalink
On 02/17/2012 06:23 PM, ext David Faure wrote:
> Yes, end users don't like debug statements polluting their terminals and
> session log file. With the above reasoning, we could just keep saying "do not
> use qDebug in committed code" and the problem would be fixed. But in the
> case where developers don't follow that rule, users will appreciate an off
> switch :).

Ok... I think I'm convinced.

You can of course always drop these messages from the message handler. I
know working on Qtopia we did exactly that so that qDebugs were never
seen in "release" builds even if they were accidentally checked into the
repo.

Turning off qDebugs using the "if (!enabled); else" pattern would make
these ignored debugs cheaper so it makes sense to do that in the macro.

Where I'm a bit less clear is how the API for this would look.

Do you imagine something in the qLog config file? An environment
variable? A C++ API?

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
Thiago Macieira
2012-02-20 08:00:12 UTC
Permalink
On segunda-feira, 20 de fevereiro de 2012 12.25.07, Lincoln Ramsay wrote:
> You can of course always drop these messages from the message handler. I
> know working on Qtopia we did exactly that so that qDebugs were never
> seen in "release" builds even if they were accidentally checked into the
> repo.

Skype does that too.

But if you start it in gdb and reset the message handler, it prints lots of
its own stuff :-)

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
David Faure
2012-02-20 11:42:49 UTC
Permalink
On Monday 20 February 2012 12:25:07 Lincoln Ramsay wrote:
> On 02/17/2012 06:23 PM, ext David Faure wrote:
> > Yes, end users don't like debug statements polluting their terminals and
> > session log file. With the above reasoning, we could just keep saying "do
> > not use qDebug in committed code" and the problem would be fixed. But in
> > the case where developers don't follow that rule, users will appreciate
> > an off switch :).
>
> Ok... I think I'm convinced.
>
> You can of course always drop these messages from the message handler.

No, users cannot do that ;)
Application developers can, but not library developers nor users.

Especially in the open source world, where libraries and apps are developed by
different people, and the app developers have little control over the code in
the libs they are using. Well, I suspect this happens in commercial setups too
:-).
Proper usage of qLog with areas solves the "lib issue", but there's also the
case of using 20 different apps, which use qDebug without an area (that's what
qDebug is for), and users then need to be able to switch it off.

> Turning off qDebugs using the "if (!enabled); else" pattern would make
> these ignored debugs cheaper so it makes sense to do that in the macro.

Yep.

> Where I'm a bit less clear is how the API for this would look.
>
> Do you imagine something in the qLog config file? An environment
> variable? A C++ API?

I think "something in the qLog config file" is the best option. It allows to
provide a GUI tool that toggles the configuration, for users.

An env var would be my second favorite, a C++ API is definitely a no since the
goal is to let users toggle it.

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
Thiago Macieira
2012-02-20 13:33:26 UTC
Permalink
On segunda-feira, 20 de fevereiro de 2012 12.42.49, David Faure wrote:
> > Do you imagine something in the qLog config file? An environment
> > variable? A C++ API?
>
> I think "something in the qLog config file" is the best option. It allows
> to provide a GUI tool that toggles the configuration, for users.

Remember that QtCore has no configuration file. We've removed all traces of
QSettings support so QSettings could be moved away.

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
BRM
2012-02-20 14:13:33 UTC
Permalink
----- Original Message -----

> From: Thiago Macieira <***@intel.com>
> On segunda-feira, 20 de fevereiro de 2012 12.42.49, David Faure wrote:
>> > Do you imagine something in the qLog config file? An environment
>> > variable? A C++ API?
>>
>> I think "something in the qLog config file" is the best option.
> It allows
>> to  provide a GUI tool that toggles the configuration, for users.
>
> Remember that QtCore has no configuration file. We've removed all traces of
> QSettings support so QSettings could be moved away.

How about have some method of the application that could load what to log or not log;
a simple set of 2 functions, each takes a QStringList of the categories:

// positive enabling (negative disable)
static void QMessageLogger::enableLogCategories(QStringList categoryList);
// positive disabling (negative enable)
static void QMessageLogger::disableLogCategories(QStringList categoryList);

// to enable verification of the above
static bool QMessageLogger::isPositiveEnable();
static bool QMessageLogger::isPositiveDisable();

// return the current list of categories loaded for positive enabling/disabling
static QStringList QMessageLogger::getCategories();
// return the build-time list of Qt categories
static QStringList QMessageLogger::getQtCategories();

Only one method could be used at a time.

It would be up to the application developer which to use and how to load it.

By default, all Qt message categories would be positively disabled.

$0.02

Ben
w***@nokia.com
2012-02-21 07:07:35 UTC
Permalink
One of the requirements was to activate the category log without recompiling the code.
Of course you can design QLog in that way that it can overwrite the category flags out from the QLog config file but then we have two different ways to activate or deactivate categories and each QLog enable check (remember the macros) and category check becomes bigger and maybe more complex.
If QLog works only with the config file you can be sure after you are done with developing QLog is disable as long you don't add the config file in your package.
How hard can it be to create a simple config file and change the category values?

B.R.
WB



-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext BRM
Sent: Tuesday, February 21, 2012 12:14 AM
To: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

----- Original Message -----

> From: Thiago Macieira <***@intel.com> On segunda-feira, 20
> de fevereiro de 2012 12.42.49, David Faure wrote:
>> > Do you imagine something in the qLog config file? An environment
>> > variable? A C++ API?
>>
>> I think "something in the qLog config file" is the best option.
> It allows
>> to  provide a GUI tool that toggles the configuration, for users.
>
> Remember that QtCore has no configuration file. We've removed all
> traces of QSettings support so QSettings could be moved away.

How about have some method of the application that could load what to log or not log; a simple set of 2 functions, each takes a QStringList of the categories:

// positive enabling (negative disable)
static void QMessageLogger::enableLogCategories(QStringList categoryList); // positive disabling (negative enable) static void QMessageLogger::disableLogCategories(QStringList categoryList);

// to enable verification of the above
static bool QMessageLogger::isPositiveEnable();
static bool QMessageLogger::isPositiveDisable();

// return the current list of categories loaded for positive enabling/disabling static QStringList QMessageLogger::getCategories(); // return the build-time list of Qt categories static QStringList QMessageLogger::getQtCategories();

Only one method could be used at a time.

It would be up to the application developer which to use and how to load it.

By default, all Qt message categories would be positively disabled.

$0.02

Ben
David Faure
2012-02-20 15:38:50 UTC
Permalink
On Monday 20 February 2012 14:33:26 Thiago Macieira wrote:
> On segunda-feira, 20 de fevereiro de 2012 12.42.49, David Faure wrote:
> > > Do you imagine something in the qLog config file? An environment
> > > variable? A C++ API?
> >
> > I think "something in the qLog config file" is the best option. It allows
> > to provide a GUI tool that toggles the configuration, for users.
>
> Remember that QtCore has no configuration file.

Clearly you haven't read http://codereview.qt-project.org/#change,13226

> We've removed all traces of
> QSettings support so QSettings could be moved away.


--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
David Faure
2012-02-20 15:42:00 UTC
Permalink
[oops, mail sent too early]

On Monday 20 February 2012 16:38:50 David Faure wrote:
> On Monday 20 February 2012 14:33:26 Thiago Macieira wrote:
> > On segunda-feira, 20 de fevereiro de 2012 12.42.49, David Faure wrote:
> > > > Do you imagine something in the qLog config file? An environment
> > > > variable? A C++ API?
> > >
> > > I think "something in the qLog config file" is the best option. It
> > > allows
> > > to provide a GUI tool that toggles the configuration, for users.
> >
> > Remember that QtCore has no configuration file.
>
> Clearly you haven't read http://codereview.qt-project.org/#change,13226
>
> > We've removed all traces of
> > QSettings support so QSettings could be moved away.

QFile is all that's needed to implement a basic config file, QSettings is not
needed.

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
Thiago Macieira
2012-02-20 17:17:50 UTC
Permalink
On segunda-feira, 20 de fevereiro de 2012 16.42.00, David Faure wrote:
> > Clearly you haven't read http://codereview.qt-project.org/#change,13226
> >
> >
> >
> > > We've removed all traces of
> > > QSettings support so QSettings could be moved away.
>
> QFile is all that's needed to implement a basic config file, QSettings is
> not needed.

No, I haven't looked at the patch yet. (Take a look at my dashboard to see
why)

Let QLog have a function that allows one to externally enable and disable
categories. If you really want to, provide a way to parse config data via
QFile, like you suggested.

But please don't hardcode any file names inside the library.

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
w***@nokia.com
2012-02-21 07:15:48 UTC
Permalink
Well we have 3 different ways and priorities to set the config file.

One of the possibilities is:
We have a default config file which uses a hardcoded filename but the path to this file is created with the default config file path + organization name + application name.
For detailed information please visit:
http://codereview.qt-project.org/13226

B.R.
WB




-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext Thiago Macieira
Sent: Tuesday, February 21, 2012 3:18 AM
To: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On segunda-feira, 20 de fevereiro de 2012 16.42.00, David Faure wrote:
> > Clearly you haven't read
> > http://codereview.qt-project.org/#change,13226
> >
> >
> >
> > > We've removed all traces of
> > > QSettings support so QSettings could be moved away.
>
> QFile is all that's needed to implement a basic config file, QSettings
> is not needed.

No, I haven't looked at the patch yet. (Take a look at my dashboard to see
why)

Let QLog have a function that allows one to externally enable and disable categories. If you really want to, provide a way to parse config data via QFile, like you suggested.

But please don't hardcode any file names inside the library.

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
Thiago Macieira
2012-02-21 08:30:25 UTC
Permalink
On terça-feira, 21 de fevereiro de 2012 07.15.48, ***@nokia.com
wrote:
> We have a default config file which uses a hardcoded filename but the path
> to this file is created with the default config file path + organization
> name + application name.

I don't want this. Application names and organisation names change every now
and then. The applications may know about their own settings and migrate
those, but if we have hardcoded paths coming from inside QtCore, those will
get lost in the move.

Please restrict this to an environment variable and to supplying a QIODevice*.

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
w***@nokia.com
2012-02-22 02:37:48 UTC
Permalink
OK,

So we've now 2 options to set the config file.
1. QLOG_CONFIG_FILE environment variable
2. setDefaultConfigFile function.

What do you mean with:
... and to supplying a QIODevice*?

B.R.
WB

-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext Thiago Macieira
Sent: Tuesday, February 21, 2012 6:30 PM
To: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On terça-feira, 21 de fevereiro de 2012 07.15.48, ***@nokia.com
wrote:
> We have a default config file which uses a hardcoded filename but the
> path to this file is created with the default config file path +
> organization name + application name.

I don't want this. Application names and organisation names change every now and then. The applications may know about their own settings and migrate those, but if we have hardcoded paths coming from inside QtCore, those will get lost in the move.

Please restrict this to an environment variable and to supplying a QIODevice*.

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
Thiago Macieira
2012-02-22 08:32:43 UTC
Permalink
On quarta-feira, 22 de fevereiro de 2012 02.37.48, ***@nokia.com
wrote:
> OK,
>
> So we've now 2 options to set the config file.
> 1. QLOG_CONFIG_FILE environment variable
> 2. setDefaultConfigFile function.
>
> What do you mean with:
> ... and to supplying a QIODevice*?

void QLog::loadConfig(QIODevice *device);

It's your option 2 above, except generalised to any QIODevice.

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
w***@nokia.com
2012-02-21 06:30:17 UTC
Permalink
Yes I know and I've changed it.
No QSetting is used anymore.

B.R.
WB

-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext Thiago Macieira
Sent: Monday, February 20, 2012 11:33 PM
To: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On segunda-feira, 20 de fevereiro de 2012 12.42.49, David Faure wrote:
> > Do you imagine something in the qLog config file? An environment
> > variable? A C++ API?
>
> I think "something in the qLog config file" is the best option. It
> allows to provide a GUI tool that toggles the configuration, for users.

Remember that QtCore has no configuration file. We've removed all traces of QSettings support so QSettings could be moved away.

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
w***@nokia.com
2012-02-21 06:28:38 UTC
Permalink
I'm preferring having QLog active only if a config file is there.
It doesn't make sense to me at all having an environment variable that can activate QLog but not config file to activate the categories.
As long there is no config file QLog is disable and uses less performance as possible but still having the feature that you can activate it without recompiling the code.

Cheers,
WB



-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext David Faure
Sent: Monday, February 20, 2012 9:43 PM
To: Ramsay Lincoln (Nokia-MP/Brisbane)
Cc: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On Monday 20 February 2012 12:25:07 Lincoln Ramsay wrote:
> On 02/17/2012 06:23 PM, ext David Faure wrote:
> > Yes, end users don't like debug statements polluting their terminals
> > and session log file. With the above reasoning, we could just keep
> > saying "do not use qDebug in committed code" and the problem would
> > be fixed. But in the case where developers don't follow that rule,
> > users will appreciate an off switch :).
>
> Ok... I think I'm convinced.
>
> You can of course always drop these messages from the message handler.

No, users cannot do that ;)
Application developers can, but not library developers nor users.

Especially in the open source world, where libraries and apps are developed by different people, and the app developers have little control over the code in the libs they are using. Well, I suspect this happens in commercial setups too :-).
Proper usage of qLog with areas solves the "lib issue", but there's also the case of using 20 different apps, which use qDebug without an area (that's what qDebug is for), and users then need to be able to switch it off.

> Turning off qDebugs using the "if (!enabled); else" pattern would make
> these ignored debugs cheaper so it makes sense to do that in the macro.

Yep.

> Where I'm a bit less clear is how the API for this would look.
>
> Do you imagine something in the qLog config file? An environment
> variable? A C++ API?

I think "something in the qLog config file" is the best option. It allows to provide a GUI tool that toggles the configuration, for users.

An env var would be my second favorite, a C++ API is definitely a no since the goal is to let users toggle it.

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-independent software solutions
David Faure
2012-02-21 09:36:08 UTC
Permalink
On Tuesday 21 February 2012 06:28:38 ***@nokia.com wrote:
> I'm preferring having QLog active only if a config file is there.
> It doesn't make sense to me at all having an environment variable that can
> activate QLog but not config file to activate the categories. As long there
> is no config file QLog is disable and uses less performance as possible but
> still having the feature that you can activate it without recompiling the
> code.

Why? IMHO things should go to stderr by default. So it makes perfect sense to
see the output, even if one didn't configure output files in a config file.

I guess this is a mobile platform vs desktop platform discussion. On a mobile
platform the logs are only useful if they go to a file, while on the desktop
the logs are useful also if they go to stderr, to get them in a terminal or in
the session log file.

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
k***@nokia.com
2012-02-21 10:02:23 UTC
Permalink
> -----Original Message-----
> From: development-bounces+kai.koehne=***@qt-project.org
> [mailto:development-bounces+kai.koehne=***@qt-project.org] On
> Behalf Of ext David Faure
> Sent: Tuesday, February 21, 2012 10:36 AM
> To: Beck Wolfgang (Nokia-MP/Brisbane)
> Cc: ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> On Tuesday 21 February 2012 06:28:38 ***@nokia.com wrote:
> > I'm preferring having QLog active only if a config file is there.
> > It doesn't make sense to me at all having an environment variable that
> > can activate QLog but not config file to activate the categories. As
> > long there is no config file QLog is disable and uses less performance
> > as possible but still having the feature that you can activate it
> > without recompiling the code.
>
> Why? IMHO things should go to stderr by default. So it makes perfect sense
> to see the output, even if one didn't configure output files in a config file.

I agree with that: On the desktop it's quite handy to see also detailed output on stderr/the shell (which one can redirect to a file if needed). But I also think that qLog() messages shouldn't show up by default for normal users, that is, unless the category has been explicitly enabled.

So how about adding another QtMsgType called QLogMsg, that qLog() uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages would not be processed by default, unless the configuration file (or an environment variable) says so ...

Kai

> I guess this is a mobile platform vs desktop platform discussion. On a mobile
> platform the logs are only useful if they go to a file, while on the desktop the
> logs are useful also if they go to stderr, to get them in a terminal or in the
> session log file.
>
>
> --
> David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
> KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08
> 53, Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-independent
> software solutions
>
> _______________________________________________
> Development mailing list
> ***@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
David Faure
2012-02-21 10:08:13 UTC
Permalink
On Tuesday 21 February 2012 10:02:23 ***@nokia.com wrote:
> I agree with that: On the desktop it's quite handy to see also detailed
> output on stderr/the shell (which one can redirect to a file if needed).
> But I also think that qLog() messages shouldn't show up by default for
> normal users, that is, unless the category has been explicitly enabled.

True.

> So how about adding another QtMsgType called QLogMsg, that qLog() uses? In
> contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages would not be
> processed by default, unless the configuration file (or an environment
> variable) says so ...

Isn't the same information given by "a category is present in the
QMessageLogContext"? All qLog calls are forced to get a category, right?

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
k***@nokia.com
2012-02-21 10:19:49 UTC
Permalink
> -----Original Message-----
> From: ext David Faure [mailto:***@kdab.com]
> Sent: Tuesday, February 21, 2012 11:08 AM
> To: Koehne Kai (Nokia-MP/Berlin)
> Cc: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> On Tuesday 21 February 2012 10:02:23 ***@nokia.com wrote:
> > I agree with that: On the desktop it's quite handy to see also
> > detailed output on stderr/the shell (which one can redirect to a file if
> needed).
> > But I also think that qLog() messages shouldn't show up by default for
> > normal users, that is, unless the category has been explicitly enabled.
>
> True.
>
> > So how about adding another QtMsgType called QLogMsg, that qLog()
> > uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages
> would
> > not be processed by default, unless the configuration file (or an
> > environment
> > variable) says so ...
>
> Isn't the same information given by "a category is present in the
> QMessageLogContext"? All qLog calls are forced to get a category, right?

Right, but that would mean we can't use categories for anything except qLog. If we use categories solely for the purpose of filtering that's probably fine, but I personally also see some value in having them available as free text in the log, for all log QtMsgType's ...

Regards

Kai


> --
> David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
> KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08
> 53, Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-independent
> software solutions
David Faure
2012-02-21 10:31:55 UTC
Permalink
On Tuesday 21 February 2012 10:19:49 ***@nokia.com wrote:
> > -----Original Message-----
> > From: ext David Faure [mailto:***@kdab.com]
> >
> > Isn't the same information given by "a category is present in the
> > QMessageLogContext"? All qLog calls are forced to get a category, right?
>
> Right, but that would mean we can't use categories for anything except qLog.
> If we use categories solely for the purpose of filtering that's probably
> fine, but I personally also see some value in having them available as free
> text in the log, for all log QtMsgType's ...

I would agree (after all we've been doing the same in KDE, it helps to
understand where a warning or error comes from). But for this to be possible,
we're back at the discussion of how to specify a category when calling qDebug
or qWarning, and I thought the conclusion was "no"...

In other words I like your idea, but there's no API to actually make it
possible...

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
w***@nokia.com
2012-02-22 00:37:40 UTC
Permalink
Why you want to use the categories somewhere else then QLog?
You want to reinvent a mechanism to filter the categories then?
If you don't filter what sense makes having the categories?
I mean you still have qDebug and you can write whatever you like.

Cheers,
WB



-----Original Message-----
From: Koehne Kai (Nokia-MP/Berlin)
Sent: Tuesday, February 21, 2012 8:20 PM
To: ext David Faure
Cc: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
Subject: RE: [Development] QLog ( Work on qDebug and friends)

> -----Original Message-----
> From: ext David Faure [mailto:***@kdab.com]
> Sent: Tuesday, February 21, 2012 11:08 AM
> To: Koehne Kai (Nokia-MP/Berlin)
> Cc: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> On Tuesday 21 February 2012 10:02:23 ***@nokia.com wrote:
> > I agree with that: On the desktop it's quite handy to see also
> > detailed output on stderr/the shell (which one can redirect to a
> > file if
> needed).
> > But I also think that qLog() messages shouldn't show up by default
> > for normal users, that is, unless the category has been explicitly enabled.
>
> True.
>
> > So how about adding another QtMsgType called QLogMsg, that qLog()
> > uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages
> would
> > not be processed by default, unless the configuration file (or an
> > environment
> > variable) says so ...
>
> Isn't the same information given by "a category is present in the
> QMessageLogContext"? All qLog calls are forced to get a category, right?

Right, but that would mean we can't use categories for anything except qLog. If we use categories solely for the purpose of filtering that's probably fine, but I personally also see some value in having them available as free text in the log, for all log QtMsgType's ...

Regards

Kai


> --
> David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
> KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84
> 08 53, Sweden (HQ) +46-563-540090 KDAB - Qt Experts -
> Platform-independent software solutions
k***@nokia.com
2012-02-22 08:19:12 UTC
Permalink
> -----Original Message-----
> From: Beck Wolfgang (Nokia-MP/Brisbane)
> Sent: Wednesday, February 22, 2012 1:38 AM
> To: Koehne Kai (Nokia-MP/Berlin); ext David Faure
> Cc: ***@qt-project.org
> Subject: RE: [Development] QLog ( Work on qDebug and friends)
>
> Why you want to use the categories somewhere else then QLog?

As I said, there are two possible reasons to have categories
* filtering. This is what apparently QLog is about
* As an additional information to quickly see where messages 'belong to'. E.g. a hypothetical log file might read

...
[warning] MyApp QtCore: QBuffer::setBuffer: Buffer is open
[warning] MyApp QtCreator.HelpManager: Error registering namespace 'Qt'
...

'QtCore', 'QtCreator.HelpManager' would quickly tell me where the messages belong to. (We're of course somewhat providing this info for the Qt Libraries already by encoding some context in the message itself ('QBuffer::setBuffer'). But other applications don't necessarily do this).

In understand that this is exactly what the 'area' in KDE/kdebug is about.

(Honestly speaking, we can of course live without this feature. But if we do it like in KDE, you'd provide a 'default' context by a compiler define, so the source code itself wouldn't get any uglier + the overhead wouldn't be that big. And since we already have a free-text 'category' field for qLog, why not allow it to be also put into the log file?).

> You want to reinvent a mechanism to filter the categories then?

I wouldn't provide one in Qt. But adding the category to the log message itself would allow to do filtering by system tools like grep, or rsyslog. That is, _after_ running the application.

> If you don't filter what sense makes having the categories?
> I mean you still have qDebug and you can write whatever you like.
>
> Cheers,
> WB
>
>
>
> -----Original Message-----
> From: Koehne Kai (Nokia-MP/Berlin)
> Sent: Tuesday, February 21, 2012 8:20 PM
> To: ext David Faure
> Cc: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
> Subject: RE: [Development] QLog ( Work on qDebug and friends)
>
> > -----Original Message-----
> > From: ext David Faure [mailto:***@kdab.com]
> > Sent: Tuesday, February 21, 2012 11:08 AM
> > To: Koehne Kai (Nokia-MP/Berlin)
> > Cc: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
> > Subject: Re: [Development] QLog ( Work on qDebug and friends)
> >
> > On Tuesday 21 February 2012 10:02:23 ***@nokia.com wrote:
> > > I agree with that: On the desktop it's quite handy to see also
> > > detailed output on stderr/the shell (which one can redirect to a
> > > file if
> > needed).
> > > But I also think that qLog() messages shouldn't show up by default
> > > for normal users, that is, unless the category has been explicitly enabled.
> >
> > True.
> >
> > > So how about adding another QtMsgType called QLogMsg, that qLog()
> > > uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages
> > would
> > > not be processed by default, unless the configuration file (or an
> > > environment
> > > variable) says so ...
> >
> > Isn't the same information given by "a category is present in the
> > QMessageLogContext"? All qLog calls are forced to get a category, right?
>
> Right, but that would mean we can't use categories for anything except qLog.
> If we use categories solely for the purpose of filtering that's probably fine,
> but I personally also see some value in having them available as free text in
> the log, for all log QtMsgType's ...
>
> Regards
>
> Kai
>
>
> > --
> > David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
> > KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84
> > 08 53, Sweden (HQ) +46-563-540090 KDAB - Qt Experts -
> > Platform-independent software solutions
w***@nokia.com
2012-02-22 00:31:35 UTC
Permalink
Yes David,
Absolutely right.

B.R.
WB



-----Original Message-----
From: ext David Faure [mailto:***@kdab.com]
Sent: Tuesday, February 21, 2012 8:08 PM
To: Koehne Kai (Nokia-MP/Berlin)
Cc: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On Tuesday 21 February 2012 10:02:23 ***@nokia.com wrote:
> I agree with that: On the desktop it's quite handy to see also
> detailed output on stderr/the shell (which one can redirect to a file if needed).
> But I also think that qLog() messages shouldn't show up by default for
> normal users, that is, unless the category has been explicitly enabled.

True.

> So how about adding another QtMsgType called QLogMsg, that qLog()
> uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages would
> not be processed by default, unless the configuration file (or an
> environment
> variable) says so ...

Isn't the same information given by "a category is present in the QMessageLogContext"? All qLog calls are forced to get a category, right?

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-independent software solutions
Thiago Macieira
2012-02-21 10:12:36 UTC
Permalink
On terça-feira, 21 de fevereiro de 2012 10.02.23, ***@nokia.com wrote:
> So how about adding another QtMsgType called QLogMsg, that qLog() uses? In
> contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages would not be
> processed by default, unless the configuration file (or an environment
> variable) says so ...

That's almost a necessity. An informative message is not debugging.
k***@nokia.com
2012-02-21 11:32:09 UTC
Permalink
> -----Original Message-----
> From: development-bounces+kai.koehne=***@qt-project.org
> [mailto:development-bounces+kai.koehne=***@qt-project.org] On
> Behalf Of ext Thiago Macieira
> Sent: Tuesday, February 21, 2012 11:13 AM
> To: ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> On terça-feira, 21 de fevereiro de 2012 10.02.23, ***@nokia.com
> wrote:
> > So how about adding another QtMsgType called QLogMsg, that qLog()
> > uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages
> would
> > not be processed by default, unless the configuration file (or an
> > environment
> > variable) says so ...
>
> That's almost a necessity. An informative message is not debugging.
>
> >
w***@nokia.com
2012-02-22 00:43:17 UTC
Permalink
We had this discussion before in the ML to add cool stuff like
Log into local socked, syslog or whatever.
This can be done later in an AddOn for example.

Cheers,
WB


-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext Thiago Macieira
Sent: Tuesday, February 21, 2012 8:13 PM
To: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On terça-feira, 21 de fevereiro de 2012 10.02.23, ***@nokia.com wrote:
> So how about adding another QtMsgType called QLogMsg, that qLog()
> uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages would
> not be processed by default, unless the configuration file (or an
> environment
> variable) says so ...

That's almost a necessity. An informative message is not debugging.

>
w***@nokia.com
2012-02-22 00:29:35 UTC
Permalink
> So how about adding another QtMsgType called QLogMsg, that qLog() uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages would not be processed by default, unless the configuration file (or an environment variable) says so ...

There is no need for this Kai.
The macro will not even create a QMessageLogger if the category is not enabled.
Have a look in the qMessageFormatString of the QLog patch how I detect if I need to add a category or not.

B.R.
WB

-----Original Message-----
From: Koehne Kai (Nokia-MP/Berlin)
Sent: Tuesday, February 21, 2012 8:02 PM
To: ext David Faure; Beck Wolfgang (Nokia-MP/Brisbane)
Cc: ***@qt-project.org
Subject: RE: [Development] QLog ( Work on qDebug and friends)

> -----Original Message-----
> From: development-bounces+kai.koehne=***@qt-project.org
> [mailto:development-bounces+kai.koehne=***@qt-project.org] On
> Behalf Of ext David Faure
> Sent: Tuesday, February 21, 2012 10:36 AM
> To: Beck Wolfgang (Nokia-MP/Brisbane)
> Cc: ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> On Tuesday 21 February 2012 06:28:38 ***@nokia.com wrote:
> > I'm preferring having QLog active only if a config file is there.
> > It doesn't make sense to me at all having an environment variable
> > that can activate QLog but not config file to activate the
> > categories. As long there is no config file QLog is disable and uses
> > less performance as possible but still having the feature that you
> > can activate it without recompiling the code.
>
> Why? IMHO things should go to stderr by default. So it makes perfect
> sense to see the output, even if one didn't configure output files in a config file.

I agree with that: On the desktop it's quite handy to see also detailed output on stderr/the shell (which one can redirect to a file if needed). But I also think that qLog() messages shouldn't show up by default for normal users, that is, unless the category has been explicitly enabled.

So how about adding another QtMsgType called QLogMsg, that qLog() uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages would not be processed by default, unless the configuration file (or an environment variable) says so ...

Kai

> I guess this is a mobile platform vs desktop platform discussion. On a
> mobile platform the logs are only useful if they go to a file, while
> on the desktop the logs are useful also if they go to stderr, to get
> them in a terminal or in the session log file.
>
>
> --
> David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
> KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84
> 08 53, Sweden (HQ) +46-563-540090 KDAB - Qt Experts -
> Platform-independent software solutions
>
> _______________________________________________
> Development mailing list
> ***@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
k***@nokia.com
2012-02-22 08:20:57 UTC
Permalink
> -----Original Message-----
> > So how about adding another QtMsgType called QLogMsg, that qLog()
> uses? In contrast to qDebug/QtDebugMsg, qLog/QtLogMsg messages would
> not be processed by default, unless the configuration file (or an environment
> variable) says so ...
>
> There is no need for this Kai.
> The macro will not even create a QMessageLogger if the category is not
> enabled.

True, my fault.

Kai
l***@nokia.com
2012-02-21 10:21:29 UTC
Permalink
On 21/02/2012, at 7:36 PM, ext David Faure wrote:

> On Tuesday 21 February 2012 06:28:38 ***@nokia.com wrote:
>> I'm preferring having QLog active only if a config file is there.
>> It doesn't make sense to me at all having an environment variable that can
>> activate QLog but not config file to activate the categories. As long there
>> is no config file QLog is disable and uses less performance as possible but
>> still having the feature that you can activate it without recompiling the
>> code.
>
> Why? IMHO things should go to stderr by default. So it makes perfect sense to
> see the output, even if one didn't configure output files in a config file.
>

The whole idea is to have noop by default. Nothing. Ziltch. Not even std err. Use qWarning if you want or need that. That's what it's for.
If you need this, only when you do a magical incantation, such as a config file or env var, will it produce any output.


> I guess this is a mobile platform vs desktop platform discussion. On a mobile
> platform the logs are only useful if they go to a file, while on the desktop
> the logs are useful also if they go to stderr, to get them in a terminal or in
> the session log file.
>

Not really. It's more of not wanting to have any performance hits in shipping code.
Even on embedded systems, developers want and need console output, and support services might need detailed log file at times.
qlog makes this possible. Nothing stopping anyone from doing a tail -f my.log



> --
> David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
> KDAB (France) S.A.S., a KDAB Group company
> Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
> KDAB - Qt Experts - Platform-independent software solutions
>
> _______________________________________________
> Development mailing list
> ***@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development

Lorn Potter
Senior Software Engineer, Core Enablers/QtSensors
David Faure
2012-02-21 10:28:56 UTC
Permalink
On Tuesday 21 February 2012 10:21:29 ***@nokia.com wrote:
> On 21/02/2012, at 7:36 PM, ext David Faure wrote:
> > On Tuesday 21 February 2012 06:28:38 ***@nokia.com wrote:
> >> I'm preferring having QLog active only if a config file is there.
> >> It doesn't make sense to me at all having an environment variable that
> >> can
> >> activate QLog but not config file to activate the categories. As long
> >> there
> >> is no config file QLog is disable and uses less performance as possible
> >> but
> >> still having the feature that you can activate it without recompiling the
> >> code.
> >
> > Why? IMHO things should go to stderr by default. So it makes perfect sense
> > to see the output, even if one didn't configure output files in a config
> > file.
> The whole idea is to have noop by default. Nothing. Ziltch. Not even std
> err. Use qWarning if you want or need that. That's what it's for. If you
> need this, only when you do a magical incantation, such as a config file or
> env var, will it produce any output.

I agree.
However my point was: once turned on, it could just go to stderr, and not
require configuration of an output file.

> > I guess this is a mobile platform vs desktop platform discussion. On a
> > mobile platform the logs are only useful if they go to a file, while on
> > the desktop the logs are useful also if they go to stderr, to get them in
> > a terminal or in the session log file.
>
> Not really. It's more of not wanting to have any performance hits in
> shipping code. Even on embedded systems, developers want and need console
> output, and support services might need detailed log file at times. qlog
> makes this possible. Nothing stopping anyone from doing a tail -f my.log

But there won't be a "my.log" configured by default, so the user needs to set
that up first.
I'm aiming at something that is simple to use for the simple case. When a user
comes on IRC with a bug and we want to see the output, it should be simple for
him/her to get that output. Finding the right config file and editing it by hand
isn't exactly simple. Well, OK, a GUI tool can fix that; maybe we can even make
that part of qtconfig. That would fix the issue nicely, in fact.

OK, so objections withdrawn.

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
l***@nokia.com
2012-02-21 10:47:18 UTC
Permalink
On 21/02/2012, at 8:28 PM, ext David Faure wrote:

> On Tuesday 21 February 2012 10:21:29 ***@nokia.com wrote:
>> On 21/02/2012, at 7:36 PM, ext David Faure wrote:
>>> On Tuesday 21 February 2012 06:28:38 ***@nokia.com wrote:
>>>> I'm preferring having QLog active only if a config file is there.
>>>> It doesn't make sense to me at all having an environment variable that
>>>> can
>>>> activate QLog but not config file to activate the categories. As long
>>>> there
>>>> is no config file QLog is disable and uses less performance as possible
>>>> but
>>>> still having the feature that you can activate it without recompiling the
>>>> code.
>>>
>>> Why? IMHO things should go to stderr by default. So it makes perfect sense
>>> to see the output, even if one didn't configure output files in a config
>>> file.
>> The whole idea is to have noop by default. Nothing. Ziltch. Not even std
>> err. Use qWarning if you want or need that. That's what it's for. If you
>> need this, only when you do a magical incantation, such as a config file or
>> env var, will it produce any output.
>
> I agree.
> However my point was: once turned on, it could just go to stderr, and not
> require configuration of an output file.

Not all systems even have easy stderr output *cough windows*. How are you going to retrieve that from an app installed in a sandbox on a clients system, when there is no access to a terminal ouput? If you want stderr, use qDebug or friends.
How are you going to configure what categories are being transmitted without a config file? A string list in an env var?


>
>>> I guess this is a mobile platform vs desktop platform discussion. On a
>>> mobile platform the logs are only useful if they go to a file, while on
>>> the desktop the logs are useful also if they go to stderr, to get them in
>>> a terminal or in the session log file.
>>
>> Not really. It's more of not wanting to have any performance hits in
>> shipping code. Even on embedded systems, developers want and need console
>> output, and support services might need detailed log file at times. qlog
>> makes this possible. Nothing stopping anyone from doing a tail -f my.log
>
> But there won't be a "my.log" configured by default, so the user needs to set
> that up first.

> I'm aiming at something that is simple to use for the simple case. When a user
> comes on IRC with a bug and we want to see the output, it should be simple for
> him/her to get that output. Finding the right config file and editing it by hand
> isn't exactly simple. Well, OK, a GUI tool can fix that; maybe we can even make
> that part of qtconfig. That would fix the issue nicely, in fact.

Who said anything about editing by hand? Simply have them install a preconfigured config file you give them.
Heck you can even do that at first install, so there is a log file, just in case.

:)

>
> OK, so objections withdrawn.
>
> --
> David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
> KDAB (France) S.A.S., a KDAB Group company
> Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
> KDAB - Qt Experts - Platform-independent software solutions
>

Lorn Potter
Senior Software Engineer, Core Enablers/QtSensors
David Faure
2012-02-21 10:55:05 UTC
Permalink
On Tuesday 21 February 2012 10:47:18 ***@nokia.com wrote:
> On 21/02/2012, at 8:28 PM, ext David Faure wrote:
> > On Tuesday 21 February 2012 10:21:29 ***@nokia.com wrote:
> >> On 21/02/2012, at 7:36 PM, ext David Faure wrote:
> >>> On Tuesday 21 February 2012 06:28:38 ***@nokia.com wrote:
> >>>> I'm preferring having QLog active only if a config file is there.
> >>>> It doesn't make sense to me at all having an environment variable that
> >>>> can
> >>>> activate QLog but not config file to activate the categories. As long
> >>>> there
> >>>> is no config file QLog is disable and uses less performance as possible
> >>>> but
> >>>> still having the feature that you can activate it without recompiling
> >>>> the
> >>>> code.
> >>>
> >>> Why? IMHO things should go to stderr by default. So it makes perfect
> >>> sense
> >>> to see the output, even if one didn't configure output files in a config
> >>> file.
> >>
> >> The whole idea is to have noop by default. Nothing. Ziltch. Not even std
> >> err. Use qWarning if you want or need that. That's what it's for. If you
> >> need this, only when you do a magical incantation, such as a config file
> >> or
> >> env var, will it produce any output.
> >
> > I agree.
> > However my point was: once turned on, it could just go to stderr, and not
> > require configuration of an output file.
>
> Not all systems even have easy stderr output *cough windows*. How are you
> going to retrieve that from an app installed in a sandbox on a clients
> system, when there is no access to a terminal ouput? If you want stderr,
> use qDebug or friends.

You keep assuming that the developer is working on ONE application, and has
full control over everything. This isn't how it works, in particular in KDE
and other opensource Qt apps.
The developer uses qDebug or qLog because that suits him/her, the user ends up
on a completely different OS, with different needs....

If there is no access to terminal output (well there's always DebugView.exe
too...), then the user can set up files, this doesn't change anything compared
to your initial idea.

> How are you going to configure what categories are
> being transmitted without a config file? A string list in an env var?

Some logging frameworks actually do that, I think. (libACE, iirc?)

But OK, I'm withdrawing the whole point - a GUI will do the job just fine, as
long as the qLog config file *does* allow the output for a given to go to
stderr, not only to files.

> Who said anything about editing by hand? Simply have them install a
> preconfigured config file you give them.

Which still requires finding out where the config file must go, on the user's
system. But OK, no better solution anyway, and the GUI app can find out
automatically.

> Heck you can even do that at first
> install, so there is a log file, just in case.

Again, with "first install" you assume pre-built binaries and an installer.
Not the case when you download the sources for a random Qt application from
sourceforge, or when you "apt-get install" or equivalent.
I keep seeing this mindset of "one big commercial application" on this list,
but Qt developers have to realize that there's also the opensource application
use case, as well as the "Qt-based framework" use case (where changing the
defaults for logging, or installing config files, is definitely not wanted).

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
k***@nokia.com
2012-02-21 11:19:06 UTC
Permalink
> -----Original Message-----
> From: development-bounces+kai.koehne=***@qt-project.org
> [mailto:development-bounces+kai.koehne=***@qt-project.org] On
> Behalf Of Potter Lorn (Nokia-MP/Brisbane)
> Sent: Tuesday, February 21, 2012 11:47 AM
> To: ***@kdab.com
> Cc: ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
>
> On 21/02/2012, at 8:28 PM, ext David Faure wrote:
>
> > On Tuesday 21 February 2012 10:21:29 ***@nokia.com wrote:
> >> On 21/02/2012, at 7:36 PM, ext David Faure wrote:
> >>> On Tuesday 21 February 2012 06:28:38 ***@nokia.com wrote:
> >>>> I'm preferring having QLog active only if a config file is there.
> >>>> It doesn't make sense to me at all having an environment variable
> >>>> that can activate QLog but not config file to activate the
> >>>> categories. As long there is no config file QLog is disable and
> >>>> uses less performance as possible but still having the feature that
> >>>> you can activate it without recompiling the code.
> >>>
> >>> Why? IMHO things should go to stderr by default. So it makes perfect
> >>> sense to see the output, even if one didn't configure output files
> >>> in a config file.
> >> The whole idea is to have noop by default. Nothing. Ziltch. Not even
> >> std err. Use qWarning if you want or need that. That's what it's for.
> >> If you need this, only when you do a magical incantation, such as a
> >> config file or env var, will it produce any output.
> >
> > I agree.
> > However my point was: once turned on, it could just go to stderr, and
> > not require configuration of an output file.
>
> Not all systems even have easy stderr output *cough windows*.

It has the debugger buffer. Admittedly it has its problems, but it's the standard for IDE's to get output. If you just log to a file, you'll never see your qLog statements in your IDE (unless you hack special support for it to catch the log file or something similar).

> How are
> you going to retrieve that from an app installed in a sandbox on a clients
> system, when there is no access to a terminal ouput?

You can always specify a file in this case. Logging to a file is sometimes needed, the question is whether it should be the only way to get the data.

> If you want stderr, use
> qDebug or friends.

So I've to tell the customer to get me the qLog file (for qLog warnings), and in addition the console output (for qWarning, qFatal etc)? And then try to match between those to understand what's going on? Or make sure that every qWarning in addition has a qLog ? Doesn't sound appealing to me either ...

> How are you going to configure what categories are being transmitted
> without a config file? A string list in an env var?

Why not?

export QT_LOG_CATEGORY="QtCore.IO" isn't that scary, is it? And even if it is more elaborous, you could still have the config file, but not specifying a log file ...

Regards

Kai
>
> >
> >>> I guess this is a mobile platform vs desktop platform discussion. On
> >>> a mobile platform the logs are only useful if they go to a file,
> >>> while on the desktop the logs are useful also if they go to stderr,
> >>> to get them in a terminal or in the session log file.
> >>
> >> Not really. It's more of not wanting to have any performance hits in
> >> shipping code. Even on embedded systems, developers want and need
> >> console output, and support services might need detailed log file at
> >> times. qlog makes this possible. Nothing stopping anyone from doing a
> >> tail -f my.log
> >
> > But there won't be a "my.log" configured by default, so the user needs
> > to set that up first.
>
> > I'm aiming at something that is simple to use for the simple case.
> > When a user comes on IRC with a bug and we want to see the output, it
> > should be simple for him/her to get that output. Finding the right
> > config file and editing it by hand isn't exactly simple. Well, OK, a
> > GUI tool can fix that; maybe we can even make that part of qtconfig. That
> would fix the issue nicely, in fact.
>
> Who said anything about editing by hand? Simply have them install a
> preconfigured config file you give them.
> Heck you can even do that at first install, so there is a log file, just in case.
>
> :)
>
> >
> > OK, so objections withdrawn.
> >
> > --
> > David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
> > KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84
> > 08 53, Sweden (HQ) +46-563-540090 KDAB - Qt Experts -
> > Platform-independent software solutions
> >
>
> Lorn Potter
> Senior Software Engineer, Core Enablers/QtSensors
>
>
>
>
>
> _______________________________________________
> Development mailing list
> ***@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
w***@nokia.com
2012-02-22 00:21:41 UTC
Permalink
QLOG ENABLED

I guess you misunderstood me.
QLog is enabled ONLY if a config file was found.
We have 3 ways to define the config file:
1. Default using application name configuration default path and organization name for the path
2. Application developer can call the QLog function "setDefaultConfigFile
3. Config file is defined in the environmane variable "QLOG_CONFIG_FILE".
This logic was discussed in the mailing list.
Please have a look at http://codereview.qt-project.org/#change,13226
QLogPrivate constructor in qlog.cpp.

To be crystal clear:

QLog | QLog
Enabeld | Config File
--------------------------
NO | no file defined
NO | no file found
YES | file found


QLOG WIRTES INTO OUTPUT FILE OR STDERR

If you don't specify "OutputFile" in the QLog config file or the environment variable "QLOG_CONFIG_FILE" the output will be stderr (default).
ONLY if you specify the "OutputFile" key file or the environment variable "QLOG_CONFIG_FILE" QLog will write into that file.
We assume for the next table that QLog is enabled.

QLog | QLog | QLog Config |
Writes Into output file | Writes into stderr | OutputFile defined |
---------------------------------------------------------------------------------
No | Yes | No |
Yes | No | Yes |

Hope that makes it clear now.
Seems that QLog code is a little hard to read so I will add a lots of commends in there :).

Cheers,
WB





-----Original Message-----
From: ext David Faure [mailto:***@kdab.com]
Sent: Tuesday, February 21, 2012 7:36 PM
To: Beck Wolfgang (Nokia-MP/Brisbane)
Cc: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On Tuesday 21 February 2012 06:28:38 ***@nokia.com wrote:
> I'm preferring having QLog active only if a config file is there.
> It doesn't make sense to me at all having an environment variable that
> can activate QLog but not config file to activate the categories. As
> long there is no config file QLog is disable and uses less performance
> as possible but still having the feature that you can activate it
> without recompiling the code.

Why? IMHO things should go to stderr by default. So it makes perfect sense to see the output, even if one didn't configure output files in a config file.

I guess this is a mobile platform vs desktop platform discussion. On a mobile platform the logs are only useful if they go to a file, while on the desktop the logs are useful also if they go to stderr, to get them in a terminal or in the session log file.


--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-independent software solutions
w***@nokia.com
2012-02-16 23:39:31 UTC
Permalink
Already done.

I'm using
if (!global_enabled()) /*NOP*/; else QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug

Anyway I will make sure that qlog still works even with -DQT_NO_WARNING_OUTPUT

Cheers,
WB

-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext David Faure
Sent: Friday, February 17, 2012 1:02 AM
To: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On Friday 10 February 2012 09:25:05 Lincoln Ramsay wrote:
> The only way to avoid some_expensive_function() is to not execute that
> code path at all. Thus the macro expansion:
>
> if (do_nothing) /*NOP*/; else qDebug() << some_expensive_function();

I think this is missing the point that qDebug() itself is a macro already (now, in qt5).

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

So why not *change* the qDebug macro to something like

if (!global_enabled()) /*NOP*/; else QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug

and the function/macro that takes categories can add the check for categories in addition.

The goal: that global_enabled() affects *all* qDebug statements, not only those with a category, leading to better integration, rather than to two competing frameworks inside QtCore itself (try to explain to a new developer, the reason why the global switch to disable debug output only works when a category is specified...). The only reason is "well, I didn't dare to touch qDebug itself"?
I think it's the right time to touch it :-)

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
w***@nokia.com
2012-02-17 01:23:21 UTC
Permalink
Dammit,
copied the wrong stuff.

I mean I'm using:

#define qLog(category) \
if (!QLog::instance()->isEnabled() || !QLog::instance()->isEnabled(#category, QLogCategories::category##_QLog_enabled)) /*NOP*/; \
else QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, #category).debug()


Cheers,
WB

________________________________________
From: Beck Wolfgang (Nokia-MP/Brisbane)
Sent: Friday, 17 February 2012 9:39 AM
To: ext David Faure; ***@qt-project.org
Subject: RE: [Development] QLog ( Work on qDebug and friends)

Already done.

I'm using
if (!global_enabled()) /*NOP*/; else QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug

Anyway I will make sure that qlog still works even with -DQT_NO_WARNING_OUTPUT

Cheers,
WB

-----Original Message-----
From: development-bounces+wolfgang.beck=***@qt-project.org [mailto:development-bounces+wolfgang.beck=***@qt-project.org] On Behalf Of ext David Faure
Sent: Friday, February 17, 2012 1:02 AM
To: ***@qt-project.org
Subject: Re: [Development] QLog ( Work on qDebug and friends)

On Friday 10 February 2012 09:25:05 Lincoln Ramsay wrote:
> The only way to avoid some_expensive_function() is to not execute that
> code path at all. Thus the macro expansion:
>
> if (do_nothing) /*NOP*/; else qDebug() << some_expensive_function();

I think this is missing the point that qDebug() itself is a macro already (now, in qt5).

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

So why not *change* the qDebug macro to something like

if (!global_enabled()) /*NOP*/; else QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug

and the function/macro that takes categories can add the check for categories in addition.

The goal: that global_enabled() affects *all* qDebug statements, not only those with a category, leading to better integration, rather than to two competing frameworks inside QtCore itself (try to explain to a new developer, the reason why the global switch to disable debug output only works when a category is specified...). The only reason is "well, I didn't dare to touch qDebug itself"?
I think it's the right time to touch it :-)

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
w***@nokia.com
2012-02-09 23:44:39 UTC
Permalink
Hi Kai,

The controlling of the category will be done using a configuration file.
QLog contains a private class that creates a file watcher for the configuration file.
So not only if you start the application but during runtime as well the category filtering can be changed dynamically by changing the config file.
No recompiling needed with this solution.

Cheers,
WB


-----Original Message-----
From: Koehne Kai (Nokia-MP/Berlin)
Sent: Thursday, February 09, 2012 7:05 PM
To: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
Subject: RE: QLog ( Work on qDebug and friends)

> -----Original Message-----
> From: Beck Wolfgang (Nokia-MP/Brisbane)
> Sent: Thursday, February 09, 2012 8:11 AM
> To: Koehne Kai (Nokia-MP/Berlin); ***@qt-project.org
> Subject: RE: QLog ( Work on qDebug and friends)
>
> Hi Kai,


Hi Wolfgang,

> I think this was a very good idea so I've tried it but I've run into
> one important problem.
> If I use this trick I have to call the overloaded function in QMessageLogger:
> e.g.
> 1. void debug(QMessageCategory category, const char *format, ...); and 2.
> QDebug debug(QMessageCategory category);
>
> The first function is ok but the 2. one needs to return a QDebug object.
> In this case I have to do a lots of overhead e.g. function call and
> creating object after I can check if the category should be logged or not.
>
> So better having a other named macro which I can do
>
> #define qLog(category) \
> If(!logging_enable); \
> Else QMessageCategory(....).debug()

I see. You'll indeed need something like that if you want to define which category to log or not with the help of the macro expander.

You might still get half-way there performance wise though by giving QDebug a boolean "active", and check for it in the various operator<<, e.g.

inline QDebug &operator<<(qint64 t) { if (!active) return *this; stream->ts << QString::number(t); return maybeSpace(); }

If everything is inlined, and the various overloads of operator<< that people can implement do the check too, this should mostly come down to just in a couple of if (false) ... being executed.

Anyhow, a more basic question I have is whether we want the filtering by category be done at runtime (e.g. in a central message handler), or at compile time (like your solution seems to be based on). Maybe there's place for both, but I thought the idea for the Qt libraries was to avoid the need for recompiles ...

Regards

Kai Koehne

> Cheers,
> WB
>
>
> -----Original Message-----
> From: Koehne Kai (Nokia-MP/Berlin)
> Sent: Tuesday, February 07, 2012 5:27 PM
> To: Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
> Subject: RE: QLog ( Work on qDebug and friends)
>
> Hi Wolfgang,
>
> how about making the category a distinct type instead?
>
> struct QMessageCategory {
> explicit QMessageCategory(const char *name); };
>
> class QMessageLogger {
> void debug(const char *format, ...);
> void debug(QMessageCategory category, const char *format, ...); }
>
>
> ...
> QDebugCategory debugCategory("MyApp"); // You'll typically do this in
> one place ...
> qDebug(debugCategory, "hi there");
>
>
> Anyhow, you probably don't want to set the category explicitly for
> every call in e.g. QtCore, so you can also pass it implicitly via a DEFINE:
>
> class QMessageLogger {
> QMessageLogger(const char *file, int line, const char *function,
> const char
> *defaultCategory) {
> }
> }
>
> #define Q_DEBUG_CATEGORY "" // empty default #define qDebug
> QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO,
> Q_DEBUG_CATEGORY).debug
>
>
> And QtCore is then compiled with
> DEFINES+="Q_DEBUG_CATEGORY=QtCore". IMO both approaches are
> complementary, passing an explicit category would overwrite the
> Q_DEBUG_CATEGORY define.
>
> Regards
>
> Kai
>
> ________________________________________
> From: development-bounces+kai.koehne=***@qt-project.org
> [development-bounces+kai.koehne=***@qt-project.org] on behalf of
> Beck Wolfgang (Nokia-MP/Brisbane)
> Sent: Tuesday, February 07, 2012 7:54 AM
> To: ***@qt-project.org
> Subject: [Development] QLog ( Work on qDebug and friends)
>
> I'm working to integrade category log with QMessageLogger & Co and
> unfortunatelly we can not use
> qDebg(<category>) << "my message" because there is already a
> debug(const char *msg, ...) function combining with the macro #define
> qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug.
>
> So I use a new function and macro:
> QDebug debug();
> QDebug debugCategory(const char *msg);
> QDebug warning();
> QDebug warningCategory(const char *msg);
> QDebug critical();
> QDebug criticalCategory(const char *msg);
> QDebug fatalCategory(const char *msg);
>
> #define qDebugCat(category) QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).debugCategory(#category)
> #define qWarningCat(category) QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).warningCategory(#category)
> #define qCriticalCat(category) QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).criticalCategory(#category)
> #define qFatalCat(category) QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).fatalCategory(#category)
>
> Any problems with this naming conventions???
>
> Cheers,
> WB
>
> _______________________________________________
> Development mailing list
> ***@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
BRM
2012-02-10 14:33:46 UTC
Permalink
> From: "***@nokia.com" <***@nokia.com>
> The controlling of the category will be done using a configuration file.
> QLog contains a private class that creates a file watcher for the configuration
> file.
> So not only if you start the application but during runtime as well the category
> filtering can be changed dynamically by changing the config file.
> No recompiling needed with this solution.

+1.

This is a far better solution, IMHO, than the macro expansion.

FYI - I support a system that operates at up to 400 samples/second with extensive logging to a modular logging system - syslog, files, EventLog, etc.
It doesn't seem to impact performance at all, so I don't see the issue with having Qt be able to filter at run-time either as Wolfgang specifies above.

Ben
k***@nokia.com
2012-02-10 15:44:10 UTC
Permalink
> -----Original Message-----
> From: ext BRM [mailto:***@yahoo.com]
> Sent: Friday, February 10, 2012 3:34 PM
> To: Beck Wolfgang (Nokia-MP/Brisbane); Koehne Kai (Nokia-MP/Berlin);
> ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> > From: "***@nokia.com" <***@nokia.com> The
> > controlling of the category will be done using a configuration file.
> > QLog contains a private class that creates a file watcher for the
> > configuration file.
> > So not only if you start the application but during runtime as well
> > the category filtering can be changed dynamically by changing the config
> file.
> > No recompiling needed with this solution.
>
> +1.
>
> This is a far better solution, IMHO, than the macro expansion.

Well, I think Lincoln and Wolfgang are voting for the filtering combined with a qLog() macro ...

Personally, I'm biased. It's certainly nice that

qLog("MyCategory") << expensiveOperation();

becomes almost a NOOP if logs for MyCategory aren't kept. However, adding yet another 'keyword' to the framework has a price, especially since the difference between 'qDebug(QMessageLogContext("MyCategory"))' << and a 'qLog("MyCategory") << ' is subtle.

But then again I'm not the person who can approve such a change in the first place :) So this is just my 2 cents here.

> FYI - I support a system that operates at up to 400 samples/second with
> extensive logging to a modular logging system - syslog, files, EventLog, etc.
> It doesn't seem to impact performance at all, so I don't see the issue with
> having Qt be able to filter at run-time either as Wolfgang specifies above.

Agreed, especially if you're not overdoing it with logging (which you shouldn't do in the libraries anyway).

> Ben

Regards

Kai
k***@nokia.com
2012-02-10 19:04:16 UTC
Permalink
>> -----Original Message-----
>> From: ext BRM [mailto:***@yahoo.com]
>> Sent: Friday, February 10, 2012 3:34 PM
>> To: Beck Wolfgang (Nokia-MP/Brisbane); Koehne Kai (Nokia-MP/Berlin);
>> ***@qt-project.org
>> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>>
>> > From: "***@nokia.com" <***@nokia.com> The
>> > controlling of the category will be done using a configuration file.
>> > QLog contains a private class that creates a file watcher for the
>> > configuration file.
>> > So not only if you start the application but during runtime as well
>> > the category filtering can be changed dynamically by changing the config
>> file.
>> > No recompiling needed with this solution.
>>
>> +1.
>>
>> This is a far better solution, IMHO, than the macro expansion.
>
> Well, I think Lincoln and Wolfgang are voting for the filtering combined with a qLog() macro ...
>
> Personally, I'm biased. It's certainly nice that ...

Actually I wanted to say that I'm unsure, not necessarily that I'm biased ;) Sometimes I'd really would like to recall e-mails ...

A nice weekend to everyone,

Kai
w***@nokia.com
2012-02-13 00:17:56 UTC
Permalink
Well I think I can change the macro name very easy but we can't name it qDebug.
So maybe qDebugCat or somethink like this.
But I think the macro is very necessary special if you develop for devices they don't have the capacity of a desktop machine.

Cheers,
WB




-----Original Message-----
From: Koehne Kai (Nokia-MP/Berlin)
Sent: Saturday, February 11, 2012 1:44 AM
To: BRM; Beck Wolfgang (Nokia-MP/Brisbane); ***@qt-project.org
Subject: RE: [Development] QLog ( Work on qDebug and friends)

> -----Original Message-----
> From: ext BRM [mailto:***@yahoo.com]
> Sent: Friday, February 10, 2012 3:34 PM
> To: Beck Wolfgang (Nokia-MP/Brisbane); Koehne Kai (Nokia-MP/Berlin);
> ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> > From: "***@nokia.com" <***@nokia.com> The
> > controlling of the category will be done using a configuration file.
> > QLog contains a private class that creates a file watcher for the
> > configuration file.
> > So not only if you start the application but during runtime as well
> > the category filtering can be changed dynamically by changing the
> > config
> file.
> > No recompiling needed with this solution.
>
> +1.
>
> This is a far better solution, IMHO, than the macro expansion.

Well, I think Lincoln and Wolfgang are voting for the filtering combined with a qLog() macro ...

Personally, I'm biased. It's certainly nice that

qLog("MyCategory") << expensiveOperation();

becomes almost a NOOP if logs for MyCategory aren't kept. However, adding yet another 'keyword' to the framework has a price, especially since the difference between 'qDebug(QMessageLogContext("MyCategory"))' << and a 'qLog("MyCategory") << ' is subtle.

But then again I'm not the person who can approve such a change in the first place :) So this is just my 2 cents here.

> FYI - I support a system that operates at up to 400 samples/second
> with extensive logging to a modular logging system - syslog, files, EventLog, etc.
> It doesn't seem to impact performance at all, so I don't see the issue
> with having Qt be able to filter at run-time either as Wolfgang specifies above.

Agreed, especially if you're not overdoing it with logging (which you shouldn't do in the libraries anyway).

> Ben

Regards

Kai
Lincoln Ramsay
2012-02-13 00:33:11 UTC
Permalink
On 02/11/2012 01:44 AM, ext ***@nokia.com wrote:
> However, adding yet another 'keyword' to the framework has a price,
> especially since the difference between
> 'qDebug(QMessageLogContext("MyCategory"))'<< and a
> 'qLog("MyCategory")<< ' is subtle.

We tried that but while this difference is subtle to the eye, it's a
huge difference to the implementation.

qDebug is currently an argument-less macro that expands to the name of a
function. Before message logging it was just a plain old function.
Overloading means that qDebug("message") and qDebug() << "message" both
work.

Since we can't have a macro func with 0, 1 or many arguments, we can
only add a new overload for qDebug(category) << "message" but if we do
this, there is nowhere to put the "do nothing quickly" logic.

Expanding to this is always going to be slow:
func(category) << "args" << expensive();

We need to expand to this to be fast:
if (do_nothing) /*NOP*/; else func(category) << "args" << expensive();

Thus we cannot overload qDebug.

qLog is just a name. It's the name this code had when it was in Qtopia
but it's hardly important if it keeps this name. It would be nice to
focus on the implementation of the feature to make sure it is sound
before we worry overly much about what to call it :)

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
k***@nokia.com
2012-02-14 10:22:16 UTC
Permalink
--
Kai Koehne
Senior Software Engineer
Nokia, Mobile Phones
 
Nokia gate5 GmbH
Firmensitz: Invalidenstr. 117, 10115 Berlin, Germany
Registergericht: Amtsgericht Charlottenburg, Berlin: HRB 106443 B
Umsatzsteueridentifikationsnummer: DE 812 845 193
Geschäftsführer: Dr. Michael Halbherr, Karim Tähtivuori


> -----Original Message-----
> From: development-bounces+kai.koehne=***@qt-project.org
> [mailto:development-bounces+kai.koehne=***@qt-project.org] On
> Behalf Of Ramsay Lincoln (Nokia-MP/Brisbane)
> Sent: Monday, February 13, 2012 1:33 AM
> To: ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> On 02/11/2012 01:44 AM, ext ***@nokia.com wrote:
> > However, adding yet another 'keyword' to the framework has a price,
> > especially since the difference between
> > 'qDebug(QMessageLogContext("MyCategory"))'<< and a
> > 'qLog("MyCategory")<< ' is subtle.
>
> We tried that but while this difference is subtle to the eye, it's a
> huge difference to the implementation.
>
> qDebug is currently an argument-less macro that expands to the name of a
> function. Before message logging it was just a plain old function.
> Overloading means that qDebug("message") and qDebug() << "message"
> both
> work.
>
> Since we can't have a macro func with 0, 1 or many arguments, we can
> only add a new overload for qDebug(category) << "message" but if we do
> this, there is nowhere to put the "do nothing quickly" logic.


Just wanted to point out that there are variadic macros: http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

#define qCategoryDebug(category, ...) if (isLogEnabled(category)) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug(__VA_ARGS__)

Seems to work with at least gcc4.2.1 and Visual studio 2010.

But that doesn't help with the fact that we can't differentiate between 'qDebug()', 'qDebug("Hello world")', and 'qDebug(MyCategory)' on the macro level.

> Expanding to this is always going to be slow:
> func(category) << "args" << expensive();
>
> We need to expand to this to be fast:
> if (do_nothing) /*NOP*/; else func(category) << "args" << expensive();
>
> Thus we cannot overload qDebug.
>
> qLog is just a name. It's the name this code had when it was in Qtopia
> but it's hardly important if it keeps this name. It would be nice to
> focus on the implementation of the feature to make sure it is sound
> before we worry overly much about what to call it :)

Sure, but names still matter for a public API .

Here's another idea:


// in qlogging.h
void qMessageLogEnabled(const char *area)
#define QMessageArea(area) if (qMessageLogEnabled(area)) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, area)


Usage would be e.g.

QMessageArea("MyArea").debug() << expensiveFunc();
QMessageArea("MyArea").warning("%s", expensiveFunc());

Regards

Kai

> --
> Lincoln Ramsay - Senior Software Engineer
> Qt Development Frameworks, Nokia - http://qt.nokia.com/
> _______________________________________________
> Development mailing list
> ***@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
BRM
2012-02-14 14:00:29 UTC
Permalink
----- Original Message -----

> From: "***@nokia.com" <***@nokia.com>
>> -----Original Message-----
>> From: development-bounces+kai.koehne=***@qt-project.org
>> [mailto:development-bounces+kai.koehne=***@qt-project.org] On
>> Behalf Of Ramsay Lincoln (Nokia-MP/Brisbane)
>> Sent: Monday, February 13, 2012 1:33 AM
>> To: ***@qt-project.org
>> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>>
>> On 02/11/2012 01:44 AM, ext ***@nokia.com wrote:
>> > However, adding yet another 'keyword' to the framework has a
> price,
>> > especially since the difference between
>> > 'qDebug(QMessageLogContext("MyCategory"))'<<
> and a
>> > 'qLog("MyCategory")<< ' is subtle.
>>
>> We tried that but while this difference is subtle to the eye, it's a
>> huge difference to the implementation.
>>
>> qDebug is currently an argument-less macro that expands to the name of a
>> function. Before message logging it was just a plain old function.
>> Overloading means that qDebug("message") and qDebug() <<
> "message"
>> both
>> work.
>>
>> Since we can't have a macro func with 0, 1 or many arguments, we can
>> only add a new overload for qDebug(category) << "message"
> but if we do
>> this, there is nowhere to put the "do nothing quickly" logic.
>
>
> Just wanted to point out that there are variadic macros:
> http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
>
> #define qCategoryDebug(category, ...) if (isLogEnabled(category))
> QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug(__VA_ARGS__)
>
> Seems to work with at least gcc4.2.1 and Visual studio 2010.
>
> But that doesn't help with the fact that we can't differentiate between
> 'qDebug()', 'qDebug("Hello world")', and
> 'qDebug(MyCategory)' on the macro level.


That depends on implementation. It does allow you take all those args and pass them over to other function easily.
And if all categories have to be registered, then you can add a check against the registration for it:

..
qLogRegisterCategory("my category");
...
qDebug("my category",...");
...
qDebug(...);
...

#define qDebug(category,...) \
    if (qLogIsCategory(category))    \
        if (qIsLogEnabled(category))   \
            QMessageLogger(__FILE,__LINE__, Q_FUNC_INFO, category).debug(__VAR__ARGS__)    \
        else {} \
    else QMessageLogger(__FILE,__LINE__, Q_FUNC_INFO).debug(category,##__VAR__ARGS__)

Ben
k***@nokia.com
2012-02-14 14:31:59 UTC
Permalink
> -----Original Message-----
> From: development-bounces+kai.koehne=***@qt-project.org
> [mailto:development-bounces+kai.koehne=***@qt-project.org] On
> Behalf Of ext BRM
> Sent: Tuesday, February 14, 2012 3:00 PM
> To: ***@qt-project.org
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> ----- Original Message -----
>
> > From: "***@nokia.com" <***@nokia.com>
> >> -----Original Message-----
> >> From: development-bounces+kai.koehne=***@qt-project.org
> >> [mailto:development-bounces+kai.koehne=***@qt-project.org]
> On
> >> Behalf Of Ramsay Lincoln (Nokia-MP/Brisbane)
> >> Sent: Monday, February 13, 2012 1:33 AM
> >> To: ***@qt-project.org
> >> Subject: Re: [Development] QLog ( Work on qDebug and friends)
> >>
> >> On 02/11/2012 01:44 AM, ext ***@nokia.com wrote:
> >> > However, adding yet another 'keyword' to the framework has a
> > price,
> >> > especially since the difference between >
> >> 'qDebug(QMessageLogContext("MyCategory"))'<<
> > and a
> >> > 'qLog("MyCategory")<< ' is subtle.
> >>
> >> We tried that but while this difference is subtle to the eye, it's a
> >> huge difference to the implementation.
> >>
> >> qDebug is currently an argument-less macro that expands to the name
> >> of a function. Before message logging it was just a plain old function.
> >> Overloading means that qDebug("message") and qDebug() <<
> > "message"
> >> both
> >> work.
> >>
> >> Since we can't have a macro func with 0, 1 or many arguments, we can
> >> only add a new overload for qDebug(category) << "message"
> > but if we do
> >> this, there is nowhere to put the "do nothing quickly" logic.
> >
> >
> > Just wanted to point out that there are variadic macros:
> > http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
> >
> > #define qCategoryDebug(category, ...) if (isLogEnabled(category))
> > QMessageLogger(__FILE__, __LINE__,
> Q_FUNC_INFO).debug(__VA_ARGS__)
> >
> > Seems to work with at least gcc4.2.1 and Visual studio 2010.
> >
> > But that doesn't help with the fact that we can't differentiate
> > between 'qDebug()', 'qDebug("Hello world")', and 'qDebug(MyCategory)'
> > on the macro level.
>
>
> That depends on implementation. It does allow you take all those args and
> pass them over to other function easily.
> And if all categories have to be registered, then you can add a check against
> the registration for it:
>
> ..
> qLogRegisterCategory("my category");
> ...
> qDebug("my category",...");
> ...
> qDebug(...);
> ...
>
> #define qDebug(category,...) \
>     if (qLogIsCategory(category))    \
>         if (qIsLogEnabled(category))   \
>             QMessageLogger(__FILE,__LINE__, Q_FUNC_INFO,
> category).debug(__VAR__ARGS__)    \
>         else {} \
>     else QMessageLogger(__FILE,__LINE__,
> Q_FUNC_INFO).debug(category,##__VAR__ARGS__)

Nice, though it'll break with

qDebug() << "Hi there";

"too few arguments to function bool qLogIsCategory(const char*)"

Also this won't work:

qDebug("category") << "HI there";

"expected primary expression before the '<<' token.

:(

Regards

Kai
BRM
2012-02-14 15:47:35 UTC
Permalink
> From: "***@nokia.com" <***@nokia.com>
> To: ***@yahoo.com; ***@qt-project.org
> Cc:
> Sent: Tuesday, February 14, 2012 9:31 AM
> Subject: RE: [Development] QLog ( Work on qDebug and friends)
>
>> -----Original Message-----
>> From: development-bounces+kai.koehne=***@qt-project.org
>> [mailto:development-bounces+kai.koehne=***@qt-project.org] On
>> Behalf Of ext BRM
>> Sent: Tuesday, February 14, 2012 3:00 PM
>> To: ***@qt-project.org
>> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>>
>> ----- Original Message -----
>>
>> > From: "***@nokia.com" <***@nokia.com>
>> >>  -----Original Message-----
>> >>  From: development-bounces+kai.koehne=***@qt-project.org
>> >>  [mailto:development-bounces+kai.koehne=***@qt-project.org]
>> On
>> >> Behalf Of Ramsay Lincoln (Nokia-MP/Brisbane)
>> >>  Sent: Monday, February 13, 2012 1:33 AM
>> >>  To: ***@qt-project.org
>> >>  Subject: Re: [Development] QLog ( Work on qDebug and friends)
>> >>
>> >>  On 02/11/2012 01:44 AM, ext ***@nokia.com wrote:
>> >>  > However, adding yet another 'keyword' to the
> framework has a
>> > price,
>> >>  > especially since the difference between  >
>> >>
> 'qDebug(QMessageLogContext("MyCategory"))'<<
>> > and a
>> >>  > 'qLog("MyCategory")<< ' is subtle.
>> >>
>> >>  We tried that but while this difference is subtle to the eye,
> it's a
>> >> huge difference to the implementation.
>> >>
>> >>  qDebug is currently an argument-less macro that expands to the
> name
>> >> of a  function. Before message logging it was just a plain old
> function.
>> >>  Overloading means that qDebug("message") and qDebug()
> <<
>> > "message"
>> >>  both
>> >>  work.
>> >>
>> >>  Since we can't have a macro func with 0, 1 or many arguments,
> we can
>> >> only add a new overload for qDebug(category) <<
> "message"
>> > but if we do
>> >>  this, there is nowhere to put the "do nothing quickly"
> logic.
>> >
>> >
>> > Just wanted to point out that there are variadic macros:
>> > http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
>> >
>> > #define qCategoryDebug(category, ...) if (isLogEnabled(category))
>> > QMessageLogger(__FILE__, __LINE__,
>> Q_FUNC_INFO).debug(__VA_ARGS__)
>> >
>> > Seems to work with at least gcc4.2.1 and Visual studio 2010.
>> >
>> > But that doesn't help with the fact that we can't
> differentiate
>> > between 'qDebug()', 'qDebug("Hello world")',
> and 'qDebug(MyCategory)'
>> > on the macro level.
>>
>>
>> That depends on implementation. It does allow you take all those args and
>> pass them over to other function easily.
>> And if all categories have to be registered, then you can add a check
> against
>> the registration for it:
>>
>> ..
>> qLogRegisterCategory("my category");
>> ...
>> qDebug("my category",...");
>> ...
>> qDebug(...);
>> ...
>>
>> #define qDebug(category,...) \
>>     if (qLogIsCategory(category))    \
>>         if (qIsLogEnabled(category))   \
>>             QMessageLogger(__FILE,__LINE__, Q_FUNC_INFO,
>> category).debug(__VAR__ARGS__)    \
>>         else {} \
>>     else QMessageLogger(__FILE,__LINE__,
>> Q_FUNC_INFO).debug(category,##__VAR__ARGS__)
>
> Nice, though it'll break with
>
> qDebug() << "Hi there";
>
> "too few arguments to function bool qLogIsCategory(const char*)"

Except the "Hi there" will be the 'category' part, so it'll be passed to qLogIsCategory(), which should return false and then cause the last else to be followed.

> Also this won't work:
>
> qDebug("category") << "HI there";
>
> "expected primary expression before the '<<' token.

Personally, I'd advocate against that any how. I'd much rather see a Category object being pushed via operator<<() instead so that it can be detected and allow things like:

// assume QMessageLoggerCategory(category) is a class
qDebug() << QMessageLoggerCategory("category1") << "message for category1" << QMessageLoggerCategory("category2") << "message for category2";

But that's me.
Lincoln Ramsay
2012-02-15 01:05:37 UTC
Permalink
On 02/15/2012 01:47 AM, ext BRM wrote:
> I'd much rather see a Category object being pushed via operator<<()
> instead so that it can be detected and allow things like:
>
> // assume QMessageLoggerCategory(category) is a class
> qDebug() << QMessageLoggerCategory("category1")<< "message for
> category1"<< QMessageLoggerCategory("category2")<< "message for
> category2";

This fails the "do nothing quickly" test so the cost of leaving such
statements in shipping code is high, even when the categories are disabled.

This works fine though.

qLog(category1) << "message for category1";
qLog(category2) << "message for category2";


--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
BRM
2012-02-15 16:14:12 UTC
Permalink
> From: Lincoln Ramsay <***@nokia.com>
> To: ***@qt-project.org
> Cc:
> Sent: Tuesday, February 14, 2012 8:05 PM
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> On 02/15/2012 01:47 AM, ext BRM wrote:
>> I'd much rather see a Category object being pushed via
> operator<<()
>> instead so that it can be detected and allow things like:
>>
>> // assume QMessageLoggerCategory(category) is a class
>> qDebug() << QMessageLoggerCategory("category1")<< 
> "message for
>> category1"<<
> QMessageLoggerCategory("category2")<<  "message for
>> category2";
>
> This fails the "do nothing quickly" test so the cost of leaving such
> statements in shipping code is high, even when the categories are disabled.
>
> This works fine though.
>
> qLog(category1) << "message for category1";
> qLog(category2) << "message for category2";

No more than the Macro.

Yes, it would need to read all the strings; but then it could just read them instead. The macro fails in the same respect.

It can also do the same test - and output an empty (or special) object if the category is not enabled, or a complete object if it is not..
And the first qDebug() can be still managed by the macro to completely disable everything just the same.

Ben
Lincoln Ramsay
2012-02-16 04:00:03 UTC
Permalink
On 02/16/2012 02:14 AM, ext BRM wrote:
>> This fails the "do nothing quickly" test so the cost of leaving
>> such statements in shipping code is high, even when the categories
>> are disabled.
>>
>> This works fine though.
>>
>> qLog(category1)<< "message for category1";
>> qLog(category2)<< "message for category2";
>
> No more than the Macro.
>
> Yes, it would need to read all the strings; but then it could just
> read them instead. The macro fails in the same respect.

I don't think I get where you're going here.

qLog expands to:

if (do_nothing) /*NOP*/; else qDebug() << "your message";

Why? Because the category check must be done first and it must be done
quickly. That means things like no string operations in the "common"
case (where we already know that the category is disabled). Sure, if you
don't know if the category should be disabled you're going to have to do
some calculations but that's the exception, not the norm.

Filtering out either at the QDebug object level or the message handler
level means that all of the code after the << _must_ be executed even if
the resulting strings are going to be dropped on the floor. This could
be hundreds of instructions which may not be noticeable on a desktop but
will cripple any slower device.

So...

This code can quickly do nothing:
qLog(category1) << "message for category1";
qLog(category2) << "message for category2";

This code cannot:
qDebug() << category1 << "message for category1"
<< category2 << "message for category2";

Is the second syntax really that much better to justify the large
performance hit? I just don't see it.

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
BRM
2012-02-16 06:16:28 UTC
Permalink
> From: Lincoln Ramsay <***@nokia.com>

>To: BRM <***@yahoo.com>
>On 02/16/2012 02:14 AM, ext BRM wrote:
>>> This fails the "do nothing quickly" test so the cost of leaving
>>> such statements in shipping code is high, even when the categories
>>> are disabled.
>>>
>>> This works fine though.
>>>
>>> qLog(category1)<< "message for category1";
>>> qLog(category2)<< "message for category2";
>>
>> No more than the Macro.
>>
>> Yes, it would need to read all the strings; but then it could just
>> read them instead. The macro fails in the same respect.
>
>I don't think I get where you're going here.
>
>qLog expands to:
>
>if (do_nothing) /*NOP*/; else qDebug() << "your message";
>
>Why? Because the category check must be done first and it must be done quickly. That means things like no string operations in the "common" case (where we already know that the category is disabled). Sure, if you don't know if the category should be disabled you're going to have to do some calculations but that's the exception, not the norm.
>
>Filtering out either at the QDebug object level or the message handler level means that all of the code after the << _must_ be executed even if the resulting strings are going to be dropped on the floor. This could be hundreds of instructions which may not be noticeable on a desktop but will cripple any slower device.
>
>So...
>
>This code can quickly do nothing:
>qLog(category1) << "message for category1";
>qLog(category2) << "message for category2";
>
>This code cannot:
>qDebug() << category1 << "message for category1"
>         << category2 << "message for category2";
>
>Is the second syntax really that much better to justify the large performance hit? I just don't see it.


Unless you're operating on a very slow processor (which is unlikely nowadays) or in a very highly time-sensitive environment (again, unlikely, or you probably wouldn't be using Qt anyway, and you'd probably be running QNX, VxWorks, or rtLinux in such case too), then the performance overhead won't be that great for doing the filtering on the fly.

As I noted earlier, I do deal with a system that is in near-real-time, collecting and processing data at up to 400HZ. It runs Linux with Qt; and does extensive logging in real-time to syslog.  When errors occur, 500MB of logs can be accumulated in a few seconds. Yet the logging is a not performance issue. So I fail to see the need to be so performance sensitive about the logging.

As you're already changing to use qLog() vs qDebug() - you can just as easily disable it by having qLog() do the same thing :

#define qLog() if (do_nothing); else qDebug() << category1<<"message for category 1"<< category2<<"message for category2";

And you get the benefit of being able to push more than one category through a single call. You're macro is not filtering based on the cateogry - it's not doing _anything_ with the category.

Furthermore, if you do make the macro evaluate the category, then you have to call something at run-time to do the filtering, in which case what I propose is equally as good.


So, why not make the category actually mean something that _can_ be filtered if desired?

Ben
Lincoln Ramsay
2012-02-16 09:00:31 UTC
Permalink
On 02/16/2012 04:16 PM, ext BRM wrote:
> Unless you're operating on a very slow processor (which is unlikely
> nowadays) or in a very highly time-sensitive environment (again,
> unlikely, or you probably wouldn't be using Qt anyway, and you'd
> probably be running QNX, VxWorks, or rtLinux in such case too), then
> the performance overhead won't be that great for doing the filtering
> on the fly.

Perhaps... though there are many devices that have single-core, sub-Ghz
CPUs and that's not going to change for a while yet. Plus, it will
always be beneficial to use as few cycles as possible on a mobile device
to extend battery life.

> As I noted earlier, I do deal with a system that is in
> near-real-time, collecting and processing data at up to 400HZ. It
> runs Linux with Qt; and does extensive logging in real-time to
> syslog. When errors occur, 500MB of logs can be accumulated in a few
> seconds. Yet the logging is a not performance issue. So I fail to see
> the need to be so performance sensitive about the logging.

It's one thing to put logs into your own system. If they were a
performance problem, you'd be able to do something about it. It's quite
another thing to find out that a third party library you use has put in
a bunch of logging statements that are wasting CPU doing nothing. Since
the point of putting qLog into QtCore is to add a bunch of logging
statements to Qt itself, it's pretty important that the overhead of
those statements is as low as possible until they are turned on.

> As you're already changing to use qLog() vs qDebug() - you can just
> as easily disable it by having qLog() do the same thing :
>
> #define qLog() if (do_nothing); else qDebug()<< category1<<"message
> for category 1"<< category2<<"message for category2";
>
> And you get the benefit of being able to push more than one category
> through a single call. You're macro is not filtering based on the
> cateogry - it's not doing _anything_ with the category.

Er... I've been using a generalized form of the macro for example
purposes. The real one most certainly does filter based on the category.
If you care about the implementation details, see the change:
http://codereview.qt-project.org/#change,13226

> Furthermore, if you do make the macro evaluate the category, then you
> have to call something at run-time to do the filtering, in which case
> what I propose is equally as good.

No, for the reasons stated before and above. Moving the "filtering" down
into the QDebug object or message handler results in a lot of work to
generate messages that get thrown away.

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
Lincoln Ramsay
2012-02-15 01:00:35 UTC
Permalink
On 02/14/2012 08:22 PM, Koehne Kai (Nokia-MP/Berlin) wrote:
> Just wanted to point out that there are variadic macros

I'm aware of this but last time I checked, they weren't in the C++
standard. It seems they're new to C99 and C++11. Grepping over the Qt 5
sources reveals no variadic macros in Qt, though a few exist in third
party bundled code.

I'm not in a position to say "we can use variadic macros in QtCore"
which is why I didn't actually try to do that.

If someone who knows about supported platforms and variadic macro
support in compilers can clarify that we can use variadic macros in Qt,
then we can see if we can actually use variadic macros to differentiate
between:

qDebug("message");
qDebug() << "message";
qDebug(CAT) << "message";

Where the last one expands to if (do_nothing); else debug()

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
Thiago Macieira
2012-02-15 08:12:57 UTC
Permalink
On quarta-feira, 15 de fevereiro de 2012 11.00.35, Lincoln Ramsay wrote:
> I'm not in a position to say "we can use variadic macros in QtCore"
> which is why I didn't actually try to do that.

You can use it if you add the necessary #ifdef for the compilers that support
it or for C++11 support (Q_COMPILER_VARIADIC_MACROS) and an #else path for
when it is not enabled.

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
Jedrzej Nowacki
2012-02-15 08:21:21 UTC
Permalink
On Wednesday 15. February 2012 02.00.35 ext Lincoln Ramsay wrote:
> On 02/14/2012 08:22 PM, Koehne Kai (Nokia-MP/Berlin) wrote:
> > Just wanted to point out that there are variadic macros
>
> I'm aware of this but last time I checked, they weren't in the C++
> standard. It seems they're new to C99 and C++11. Grepping over the Qt 5
> sources reveals no variadic macros in Qt, though a few exist in third
> party bundled code.
>
> I'm not in a position to say "we can use variadic macros in QtCore"
> which is why I didn't actually try to do that.
>
> If someone who knows about supported platforms and variadic macro
> support in compilers can clarify that we can use variadic macros in Qt,
> then we can see if we can actually use variadic macros to differentiate
> between:
>
> qDebug("message");
> qDebug() << "message";
> qDebug(CAT) << "message";
>
> Where the last one expands to if (do_nothing); else debug()

Hi,

Usage of variadic macro was removed from Qt, It was causing compilation
failure of a code compiled with --ansi -werror.

It was discussed here: http://lists.qt-project.org/pipermail/development/2011-
November/000348.html

Cheers,
Jędrek
Lincoln Ramsay
2012-02-15 01:10:35 UTC
Permalink
On 02/14/2012 08:22 PM, Koehne Kai (Nokia-MP/Berlin) wrote:
> Here's another idea:
>
> // in qlogging.h
> void qMessageLogEnabled(const char *area)
> #define QMessageArea(area) if (qMessageLogEnabled(area)) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, area)
>
> Usage would be e.g.
>
> QMessageArea("MyArea").debug()<< expensiveFunc();
> QMessageArea("MyArea").warning("%s", expensiveFunc());

Supporting both debug and warning statements tied to a category isn't
useful. Warnings have always been unconditional and will remain so.

Removing that from your example gives almost the same syntax as qLog but
with a different name and I think I've covered that already :)

--
Lincoln Ramsay - Senior Software Engineer
Qt Development Frameworks, Nokia - http://qt.nokia.com/
David Faure
2012-02-16 15:08:26 UTC
Permalink
On Wednesday 15 February 2012 11:10:35 Lincoln Ramsay wrote:
> Warnings have always been unconditional and will remain so.

Not exactly. They can be disabled at compile time by -DQT_NO_WARNING_OUTPUT.

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
Robin Burchell
2012-02-16 15:23:28 UTC
Permalink
On Thu, Feb 16, 2012 at 4:08 PM, David Faure <***@kdab.com> wrote:
> On Wednesday 15 February 2012 11:10:35 Lincoln Ramsay wrote:
>> Warnings have always been unconditional and will remain so.
>
> Not exactly. They can be disabled at compile time by -DQT_NO_WARNING_OUTPUT.

I almost wrote exactly that mail, but then I thought about the
context. The output may be disabled, but the call is always there, no?
David Faure
2012-02-16 15:47:22 UTC
Permalink
On Thursday 16 February 2012 16:23:28 Robin Burchell wrote:
> On Thu, Feb 16, 2012 at 4:08 PM, David Faure <***@kdab.com> wrote:
> > On Wednesday 15 February 2012 11:10:35 Lincoln Ramsay wrote:
> >> Warnings have always been unconditional and will remain so.
> >
> > Not exactly. They can be disabled at compile time by
> > -DQT_NO_WARNING_OUTPUT.
> I almost wrote exactly that mail, but then I thought about the
> context. The output may be disabled, but the call is always there, no?

No, not in Qt5:

#if defined(QT_NO_WARNING_OUTPUT)
# undef qWarning
# define qWarning QT_NO_QWARNING_MACRO
#endif

and

#define QT_NO_QWARNING_MACRO while (false) QMessageLogger().noDebug

--
David Faure | ***@kdab.com | KDE/Qt Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions
Thiago Macieira
2012-02-16 15:58:22 UTC
Permalink
On quinta-feira, 16 de fevereiro de 2012 16.08.26, David Faure wrote:
> On Wednesday 15 February 2012 11:10:35 Lincoln Ramsay wrote:
> > Warnings have always been unconditional and will remain so.
>
> Not exactly. They can be disabled at compile time by -DQT_NO_WARNING_OUTPUT.

Indeed, but that flag is never set in Qt. I can imagine some embedded system
integrators might want to turn it on to save on library size, but it's a non-
standard build.

Warnings are unconditional and will remain so in Qt. They indicate misuse of
the API.

But other code can use warnings for other reasons and we can't make the
decision for them. KDE has used warnings for a long time to tell developers
about unexpected situations. That's why a couple of years ago I made kWarning
use QtDebugMsg level instead.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
Oswald Buddenhagen
2012-02-07 10:21:32 UTC
Permalink
On Tue, Feb 07, 2012 at 06:54:55AM +0000, ext ***@nokia.com wrote:
> I'm working to integrade category log with QMessageLogger & Co and unfortunatelly we can not use
> qDebg(<category>) << "my message" because there is already a debug(const char *msg, ...) function
> combining with the macro
> #define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug.
>
> So I use a new function and macro:
> QDebug debug();
> QDebug debugCategory(const char *msg);
> QDebug warning();
> QDebug warningCategory(const char *msg);
> QDebug critical();
> QDebug criticalCategory(const char *msg);
> QDebug fatalCategory(const char *msg);
>
> #define qDebugCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debugCategory(#category)
> #define qWarningCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).warningCategory(#category)
> #define qCriticalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).criticalCategory(#category)
> #define qFatalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).fatalCategory(#category)
>
> Any problems with this naming conventions???
>
yes. they suggest that you are getting a category back. a proper verbose
name would be fooWithCategory or possibly categorizedFoo.
the fatal cat certainly has entertainment value, but is not necessarily
good api.
i'd actually suggest going the microsoft route and naming the functions
qFooEx or something similarly undescriptive. then it's clear that it's
"just an overload".

fwiw, the right solution would of course be renaming the existing
qFoo(const char *) to qPrintFoo(const char *) - the overloading always
seemed weird to me anyway (especially as the stream variant works only
with qdebug.h, while the print variant "just works"). unfortunately,
this is not source compatible.
BRM
2012-02-07 14:53:18 UTC
Permalink
----- Original Message -----
> From: "***@nokia.com" <***@nokia.com>
> To: ***@nokia.com; ***@qt-project.org
> Cc:
> Sent: Tuesday, February 7, 2012 2:26 AM
> Subject: Re: [Development] QLog ( Work on qDebug and friends)
>
> Hi Wolfgang,
>
> how about making the category a distinct type instead?
>
> struct QMessageCategory {
>   explicit QMessageCategory(const char *name);
> };
>
> class QMessageLogger {
>   void debug(const char *format, ...);
>   void debug(QMessageCategory category, const char *format, ...);
> }
>
>
> ...
> QDebugCategory debugCategory("MyApp"); // You'll typically do this
> in one place
> ...
> qDebug(debugCategory, "hi there");
>

+1.

I think this makes a lot of sense especially if you let people derive from QMessageCategory. So I'd suggest it is a class instead of a structure.
(Yes, I know a 'struct' is just a class that defaults to public; but making it a class now (i) saves a lot of headaches, and (ii) makes it more clear what is intended.)

> From: Oswald Buddenhagen <***@nokia.com>

>On Tue, Feb 07, 2012 at 06:54:55AM +0000, ext ***@nokia.com wrote:
>> I'm working to integrade category log with QMessageLogger & Co and unfortunatelly we can not use
>> qDebg(<category>) << "my message" because there is already a debug(const char *msg, ...) function
>> combining with the macro
>> #define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug.
>>
>> So I use a new function and macro:
>>     QDebug debug();
>>     QDebug debugCategory(const char *msg);
>>     QDebug warning();
>>     QDebug warningCategory(const char *msg);
>>     QDebug critical();
>>     QDebug criticalCategory(const char *msg);
>>     QDebug fatalCategory(const char *msg);
>>
>> #define qDebugCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debugCategory(#category)
>> #define qWarningCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).warningCategory(#category)
>> #define qCriticalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).criticalCategory(#category)
>> #define qFatalCat(category) QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).fatalCategory(#category)
>>
>> Any problems with this naming conventions???
>>
>yes. they suggest that you are getting a category back. a proper verbose
>name would be fooWithCategory or possibly categorizedFoo.


+1


>the fatal cat certainly has entertainment value, but is not necessarily
>good api.


Certainly the case.


>i'd actually suggest going the microsoft route and naming the functions
>qFooEx or something similarly undescriptive. then it's clear that it's
>"just an overload".


-1

We're not Microsoft; and I always thought that was bad API design itself as what happens the next time you need to extend it? qFooExEx?
No. Just come up with a new, proper name for it in the first place.


>fwiw, the right solution would of course be renaming the existing
>qFoo(const char *) to qPrintFoo(const char *) - the overloading always
>seemed weird to me anyway (especially as the stream variant works only
>with qdebug.h, while the print variant "just works"). unfortunately,
>this is not source compatible.


Guess its just to C++--ify it; but yeah, I agree. That said; I think the use of QMessageCategory can certainly clean that up.
If done right, one could use the << to generate several different category messages in a row.

Ben
w***@nokia.com
2012-02-10 07:17:39 UTC
Permalink
QLog uses QMessageLogger.
Please check patch:
http://codereview.qt-project.org/#change,13226

B.R.
WB
Loading...