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,
|
NormalMessageFormat,
|
||||||
ErrorMessageFormat,
|
ErrorMessageFormat,
|
||||||
|
LogMessageFormat,
|
||||||
DebugFormat,
|
DebugFormat,
|
||||||
StdOutFormat,
|
StdOutFormat,
|
||||||
StdErrFormat,
|
StdErrFormat,
|
||||||
|
|||||||
@@ -145,6 +145,10 @@ void OutputFormatter::initFormats()
|
|||||||
d->formats[ErrorMessageFormat].setFont(boldFont, QTextCharFormat::FontPropertiesSpecifiedOnly);
|
d->formats[ErrorMessageFormat].setFont(boldFont, QTextCharFormat::FontPropertiesSpecifiedOnly);
|
||||||
d->formats[ErrorMessageFormat].setForeground(theme->color(Theme::OutputPanes_ErrorMessageTextColor));
|
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
|
// StdOutFormat
|
||||||
d->formats[StdOutFormat].setFont(d->font, QTextCharFormat::FontPropertiesSpecifiedOnly);
|
d->formats[StdOutFormat].setFont(d->font, QTextCharFormat::FontPropertiesSpecifiedOnly);
|
||||||
d->formats[StdOutFormat].setForeground(theme->color(Theme::OutputPanes_StdOutTextColor));
|
d->formats[StdOutFormat].setForeground(theme->color(Theme::OutputPanes_StdOutTextColor));
|
||||||
|
|||||||
@@ -27,9 +27,6 @@
|
|||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include "windebuginterface.h"
|
#include "windebuginterface.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_JOURNALD
|
|
||||||
#include "journaldwatcher.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
@@ -72,12 +69,12 @@ struct ApplicationLauncherPrivate {
|
|||||||
Utils::QtcProcess m_guiProcess;
|
Utils::QtcProcess m_guiProcess;
|
||||||
Utils::ConsoleProcess m_consoleProcess;
|
Utils::ConsoleProcess m_consoleProcess;
|
||||||
ApplicationLauncher::Mode m_currentMode;
|
ApplicationLauncher::Mode m_currentMode;
|
||||||
|
// Keep track whether we need to emit a finished signal
|
||||||
|
bool m_processRunning = false;
|
||||||
|
|
||||||
QTextCodec *m_outputCodec;
|
QTextCodec *m_outputCodec;
|
||||||
QTextCodec::ConverterState m_outputCodecState;
|
QTextCodec::ConverterState m_outputCodecState;
|
||||||
QTextCodec::ConverterState m_errorCodecState;
|
QTextCodec::ConverterState m_errorCodecState;
|
||||||
// Keep track whether we need to emit a finished signal
|
|
||||||
bool m_processRunning = false;
|
|
||||||
|
|
||||||
qint64 m_listeningPid = 0;
|
qint64 m_listeningPid = 0;
|
||||||
};
|
};
|
||||||
@@ -126,10 +123,6 @@ ApplicationLauncher::ApplicationLauncher(QObject *parent) : QObject(parent),
|
|||||||
connect(WinDebugInterface::instance(), &WinDebugInterface::debugOutput,
|
connect(WinDebugInterface::instance(), &WinDebugInterface::debugOutput,
|
||||||
this, &ApplicationLauncher::checkDebugOutput, Qt::BlockingQueuedConnection);
|
this, &ApplicationLauncher::checkDebugOutput, Qt::BlockingQueuedConnection);
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_JOURNALD
|
|
||||||
connect(JournaldWatcher::instance(), &JournaldWatcher::journaldOutput,
|
|
||||||
this, &ApplicationLauncher::checkDebugOutput);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationLauncher::~ApplicationLauncher()
|
ApplicationLauncher::~ApplicationLauncher()
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ bool JournaldWatcher::subscribe(QObject *subscriber, const Subscription &subscri
|
|||||||
[subscriber](const JournaldWatcherPrivate::SubscriberInformation &info) {
|
[subscriber](const JournaldWatcherPrivate::SubscriberInformation &info) {
|
||||||
return info.subscriber == subscriber;
|
return info.subscriber == subscriber;
|
||||||
});
|
});
|
||||||
QTC_ASSERT(pos >= 0, return false);
|
QTC_ASSERT(pos < 0, return false);
|
||||||
|
|
||||||
d->m_subscriptions.append(JournaldWatcherPrivate::SubscriberInformation(subscriber, subscription));
|
d->m_subscriptions.append(JournaldWatcherPrivate::SubscriberInformation(subscriber, subscription));
|
||||||
connect(subscriber, &QObject::destroyed, m_instance, &JournaldWatcher::unsubscribe);
|
connect(subscriber, &QObject::destroyed, m_instance, &JournaldWatcher::unsubscribe);
|
||||||
@@ -214,20 +214,6 @@ void JournaldWatcher::handleEntry()
|
|||||||
|
|
||||||
foreach (const JournaldWatcherPrivate::SubscriberInformation &info, d->m_subscriptions)
|
foreach (const JournaldWatcherPrivate::SubscriberInformation &info, d->m_subscriptions)
|
||||||
info.subscription(logEntry);
|
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:
|
public:
|
||||||
typedef QMap<QByteArray, QByteArray> LogEntry;
|
typedef QMap<QByteArray, QByteArray> LogEntry;
|
||||||
typedef std::function<void(LogEntry)> Subscription;
|
typedef std::function<void(const LogEntry&)> Subscription;
|
||||||
|
|
||||||
~JournaldWatcher() override;
|
~JournaldWatcher() override;
|
||||||
|
|
||||||
@@ -52,9 +52,6 @@ public:
|
|||||||
static bool subscribe(QObject *subscriber, const Subscription &subscription);
|
static bool subscribe(QObject *subscriber, const Subscription &subscription);
|
||||||
static void unsubscribe(QObject *subscriber);
|
static void unsubscribe(QObject *subscriber);
|
||||||
|
|
||||||
signals:
|
|
||||||
void journaldOutput(quint64 pid, const QString &message);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JournaldWatcher();
|
JournaldWatcher();
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,10 @@
|
|||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined (WITH_JOURNALD)
|
||||||
|
#include "journaldwatcher.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
@@ -541,10 +545,31 @@ public:
|
|||||||
|
|
||||||
RunControl::RunControl(RunConfiguration *runConfiguration, Core::Id mode) :
|
RunControl::RunControl(RunConfiguration *runConfiguration, Core::Id mode) :
|
||||||
d(new Internal::RunControlPrivate(runConfiguration, 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()
|
RunControl::~RunControl()
|
||||||
{
|
{
|
||||||
|
#ifdef WITH_JOURNALD
|
||||||
|
JournaldWatcher::instance()->unsubscribe(this);
|
||||||
|
#endif
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user