Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to redirect std::out & std::err to a qDebug() message
Forum Updated to NodeBB v4.3 + New Features

How to redirect std::out & std::err to a qDebug() message

Scheduled Pinned Locked Moved Unsolved General and Desktop
10 Posts 5 Posters 1.9k Views 5 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    ademmler
    wrote on 1 Sept 2023, 08:56 last edited by
    #1

    In my application I use dDebug for logging. Actually I miss all std::out and std::err messages - coming from external libs/dlls/frameworks - in my logging. Is there a way to catch std::out and std::error messages and create a qDebug() message?

    I want to do it this way, because all my qDebug() messages ending up in a log file already and I want to add std::err and std::out to it.

    I searched the forum but found only logging to file examples.

    J P 2 Replies Last reply 1 Sept 2023, 09:02
    0
    • A ademmler
      1 Sept 2023, 08:56

      In my application I use dDebug for logging. Actually I miss all std::out and std::err messages - coming from external libs/dlls/frameworks - in my logging. Is there a way to catch std::out and std::error messages and create a qDebug() message?

      I want to do it this way, because all my qDebug() messages ending up in a log file already and I want to add std::err and std::out to it.

      I searched the forum but found only logging to file examples.

      J Offline
      J Offline
      JonB
      wrote on 1 Sept 2023, 09:02 last edited by
      #2

      @ademmler
      I presume you mean nothing to do with running external processes via QProcess, you mean that code you link with writes stuff to stdout/err?
      Start by confirming that if you run under Qt Creator debugger you do see these messages in its *Application Output pane?
      The first thing is that solution will depend on whether your Qt program is a console or a UI application?
      You might also indicate target platform(s)?

      A 1 Reply Last reply 1 Sept 2023, 09:07
      0
      • J JonB
        1 Sept 2023, 09:02

        @ademmler
        I presume you mean nothing to do with running external processes via QProcess, you mean that code you link with writes stuff to stdout/err?
        Start by confirming that if you run under Qt Creator debugger you do see these messages in its *Application Output pane?
        The first thing is that solution will depend on whether your Qt program is a console or a UI application?
        You might also indicate target platform(s)?

        A Offline
        A Offline
        ademmler
        wrote on 1 Sept 2023, 09:07 last edited by
        #3

        @JonB Dear John, thx agin.

        yes I meant linked code, which writes stuff to stdout/err.
        And yes I see all messages in the debugger.
        It is a UI Application running on Mac OS, Windows and Linux - hence cross platform.

        J 1 Reply Last reply 1 Sept 2023, 09:15
        0
        • A ademmler
          1 Sept 2023, 09:07

          @JonB Dear John, thx agin.

          yes I meant linked code, which writes stuff to stdout/err.
          And yes I see all messages in the debugger.
          It is a UI Application running on Mac OS, Windows and Linux - hence cross platform.

          J Offline
          J Offline
          JonB
          wrote on 1 Sept 2023, 09:15 last edited by JonB 9 Jan 2023, 09:20
          #4

          @ademmler said in How to redirect std::out & std::err to a qDebug() message:

          hence cross platform

          Yeah, that's nasty but rules out e.g. any Windows-only solutions, so we know where we are.

          Basically I would expect you to use either freopen(stdout/stderr) or possibly open/dup(1/2). These are C library calls, hopefully POSIX, you'd have to check across platforms. You won't be able to actually use qDebug(), you are trying to getting them into the Qt message handler you must have installed for your present save to log file. Unless you choose to directly append those messages to file rather than go through a Qt message handler, you will probably want to redirect to a string buffer. I don't know whether the C++ at https://en.cppreference.com/w/cpp/io/basic_ios/rdbuf could be useful.

          1 Reply Last reply
          0
          • A ademmler
            1 Sept 2023, 08:56

            In my application I use dDebug for logging. Actually I miss all std::out and std::err messages - coming from external libs/dlls/frameworks - in my logging. Is there a way to catch std::out and std::error messages and create a qDebug() message?

            I want to do it this way, because all my qDebug() messages ending up in a log file already and I want to add std::err and std::out to it.

            I searched the forum but found only logging to file examples.

            P Offline
            P Offline
            Pl45m4
            wrote on 1 Sept 2023, 12:17 last edited by
            #5

            @ademmler

            Have you seen this?

            • https://stackoverflow.com/questions/4954140/how-to-redirect-qdebug-qwarning-qcritical-etc-output

            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

            ~E. W. Dijkstra

            J A 2 Replies Last reply 1 Sept 2023, 13:34
            1
            • P Pl45m4
              1 Sept 2023, 12:17

              @ademmler

              Have you seen this?

              • https://stackoverflow.com/questions/4954140/how-to-redirect-qdebug-qwarning-qcritical-etc-output
              J Offline
              J Offline
              JonB
              wrote on 1 Sept 2023, 13:34 last edited by
              #6

              @Pl45m4
              That is all standard qDebug()/qInstallMessageHandler() stuff. I presume the OP already has that

              because all my qDebug() messages ending up in a log file already and I want to add std::err and std::out to it.

              The part the OP wants is how to grab anything written to stdout/err by anything in his application, including from libraries, so code for that cannot be changed.

              A 1 Reply Last reply 1 Sept 2023, 19:53
              1
              • P Pl45m4
                1 Sept 2023, 12:17

                @ademmler

                Have you seen this?

                • https://stackoverflow.com/questions/4954140/how-to-redirect-qdebug-qwarning-qcritical-etc-output
                A Offline
                A Offline
                ademmler
                wrote on 1 Sept 2023, 19:53 last edited by
                #7

                @Pl45m4 Yes I have seen this. Thanks you.

                I use this in my Application. This way Uni Messages and Logging goes the same way. Now I wan't to add stderr/out to exit the same logfile.

                void MyApplication::sendMessage(QString message, int msg_mode = msg_debug, int seconds)
                {
                    QFile *file = new QFile;
                    file->setFileName(logFolder.absolutePath() + "/application.log");
                    file->open(QIODevice::Append | QIODevice::Text);
                    QTextStream logfile(file);
                    logfile.setCodec("UTF-8");
                
                    switch (msg_mode) {
                    case msg_debug:
                        qDebug() << message;
                        logfile << "Debug: " << message << "\n";
                        break;
                    case msg_status:
                        qDebug() << message;
                        logfile << "Status: " << message << "\n";
                        ui->statusBar->showMessage(message, seconds);
                        break;
                    case msg_boxInfo:
                        qDebug() << message;
                        logfile << "Info: " << message << "\n";
                        QMessageBox::information(this, tr("Info"), message);
                        break;
                    case msg_boxWarning:
                        qDebug() << message;
                        logfile << "Warning: " << message << "\n";
                        QMessageBox::warning(this, tr("Warning"), message);
                        break;
                    case msg_boxError:
                        qDebug() << message;
                        logfile << "Error: " << message << "\n";
                        QMessageBox::warning(this, tr("Error"), message);
                        break;
                    case msg_boxStatus:
                        qDebug() << message;
                        logfile << "Warning: " << message << "\n";
                        ui->statusBar->showMessage(message, seconds);
                        QMessageBox::warning(this, tr("Warning"), message);
                        break;
                    case msg_boxWarningYN:
                        qDebug() << message;
                        logfile << "Warning: " << message << "\n";
                        QMessageBox::warning(this, tr("Warning"), message, QMessageBox::Yes | QMessageBox::No);
                        break;
                    }
                
                    if (file != 0)
                        file->close();
                }
                
                1 Reply Last reply
                0
                • J JonB
                  1 Sept 2023, 13:34

                  @Pl45m4
                  That is all standard qDebug()/qInstallMessageHandler() stuff. I presume the OP already has that

                  because all my qDebug() messages ending up in a log file already and I want to add std::err and std::out to it.

                  The part the OP wants is how to grab anything written to stdout/err by anything in his application, including from libraries, so code for that cannot be changed.

                  A Offline
                  A Offline
                  ademmler
                  wrote on 1 Sept 2023, 19:53 last edited by
                  #8

                  @JonB OP = ?

                  M 1 Reply Last reply 1 Sept 2023, 23:03
                  0
                  • A ademmler
                    1 Sept 2023, 19:53

                    @JonB OP = ?

                    M Offline
                    M Offline
                    mpergand
                    wrote on 1 Sept 2023, 23:03 last edited by
                    #9

                    @ademmler said in How to redirect std::out & std::err to a qDebug() message:

                    OP = ?

                    Original poster/post

                    1 Reply Last reply
                    0
                    • Paul ColbyP Offline
                      Paul ColbyP Offline
                      Paul Colby
                      wrote on 2 Sept 2023, 02:11 last edited by Paul Colby 9 Feb 2023, 02:12
                      #10

                      Hi @ademmler,

                      Just for inspiration, here's a class I use for capturing std::cout for verifying output in unit tests. You should be able to use it for std::err too, and then either qDebug() the captured text, or invoke your installed message handler directly, as @JonB suggested.

                      Note, though, this would only work for code that uses the std::cout and/or std::cerr C++ output streams, which is close but not quite the same as, for example, plain C code writing to the stdout or stderr file stream pointers, so it depends on how your included libraries, etc are writing their output.

                      /*!
                       * Implements a simple RAII capture of output streams.
                       */
                      class OutputStreamCapture
                      {
                      public:
                          explicit OutputStreamCapture(std::ostream * const stream) : stream(stream)
                          {
                              originalBuffer = stream->rdbuf(newBuffer.rdbuf());
                          }
                      
                          std::string data() const
                          {
                              return newBuffer.str();
                          }
                      
                          ~OutputStreamCapture()
                          {
                              stream->rdbuf(originalBuffer);
                          }
                      
                      private:
                          std::ostringstream newBuffer;
                          std::streambuf * originalBuffer;
                          std::ostream * stream;
                      };
                      

                      Use it like:

                      const OutputStreamCapture capture(&std::cout);
                      // do stuff that might output to std::cout.
                      qDebug() << capture.data();
                      

                      Again, this won't capture non-C++ streams, but at least it is portable (on Linux, macOS and Windows at least).

                      Hope that helps.

                      Cheers.

                      1 Reply Last reply
                      2

                      1/10

                      1 Sept 2023, 08:56

                      • Login

                      • Login or register to search.
                      1 out of 10
                      • First post
                        1/10
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved