7

According to qlogging.h

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

but when I use like this, file,line,function name not show.

qDebug()<< "abc"; // only show abc;
qDebug()<< "";    // show nothing;

I search for a while, it seems no one had my problem like above.

I use ubuntu14.04,g++ version 4.8.2, qt5.3 build from git.

T_T
  • 515
  • 1
  • 7
  • 16
  • Just because the logger captures that context data doesn't mean it will actually be displayed. There's no mention in the docs of that information being outputted, and digging into the source code to see how it might be used is a pretty deep rabbit hole. – Retired Ninja Jun 03 '14 at 10:14
  • That is really confusing. Why not displayed, who ever do not want it to be displayed. – T_T Jun 03 '14 at 15:04

8 Answers8

21

You can reformat from default output format. This function was introduced in Qt 5.0.

The line number does not output because the default message pattern is "%{if-category}%{category}: %{endif}%{message}". This format means that the default outputting format is not including metadata like a line number or file name.

% cat logtest.pro

TEMPLATE = app
TARGET = logtest
mac:CONFIG-=app_bundle
SOURCES += main.cpp

% cat main.cpp

#include <QCoreApplication>
#include <QDebug>

int main(int argc, char *argv[])
{
    qSetMessagePattern("%{file}(%{line}): %{message}");
    QCoreApplication a(argc, argv);
    qDebug() << "my output";
    return 0;
}

% qmake && make

% ./logtest

main.cpp(8): my output

You can also use QT_MESSAGE_PATTERN environment variable for setting the message pattern without calling qSetMessagePattern().

See reference for other placeholder. http://qt-project.org/doc/qt-5/qtglobal.html#qSetMessagePattern

user1544041
  • 211
  • 2
  • 5
14

If you dig in Qt history you can find out that the __FILE__ and __FUNCTION__ are logged only in debug builds since 1 Oct 2014. The git commit hash is d78fb442d750b33afe2e41f31588ec94cf4023ad. The commit message states:

Logging: Disable tracking of debug source info for release builds

Tracking the file, line, function means the information has to be stored in the binaries, enlarging the size. It also might be a surprise to some commercial customers that their internal file & function names are 'leaked'. Therefore we enable it for debug builds only.

pestophagous
  • 4,069
  • 3
  • 33
  • 42
Uga Buga
  • 1,724
  • 3
  • 19
  • 38
  • 1
    Can you add link? – kyb Sep 29 '18 at 19:53
  • You need to clone the Qt git repository and search the commit mentionsd. Currently I could not find a repository that is web browsable. As far as I remember it was in the qtbase sumodule. – Uga Buga Sep 30 '18 at 21:03
5

Here's a simple example of how you might use the captured QMessageLogContext data in a custom message handler installed using qInstallMessageHandler. I didn't output the category or version members because they didn't seem useful. If desired you could also log to a file this way.

#include <QDebug>
#include <QString>
#include <QDateTime>
#include <iostream>

void verboseMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    static const char* typeStr[] = {"[   Debug]", "[ Warning]", "[Critical]", "[   Fatal]" };

    if(type <= QtFatalMsg)
    {
        QByteArray localMsg = msg.toLocal8Bit();
        QString contextString(QStringLiteral("(%1, %2, %3)")
                              .arg(context.file)
                              .arg(context.function)
                              .arg(context.line));

        QString timeStr(QDateTime::currentDateTime().toString("dd-MM-yy HH:mm:ss:zzz"));

        std::cerr << timeStr.toLocal8Bit().constData() << " - " 
                  << typeStr[type] << " "
                  << contextString.toLocal8Bit().constData() << " " 
                  << localMsg.constData() << std::endl;

        if(type == QtFatalMsg)
        {
            abort();
        }
    }
}

int main()
{
    //Use default handler
    qDebug() << "default handler";
    qWarning() << "default handler";
    qCritical() << "default handler";

    //Install verbose handler
    qInstallMessageHandler(verboseMessageHandler);

    qDebug() << "verbose handler";
    qWarning() << "verbose handler";
    qCritical() << "verbose handler";

    //Restore default handler
    qInstallMessageHandler(0);

    qDebug() << "default handler";
    qWarning() << "default handler";
    qCritical() << "default handler";

    return 0;
}
Retired Ninja
  • 4,785
  • 3
  • 25
  • 35
2

You can use standard C++'s __LINE__ and __FILE__. Also, take a look at What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__ SO question. If you use GCC, you can write __PRETTY_FUNCTION__ to get information about function from where the code executes. Just prepare debug-define you like.

For example, here is small compilable application:

#include <QApplication>
#include <QDebug>
#include <iostream>

// Qt-way
#define MyDBG (qDebug()<<__FILE__<<__LINE__<<__PRETTY_FUNCTION__)
// GCC
#define MyStdDBG (std::cout<< __FILE__<<":"<<__LINE__<<" in "<<__PRETTY_FUNCTION__<<std::endl)

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // Qt-way
    MyDBG;
    MyDBG << "Something happened!";

    // GCC
    MyStdDBG;

    return a.exec();
}

It gives next output:

../path/main.cpp 14 int main(int, char**)
../path/main.cpp 15 int main(int, char**) Something happened!
../path/main.cpp:18 in int main(int, char**)

UPD: Added pure C++-way to output.

Community
  • 1
  • 1
NG_
  • 6,895
  • 7
  • 45
  • 67
  • I define macro myself in other non QT project. But QT provide this macro, I want know how to correct use it. – T_T Jun 03 '14 at 15:07
  • Added upd, please, check it. – NG_ Jun 03 '14 at 16:27
  • I think you misunderstand me.'#define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug' is defined by QT in qlogging.h file, but it is not work as my exceptation. But thanks all the same. – T_T Jun 04 '14 at 01:13
1

I think you need to define:

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

and use it as

qDebug() << "abc";

or

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

and use it as:

qDebug << "abc";
vahancho
  • 20,808
  • 3
  • 47
  • 55
  • I define macro myself in other non QT project. But QT provide this macro, I want know how to correct use it. – T_T Jun 03 '14 at 15:08
1

According to documentation qDebug() is already a macro to QMessageLogger(). Default Message handler prints only the message to stderr. I think you might want to use qInstallMessageHandler() to install your own message handler, that uses the context

Edit:

There is a relevant section in a manual, that describes this issue. In Qt4 context variable was not passed to installed message handler, so this solution is Qt5+ only. Default message handler does not make use of passed in context, but you can easily install your own, it's just a function pointer. There is even an example in the manual.

friendzis
  • 799
  • 6
  • 17
  • I can use this method, or define a simple macro. But QT provide this macro, I want know how to correct use it. – T_T Jun 03 '14 at 15:09
1

This depends on your Qt version number, whether you are using a debug build or a release build of Qt, and whether you have customized Qt message handling in your application.

According to Qt 5.4 documentation written in source code "qlogging.cpp":

QMessageLogger is used to generate messages for the Qt logging framework. Usually one uses
it through qDebug(), qWarning(), qCritical, or qFatal() functions,
which are actually macros: For example qDebug() expands to
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug()
for debug builds, and QMessageLogger(0, 0, 0).debug() for release builds.

So if you do not see file, line and function name information in your output, very likely you are using a release version of Qt.

If you still want to see the file, line and function name information in your output with a release version of Qt, there are several ways of achieving it, as very well explained in some of the previous answers.

jonathanzh
  • 1,346
  • 15
  • 21
1

If you wonder how to get the debug context in a non-debug build: Define QT_MESSAGELOGCONTEXT while compiling your code, and the information won't be stripped:

http://doc.qt.io/qt-5/qmessagelogcontext.html

milianw
  • 5,164
  • 2
  • 37
  • 41