forked from qt-creator/qt-creator
		
	ProjectExplorer: Retrieve output from Journald more reliably
Retrieve output from Journald more reliably. Change-Id: Ic733698e7ed3717841a5a902c4f1e9e94d952885 Reviewed-by: Christian Stenger <christian.stenger@qt.io> Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
		@@ -31,6 +31,7 @@ enum OutputFormat
 | 
			
		||||
{
 | 
			
		||||
    NormalMessageFormat,
 | 
			
		||||
    ErrorMessageFormat,
 | 
			
		||||
    LogMessageFormat,
 | 
			
		||||
    DebugFormat,
 | 
			
		||||
    StdOutFormat,
 | 
			
		||||
    StdErrFormat,
 | 
			
		||||
 
 | 
			
		||||
@@ -145,6 +145,10 @@ void OutputFormatter::initFormats()
 | 
			
		||||
    d->formats[ErrorMessageFormat].setFont(boldFont, QTextCharFormat::FontPropertiesSpecifiedOnly);
 | 
			
		||||
    d->formats[ErrorMessageFormat].setForeground(theme->color(Theme::OutputPanes_ErrorMessageTextColor));
 | 
			
		||||
 | 
			
		||||
    // LogMessageFormat
 | 
			
		||||
    d->formats[LogMessageFormat].setFont(d->font, QTextCharFormat::FontPropertiesSpecifiedOnly);
 | 
			
		||||
    d->formats[LogMessageFormat].setForeground(theme->color(Theme::OutputPanes_WarningMessageTextColor));
 | 
			
		||||
 | 
			
		||||
    // StdOutFormat
 | 
			
		||||
    d->formats[StdOutFormat].setFont(d->font, QTextCharFormat::FontPropertiesSpecifiedOnly);
 | 
			
		||||
    d->formats[StdOutFormat].setForeground(theme->color(Theme::OutputPanes_StdOutTextColor));
 | 
			
		||||
 
 | 
			
		||||
@@ -27,9 +27,6 @@
 | 
			
		||||
#ifdef Q_OS_WIN
 | 
			
		||||
#include "windebuginterface.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef WITH_JOURNALD
 | 
			
		||||
#include "journaldwatcher.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <coreplugin/icore.h>
 | 
			
		||||
 | 
			
		||||
@@ -72,12 +69,12 @@ struct ApplicationLauncherPrivate {
 | 
			
		||||
    Utils::QtcProcess m_guiProcess;
 | 
			
		||||
    Utils::ConsoleProcess m_consoleProcess;
 | 
			
		||||
    ApplicationLauncher::Mode m_currentMode;
 | 
			
		||||
    // Keep track whether we need to emit a finished signal
 | 
			
		||||
    bool m_processRunning = false;
 | 
			
		||||
 | 
			
		||||
    QTextCodec *m_outputCodec;
 | 
			
		||||
    QTextCodec::ConverterState m_outputCodecState;
 | 
			
		||||
    QTextCodec::ConverterState m_errorCodecState;
 | 
			
		||||
    // Keep track whether we need to emit a finished signal
 | 
			
		||||
    bool m_processRunning = false;
 | 
			
		||||
 | 
			
		||||
    qint64 m_listeningPid = 0;
 | 
			
		||||
};
 | 
			
		||||
@@ -126,10 +123,6 @@ ApplicationLauncher::ApplicationLauncher(QObject *parent) : QObject(parent),
 | 
			
		||||
    connect(WinDebugInterface::instance(), &WinDebugInterface::debugOutput,
 | 
			
		||||
            this, &ApplicationLauncher::checkDebugOutput, Qt::BlockingQueuedConnection);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef WITH_JOURNALD
 | 
			
		||||
    connect(JournaldWatcher::instance(), &JournaldWatcher::journaldOutput,
 | 
			
		||||
            this, &ApplicationLauncher::checkDebugOutput);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ApplicationLauncher::~ApplicationLauncher()
 | 
			
		||||
 
 | 
			
		||||
@@ -163,7 +163,7 @@ bool JournaldWatcher::subscribe(QObject *subscriber, const Subscription &subscri
 | 
			
		||||
                             [subscriber](const JournaldWatcherPrivate::SubscriberInformation &info) {
 | 
			
		||||
                                 return info.subscriber == subscriber;
 | 
			
		||||
                             });
 | 
			
		||||
    QTC_ASSERT(pos >= 0, return false);
 | 
			
		||||
    QTC_ASSERT(pos < 0, return false);
 | 
			
		||||
 | 
			
		||||
    d->m_subscriptions.append(JournaldWatcherPrivate::SubscriberInformation(subscriber, subscription));
 | 
			
		||||
    connect(subscriber, &QObject::destroyed, m_instance, &JournaldWatcher::unsubscribe);
 | 
			
		||||
@@ -214,20 +214,6 @@ void JournaldWatcher::handleEntry()
 | 
			
		||||
 | 
			
		||||
        foreach (const JournaldWatcherPrivate::SubscriberInformation &info, d->m_subscriptions)
 | 
			
		||||
            info.subscription(logEntry);
 | 
			
		||||
 | 
			
		||||
        if (logEntry.value(QByteArrayLiteral("_MACHINE_ID")) != machineId())
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        const QByteArray pid = logEntry.value(QByteArrayLiteral("_PID"));
 | 
			
		||||
        if (pid.isEmpty())
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        quint64 pidNum = QString::fromLatin1(pid).toInt();
 | 
			
		||||
 | 
			
		||||
        QString message = QString::fromUtf8(logEntry.value(QByteArrayLiteral("MESSAGE")));
 | 
			
		||||
        message.append(QLatin1Char('\n')); // Add newline.
 | 
			
		||||
 | 
			
		||||
        emit journaldOutput(pidNum, message);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ class JournaldWatcher : public QObject
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    typedef QMap<QByteArray, QByteArray> LogEntry;
 | 
			
		||||
    typedef std::function<void(LogEntry)> Subscription;
 | 
			
		||||
    typedef std::function<void(const LogEntry&)> Subscription;
 | 
			
		||||
 | 
			
		||||
    ~JournaldWatcher() override;
 | 
			
		||||
 | 
			
		||||
@@ -52,9 +52,6 @@ public:
 | 
			
		||||
    static bool subscribe(QObject *subscriber, const Subscription &subscription);
 | 
			
		||||
    static void unsubscribe(QObject *subscriber);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void journaldOutput(quint64 pid, const QString &message);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    JournaldWatcher();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,10 @@
 | 
			
		||||
#include <ApplicationServices/ApplicationServices.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined (WITH_JOURNALD)
 | 
			
		||||
#include "journaldwatcher.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using namespace Utils;
 | 
			
		||||
 | 
			
		||||
namespace ProjectExplorer {
 | 
			
		||||
@@ -541,10 +545,31 @@ public:
 | 
			
		||||
 | 
			
		||||
RunControl::RunControl(RunConfiguration *runConfiguration, Core::Id mode) :
 | 
			
		||||
    d(new Internal::RunControlPrivate(runConfiguration, mode))
 | 
			
		||||
{ }
 | 
			
		||||
{
 | 
			
		||||
#ifdef WITH_JOURNALD
 | 
			
		||||
    JournaldWatcher::instance()->subscribe(this, [this](const JournaldWatcher::LogEntry &entry) {
 | 
			
		||||
        if (entry.value("_MACHINE_ID") != JournaldWatcher::instance()->machineId())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        const QByteArray pid = entry.value("_PID");
 | 
			
		||||
        if (pid.isEmpty())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        const qint64 pidNum = static_cast<qint64>(QString::fromLatin1(pid).toInt());
 | 
			
		||||
        if (pidNum != d->applicationProcessHandle.pid())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        const QString message = QString::fromUtf8(entry.value("MESSAGE")) + "\n";
 | 
			
		||||
        appendMessageRequested(this, message, Utils::OutputFormat::LogMessageFormat);
 | 
			
		||||
    });
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RunControl::~RunControl()
 | 
			
		||||
{
 | 
			
		||||
#ifdef WITH_JOURNALD
 | 
			
		||||
    JournaldWatcher::instance()->unsubscribe(this);
 | 
			
		||||
#endif
 | 
			
		||||
    delete d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user