Skip to content

Commit e4c2050

Browse files
committed
refactor(eventreporter): use x_linglong() for linglong detection and improve error reporting
重构事件上报模块:将玲珑包判断从 appId 前缀匹配改为由调用方传入 x_linglong() 结果, 内化包信息查询逻辑,新增 app_package_type 字段上报,优化错误信息并添加命令失败日志。 Rework the event reporting logic in removeInstance to use richer systemd unit exit info (result, execMainCode, execMainStatus, timestamps) via UnitExitInfo, replacing the previous simple string-based result matching. Split the ambiguous exit results into launch-failed vs abnormal-exit using systemd result semantics and a 3-second duration heuristic. Remove the premature reportAppLaunchFailed call from the app-launch-helper exit code check in Launch(), since invalid desktop files would produce noisy data at that stage. - Replace appId.startsWith("org.") with caller-provided x_linglong() for linglong detection - Internalize package info query (version + pakType) into queryAppPackageInfo() - Add app_package_type field to all event reports - Collect full UnitExitInfo (result, execMainCode, execMainStatus, timestamps) via UnitResultWatcher instead of just the result string - Classify systemd results into launchFailedResults and ambiguousResults, use 3s duration threshold to distinguish launch failure from abnormal exit - Remove reportAppLaunchFailed from Launch() app-launch-helper error path to avoid noise from invalid desktop files - Remove reportAppLaunchDuration and getAppVersion() API - Add qCWarning logs for failed dpkg-query/ll-cli commands - Cache both version and pakType (including empty results) to avoid redundant queries - Reduce waitForFinished timeout from 3s/5s to 1s PMS: TASK-389405
1 parent ef15406 commit e4c2050

5 files changed

Lines changed: 147 additions & 97 deletions

File tree

src/dbus/applicationmanager1service.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
#include "systemdsignaldispatcher.h"
1616
#include <DUtil>
1717
#include <QDBusMessage>
18+
#include <QDBusVariant>
1819
#include <QDirIterator>
1920
#include <QFile>
2021
#include <QGuiApplication>
2122
#include <QHash>
2223
#include <QLoggingCategory>
2324
#include <QProcess>
25+
#include <QSet>
2426
#include <QStringBuilder>
2527
#include <unistd.h>
2628

@@ -468,17 +470,40 @@ void ApplicationManager1Service::removeInstanceFromApplication(const QString &un
468470
});
469471

470472
if (instanceIt != appIns.cend()) {
471-
auto result = m_unitResults.take(systemdUnitPath.path());
472-
qCDebug(DDEAM) << "removeInstance: unitPath=" << systemdUnitPath.path() << "cached result=" << result;
473-
if (result == u"failed" || result == u"canceled" || result == u"timeout"
474-
|| result == u"signal" || result == u"core-dump" || result == u"exit-code") {
475-
QStringList logArgs{QStringLiteral("--unit=%1").arg(unitName),
473+
auto exitInfo = m_unitResults.take(systemdUnitPath.path());
474+
qCDebug(DDEAM) << "removeInstance: unitPath=" << systemdUnitPath.path() << "cached result=" << exitInfo.result
475+
<< "execMainCode=" << exitInfo.execMainCode << "execMainStatus=" << exitInfo.execMainStatus
476+
<< "execMainDuration=" << (exitInfo.execMainExitTimestamp - exitInfo.execMainStartTimestamp) / 1000 << "ms";
477+
478+
static const QSet<QString> launchFailedResults{u"start-limit-hit"_s, u"resources"_s, u"exec-condition"_s, u"protocol"_s, u"timeout"_s};
479+
static const QSet<QString> ambiguousResults{u"exit-code"_s, u"signal"_s, u"core-dump"_s, u"oom-kill"_s, u"watchdog"_s};
480+
481+
auto doReport = [&](bool isLaunchFailed) {
482+
QStringList logArgs{"--user", QStringLiteral("--unit=%1").arg(unitName),
476483
"-n", "20", "-o", "cat", "-o", "with-unit", "--no-pager"};
477484
QProcess logProc;
478485
logProc.start("journalctl", logArgs);
479486
logProc.waitForFinished(3000);
480487
QString logInfo = QString::fromUtf8(logProc.readAllStandardOutput());
481-
EventReporter::reportAppAbnormalExit(app->eventAppId(), (*instanceIt)->launchType(), unitName, logInfo, (*instanceIt)->launchUniqueId());
488+
489+
if (isLaunchFailed) {
490+
EventReporter::reportAppLaunchFailed(app->eventAppId(),
491+
QStringLiteral("systemd result: %1, execMainCode: %2, execMainStatus: %3")
492+
.arg(exitInfo.result)
493+
.arg(exitInfo.execMainCode)
494+
.arg(exitInfo.execMainStatus),
495+
app->x_linglong(), (*instanceIt)->launchType(), (*instanceIt)->launchUniqueId());
496+
} else {
497+
EventReporter::reportAppAbnormalExit(app->eventAppId(), (*instanceIt)->launchType(), unitName, logInfo, app->x_linglong(), (*instanceIt)->launchUniqueId());
498+
}
499+
};
500+
501+
if (launchFailedResults.contains(exitInfo.result)) {
502+
doReport(true);
503+
} else if (ambiguousResults.contains(exitInfo.result)) {
504+
auto durationUs = exitInfo.execMainExitTimestamp - exitInfo.execMainStartTimestamp;
505+
constexpr qulonglong launchPhaseThresholdUs = 3'000'000; // 3 seconds
506+
doReport(durationUs < launchPhaseThresholdUs);
482507
}
483508

484509
app->removeOneInstance(instanceIt.key());
@@ -490,10 +515,11 @@ void ApplicationManager1Service::removeInstanceFromApplication(const QString &un
490515
});
491516
}
492517

493-
void ApplicationManager1Service::onUnitResultReady(const QDBusObjectPath &unitPath, const QString &result)
518+
void ApplicationManager1Service::onUnitResultReady(const QDBusObjectPath &unitPath, const UnitExitInfo &info)
494519
{
495-
qCDebug(DDEAM) << "onUnitResultReady: unitPath=" << unitPath.path() << "result=" << result;
496-
m_unitResults.insert(unitPath.path(), result);
520+
qCDebug(DDEAM) << "onUnitResultReady: unitPath=" << unitPath.path() << "result=" << info.result
521+
<< "execMainCode=" << info.execMainCode << "execMainStatus=" << info.execMainStatus;
522+
m_unitResults.insert(unitPath.path(), info);
497523
}
498524

499525
void ApplicationManager1Service::scanMimeInfos() noexcept

src/dbus/applicationmanager1service.h

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ Q_DECLARE_LOGGING_CATEGORY(DDEAM)
2626

2727
class ApplicationService;
2828

29+
struct UnitExitInfo {
30+
QString result;
31+
uint execMainCode{0};
32+
uint execMainStatus{0};
33+
qulonglong execMainStartTimestamp{0};
34+
qulonglong execMainExitTimestamp{0};
35+
};
36+
2937
class UnitResultWatcher : public QObject
3038
{
3139
Q_OBJECT
@@ -36,18 +44,38 @@ class UnitResultWatcher : public QObject
3644
public Q_SLOTS:
3745
void handlePropertyChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated)
3846
{
39-
if ((interface == QStringLiteral("org.freedesktop.systemd1.Unit")
40-
|| interface == QStringLiteral("org.freedesktop.systemd1.Service"))
41-
&& changed.contains(QStringLiteral("Result"))) {
42-
emit resultReady(m_unitPath, changed.value(QStringLiteral("Result")).toString());
47+
if (interface != QStringLiteral("org.freedesktop.systemd1.Unit")
48+
&& interface != QStringLiteral("org.freedesktop.systemd1.Service")) {
49+
return;
50+
}
51+
52+
if (changed.contains(QStringLiteral("Result"))) {
53+
m_info.result = changed.value(QStringLiteral("Result")).toString();
54+
}
55+
if (changed.contains(QStringLiteral("ExecMainCode"))) {
56+
m_info.execMainCode = changed.value(QStringLiteral("ExecMainCode")).toUInt();
57+
}
58+
if (changed.contains(QStringLiteral("ExecMainStatus"))) {
59+
m_info.execMainStatus = changed.value(QStringLiteral("ExecMainStatus")).toUInt();
60+
}
61+
if (changed.contains(QStringLiteral("ExecMainStartTimestamp"))) {
62+
m_info.execMainStartTimestamp = changed.value(QStringLiteral("ExecMainStartTimestamp")).toULongLong();
63+
}
64+
if (changed.contains(QStringLiteral("ExecMainExitTimestamp"))) {
65+
m_info.execMainExitTimestamp = changed.value(QStringLiteral("ExecMainExitTimestamp")).toULongLong();
66+
}
67+
68+
if (!m_info.result.isNull()) {
69+
emit resultReady(m_unitPath, m_info);
4370
}
4471
}
4572

4673
Q_SIGNALS:
47-
void resultReady(const QDBusObjectPath &unitPath, const QString &result);
74+
void resultReady(const QDBusObjectPath &unitPath, const UnitExitInfo &info);
4875

4976
private:
5077
QDBusObjectPath m_unitPath;
78+
UnitExitInfo m_info;
5179
};
5280

5381
class ApplicationManager1Service final : public QObject, protected QDBusContext
@@ -108,7 +136,7 @@ public Q_SLOTS:
108136

109137
private Q_SLOTS:
110138
void doReloadApplications();
111-
void onUnitResultReady(const QDBusObjectPath &unitPath, const QString &result);
139+
void onUnitResultReady(const QDBusObjectPath &unitPath, const UnitExitInfo &info);
112140

113141
private:
114142
bool m_startupPhase{true};
@@ -124,7 +152,7 @@ private Q_SLOTS:
124152
bool m_isReloading{false};
125153
bool m_pendingReload{false};
126154
QHash<QString, QSharedPointer<ApplicationService>> m_applicationList;
127-
QHash<QString, QString> m_unitResults;
155+
QHash<QString, UnitExitInfo> m_unitResults;
128156
QSharedPointer<CompatibilityManager> m_compatibilityManager;
129157
std::unique_ptr<PrelaunchSplashHelper> m_splashHelper;
130158

src/dbus/applicationservice.cpp

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,6 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
408408
}();
409409

410410
if (desktopEntry == nullptr) {
411-
EventReporter::reportAppLaunchFailed(eventAppId(), EventReporter::getAppVersion(id()), "This application is not set to autostart.", launchType, launchUniqueId);
412411
safe_sendErrorReply(QDBusError::Failed, "This application is not set to autostart.");
413412
}
414413

@@ -438,7 +437,6 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
438437
if (!Actions) {
439438
const QString msg{"application can't be executed."};
440439
qWarning() << msg;
441-
EventReporter::reportAppLaunchFailed(eventAppId(), EventReporter::getAppVersion(id()), msg, launchType, launchUniqueId);
442440
safe_sendErrorReply(QDBusError::Failed, msg);
443441
return {};
444442
}
@@ -447,7 +445,6 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
447445
if (execStr.isEmpty()) {
448446
const QString msg{"maybe entry actions's format is invalid, abort launch."};
449447
qWarning() << msg;
450-
EventReporter::reportAppLaunchFailed(eventAppId(), EventReporter::getAppVersion(id()), msg, launchType, launchUniqueId);
451448
safe_sendErrorReply(QDBusError::Failed, msg);
452449
return {};
453450
}
@@ -462,8 +459,6 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
462459
}
463460
}
464461

465-
EventReporter::getAppVersion(eventAppId());
466-
467462
const bool isSingleton =
468463
findEntryValue(fromStaticRaw(DesktopFileEntryKey), fromStaticRaw(DesktopEntryXDeepinSingleton), EntryValueType::Boolean)
469464
.toBool();
@@ -499,14 +494,12 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
499494
auto cmds = generateCommand(optionsMap);
500495
auto task = processExec(execStr, fields, workingDir);
501496
if (!task) {
502-
EventReporter::reportAppLaunchFailed(eventAppId(), EventReporter::getAppVersion(id()), "Invalid Command.", launchType, launchUniqueId);
503497
safe_sendErrorReply(QDBusError::InternalError, "Invalid Command.");
504498
return {};
505499
}
506500

507501
if (task.LaunchBin.isEmpty()) {
508502
qCritical() << "error command is detected, abort.";
509-
EventReporter::reportAppLaunchFailed(eventAppId(), EventReporter::getAppVersion(id()), "error command is detected, abort.", launchType, launchUniqueId);
510503
safe_sendErrorReply(QDBusError::Failed);
511504
return {};
512505
}
@@ -521,7 +514,7 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
521514
// Generate instance UUID early so splash and job lambda share the same id.
522515
auto instanceRandomUUID = QUuid::createUuid().toString(QUuid::Id128);
523516

524-
EventReporter::reportAppLaunch(eventAppId(), EventReporter::getAppVersion(eventAppId()), QDateTime::currentMSecsSinceEpoch(), launchType, launchUniqueId);
517+
EventReporter::reportAppLaunch(eventAppId(), QDateTime::currentMSecsSinceEpoch(), x_linglong(), launchType, launchUniqueId);
525518

526519
// Notify the compositor to show a splash screen (after validation passes).
527520
if (isAutostartLaunch) {
@@ -614,7 +607,6 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
614607
auto exitCode = process.exitCode();
615608
if (exitCode != 0) {
616609
qWarning() << "Launch Application Failed";
617-
EventReporter::reportAppLaunchFailed(eventAppId(), EventReporter::getAppVersion(eventAppId()), "app-launch-helper exited with code " + QString::number(exitCode), m_launchType, m_launchUniqueId);
618610
return QDBusError::Failed;
619611
}
620612

@@ -1123,8 +1115,6 @@ bool ApplicationService::addOneInstance(const QString &instanceId,
11231115
QVariant::fromValue(interfaces));
11241116
}
11251117

1126-
EventReporter::reportAppLaunchDuration(eventAppId(), EventReporter::getAppVersion(eventAppId()), QDateTime::currentMSecsSinceEpoch(), launchType, uniqueId);
1127-
11281118
return true;
11291119
}
11301120

0 commit comments

Comments
 (0)