File indexing completed on 2024-04-28 16:49:53
0001 /* 0002 SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #include "extended_process_list.h" 0007 0008 #include <KLocalizedString> 0009 #include <KPluginFactory> 0010 #include <KPluginMetaData> 0011 #include <KUser> 0012 0013 #include "process.h" 0014 #include "process_attribute.h" 0015 #include "process_data_provider.h" 0016 #include "processcore_debug.h" 0017 0018 using namespace KSysGuard; 0019 0020 class Q_DECL_HIDDEN ExtendedProcesses::Private 0021 { 0022 public: 0023 Private(ExtendedProcesses *q); 0024 void loadPlugins(); 0025 0026 ExtendedProcesses *q; 0027 QVector<ProcessAttribute *> m_coreAttributes; 0028 QVector<ProcessDataProvider *> m_providers; 0029 QHash<K_UID, KUser> m_userCache; 0030 }; 0031 0032 enum GroupPolicy { Accumulate, Average, ForwardFirstEntry }; 0033 0034 template<class T> 0035 class ProcessSensor : public KSysGuard::ProcessAttribute 0036 { 0037 public: 0038 ProcessSensor(ExtendedProcesses *parent, 0039 const QString &id, 0040 const QString &name, 0041 std::function<T(KSysGuard::Process *)> extractFunc, 0042 KSysGuard::Process::Change changeFlag = KSysGuard::Process::Nothing, 0043 GroupPolicy groupPolicy = Accumulate) 0044 : KSysGuard::ProcessAttribute(id, name, parent) 0045 , m_extractFunc(extractFunc) 0046 , m_changeFlag(changeFlag) 0047 , m_groupPolicy(groupPolicy) 0048 { 0049 if (m_changeFlag != 0) { 0050 connect(parent, &ExtendedProcesses::processChanged, this, [this](KSysGuard::Process *process) { 0051 if (!process->changes().testFlag(m_changeFlag)) { 0052 return; 0053 } 0054 Q_EMIT dataChanged(process); 0055 }); 0056 } 0057 } 0058 0059 QVariant data(KSysGuard::Process *process) const override 0060 { 0061 return QVariant::fromValue(m_extractFunc(process)); 0062 } 0063 0064 QVariant cgroupData(KSysGuard::CGroup *cgroup, const QVector<KSysGuard::Process *> &groupProcesses) const override 0065 { 0066 switch (m_groupPolicy) { 0067 case Accumulate: 0068 return ProcessAttribute::cgroupData(cgroup, groupProcesses); 0069 case Average: 0070 return ProcessAttribute::cgroupData(cgroup, groupProcesses).toDouble() / groupProcesses.size(); 0071 case ForwardFirstEntry: 0072 return groupProcesses.isEmpty() ? QVariant() : data(groupProcesses.first()); 0073 } 0074 Q_UNREACHABLE(); 0075 } 0076 0077 private: 0078 std::function<T(KSysGuard::Process *)> m_extractFunc; 0079 KSysGuard::Process::Change m_changeFlag; 0080 GroupPolicy m_groupPolicy = Accumulate; 0081 }; 0082 0083 ExtendedProcesses::Private::Private(ExtendedProcesses *_q) 0084 : q(_q) 0085 { 0086 } 0087 0088 ExtendedProcesses::ExtendedProcesses(QObject *parent) 0089 : Processes(QString(), parent) 0090 , d(new Private(this)) 0091 { 0092 d->loadPlugins(); 0093 0094 auto pidSensor = 0095 new ProcessSensor<qlonglong>(this, QStringLiteral("pid"), i18n("PID"), &KSysGuard::Process::pid, KSysGuard::Process::Status, ForwardFirstEntry); 0096 pidSensor->setDescription(i18n("The unique Process ID that identifies this process.")); 0097 d->m_coreAttributes << pidSensor; 0098 0099 auto parentPidSensor = new ProcessSensor<qlonglong>(this, 0100 QStringLiteral("parentPid"), 0101 i18n("Parent PID"), 0102 &KSysGuard::Process::parentPid, 0103 Process::Nothing, 0104 ForwardFirstEntry); 0105 d->m_coreAttributes << parentPidSensor; 0106 0107 auto loginSensor = 0108 new ProcessSensor<QString>(this, QStringLiteral("login"), i18n("Login"), &KSysGuard::Process::login, KSysGuard::Process::Login, ForwardFirstEntry); 0109 loginSensor->setDescription(i18n("The user who owns this process.")); 0110 d->m_coreAttributes << loginSensor; 0111 0112 auto uidSensor = 0113 new ProcessSensor<qlonglong>(this, QStringLiteral("uid"), i18n("UID"), &KSysGuard::Process::uid, KSysGuard::Process::Uids, ForwardFirstEntry); 0114 d->m_coreAttributes << uidSensor; 0115 0116 auto userNameSensor = new ProcessSensor<QString>( 0117 this, 0118 QStringLiteral("username"), 0119 i18n("Username"), 0120 [this](KSysGuard::Process *p) { 0121 const K_UID uid = p->uid(); 0122 auto userIt = d->m_userCache.find(uid); 0123 if (userIt == d->m_userCache.end()) { 0124 userIt = d->m_userCache.insert(uid, KUser(uid)); 0125 } 0126 return userIt->loginName(); 0127 }, 0128 KSysGuard::Process::Uids, 0129 ForwardFirstEntry); 0130 d->m_coreAttributes << userNameSensor; 0131 0132 auto canUserLoginSensor = new ProcessSensor<bool>( 0133 this, 0134 QStringLiteral("canUserLogin"), 0135 i18n("Can Login"), 0136 [this](KSysGuard::Process *p) { 0137 const K_UID uid = p->uid(); 0138 if (uid == 65534) { // special value meaning nobody 0139 return false; 0140 } 0141 auto userIt = d->m_userCache.find(uid); 0142 if (userIt == d->m_userCache.end()) { 0143 userIt = d->m_userCache.insert(uid, KUser(uid)); 0144 } 0145 0146 if (!userIt->isValid()) { 0147 // For some reason the user isn't recognised. This might happen under certain security situations. 0148 // Just return true to be safe 0149 return true; 0150 } 0151 const QString shell = userIt->shell(); 0152 if (shell == QLatin1String("/bin/false")) { // FIXME - add in any other shells it could be for false 0153 return false; 0154 } 0155 return true; 0156 }, 0157 KSysGuard::Process::Uids, 0158 ForwardFirstEntry); 0159 d->m_coreAttributes << canUserLoginSensor; 0160 0161 auto euidSensor = 0162 new ProcessSensor<qlonglong>(this, QStringLiteral("euid"), i18n("EUID"), &KSysGuard::Process::euid, KSysGuard::Process::Uids, ForwardFirstEntry); 0163 d->m_coreAttributes << euidSensor; 0164 0165 auto suidSensor = 0166 new ProcessSensor<qlonglong>(this, QStringLiteral("suid"), i18n("suid"), &KSysGuard::Process::suid, KSysGuard::Process::Uids, ForwardFirstEntry); 0167 d->m_coreAttributes << suidSensor; 0168 0169 auto fsuidSensor = 0170 new ProcessSensor<qlonglong>(this, QStringLiteral("fsuid"), i18n("fsuid"), &KSysGuard::Process::fsuid, KSysGuard::Process::Uids, ForwardFirstEntry); 0171 d->m_coreAttributes << fsuidSensor; 0172 0173 auto gidSensor = 0174 new ProcessSensor<qlonglong>(this, QStringLiteral("gid"), i18n("gid"), &KSysGuard::Process::gid, KSysGuard::Process::Gids, ForwardFirstEntry); 0175 d->m_coreAttributes << gidSensor; 0176 0177 auto egidSensor = 0178 new ProcessSensor<qlonglong>(this, QStringLiteral("egid"), i18n("egid"), &KSysGuard::Process::egid, KSysGuard::Process::Gids, ForwardFirstEntry); 0179 d->m_coreAttributes << egidSensor; 0180 0181 auto sgidSensor = 0182 new ProcessSensor<qlonglong>(this, QStringLiteral("sgid"), i18n("sgid"), &KSysGuard::Process::sgid, KSysGuard::Process::Gids, ForwardFirstEntry); 0183 d->m_coreAttributes << sgidSensor; 0184 0185 auto fsgidSensor = 0186 new ProcessSensor<qlonglong>(this, QStringLiteral("fsgid"), i18n("fsgid"), &KSysGuard::Process::fsgid, KSysGuard::Process::Gids, ForwardFirstEntry); 0187 d->m_coreAttributes << fsgidSensor; 0188 0189 auto tracerpidSensor = new ProcessSensor<qlonglong>(this, 0190 QStringLiteral("tracerpid"), 0191 i18n("Tracer Pid"), 0192 &KSysGuard::Process::tracerpid, 0193 Process::Nothing, 0194 ForwardFirstEntry); 0195 d->m_coreAttributes << tracerpidSensor; 0196 0197 auto ttySensor = 0198 new ProcessSensor<QByteArray>(this, QStringLiteral("tty"), i18n("tty"), &KSysGuard::Process::tty, KSysGuard::Process::Tty, ForwardFirstEntry); 0199 ttySensor->setDescription(i18n("The controlling terminal on which this process is running.")); 0200 d->m_coreAttributes << ttySensor; 0201 0202 auto userTimeSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("userTime"), i18n("User Time"), &KSysGuard::Process::userTime); 0203 userTimeSensor->setUnit(KSysGuard::UnitTicks); 0204 d->m_coreAttributes << userTimeSensor; 0205 0206 auto sysTimeSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("sysTime"), i18n("System Time"), &KSysGuard::Process::sysTime); 0207 sysTimeSensor->setUnit(KSysGuard::UnitTicks); 0208 d->m_coreAttributes << sysTimeSensor; 0209 0210 auto timeSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("totalTime"), i18n("Total Time"), [](KSysGuard::Process *p) { 0211 return p->userTime() + p->sysTime(); 0212 }); 0213 timeSensor->setShortName(i18n("Time")); 0214 timeSensor->setUnit(KSysGuard::UnitTicks); 0215 timeSensor->setDescription(i18n("The total user and system time that this process has been running for")); 0216 d->m_coreAttributes << timeSensor; 0217 0218 auto startTimeSensor = new ProcessSensor<qlonglong>(this, 0219 QStringLiteral("startTime"), 0220 i18n("Start Time"), 0221 &KSysGuard::Process::startTime, 0222 Process::Nothing, 0223 ForwardFirstEntry); // Is this correct for apps? 0224 startTimeSensor->setUnit(KSysGuard::UnitBootTimestamp); 0225 d->m_coreAttributes << startTimeSensor; 0226 0227 const int maximumCpuPercent = 100 * numberProcessorCores(); 0228 0229 auto userUsageSensor = 0230 new ProcessSensor<int>(this, QStringLiteral("userUsage"), i18n("User CPU Usage"), &KSysGuard::Process::userUsage, KSysGuard::Process::Usage); 0231 userUsageSensor->setShortName(i18n("User CPU")); 0232 userUsageSensor->setMin(0); 0233 userUsageSensor->setMax(maximumCpuPercent); 0234 userUsageSensor->setUnit(KSysGuard::UnitPercent); 0235 d->m_coreAttributes << userUsageSensor; 0236 0237 auto sysUsageSensor = 0238 new ProcessSensor<int>(this, QStringLiteral("sysUsage"), i18n("System CPU Usage"), &KSysGuard::Process::sysUsage, KSysGuard::Process::Usage); 0239 sysUsageSensor->setShortName(i18n("System CPU")); 0240 sysUsageSensor->setMin(0); 0241 sysUsageSensor->setMax(maximumCpuPercent); 0242 sysUsageSensor->setUnit(KSysGuard::UnitPercent); 0243 d->m_coreAttributes << sysUsageSensor; 0244 0245 auto usageSensor = new ProcessSensor<int>( 0246 this, 0247 QStringLiteral("usage"), 0248 i18n("Total CPU Usage"), 0249 [](KSysGuard::Process *p) { 0250 return p->userUsage() + p->sysUsage(); 0251 }, 0252 KSysGuard::Process::Usage, 0253 Accumulate); 0254 usageSensor->setShortName(i18n("CPU")); 0255 usageSensor->setMin(0); 0256 usageSensor->setMax(maximumCpuPercent); 0257 usageSensor->setUnit(KSysGuard::UnitPercent); 0258 usageSensor->setDescription(i18n("The current total CPU usage of the process.")); 0259 d->m_coreAttributes << usageSensor; 0260 0261 auto totalUserUsageSensor = new ProcessSensor<int>(this, 0262 QStringLiteral("totalUserUsage"), 0263 i18n("Group User CPU Usage"), 0264 &KSysGuard::Process::totalUserUsage, 0265 KSysGuard::Process::TotalUsage, 0266 Average); 0267 totalUserUsageSensor->setDescription(i18n("The amount of userspace CPU used by this process and all its children.")); 0268 totalUserUsageSensor->setMin(0); 0269 totalUserUsageSensor->setMax(maximumCpuPercent); 0270 totalUserUsageSensor->setUnit(KSysGuard::UnitPercent); 0271 d->m_coreAttributes << totalUserUsageSensor; 0272 0273 auto totalSysUsageSensor = new ProcessSensor<int>(this, 0274 QStringLiteral("totalSysUsage"), 0275 i18n("Group System CPU Usage"), 0276 &KSysGuard::Process::totalSysUsage, 0277 KSysGuard::Process::TotalUsage, 0278 Average); 0279 totalUserUsageSensor->setDescription(i18n("The amount of system CPU used by this process and all its children.")); 0280 totalSysUsageSensor->setMin(0); 0281 totalSysUsageSensor->setMax(maximumCpuPercent); 0282 totalSysUsageSensor->setUnit(KSysGuard::UnitPercent); 0283 d->m_coreAttributes << totalSysUsageSensor; 0284 0285 auto totalUsageSensor = new ProcessSensor<int>( 0286 this, 0287 QStringLiteral("totalUsage"), 0288 i18n("Group Total CPU Usage"), 0289 [](KSysGuard::Process *p) { 0290 return p->totalUserUsage() + p->totalSysUsage(); 0291 }, 0292 KSysGuard::Process::TotalUsage, 0293 Average); 0294 totalUsageSensor->setShortName(i18n("Group CPU")); 0295 totalUserUsageSensor->setDescription(i18n("The total amount of CPU used by this process and all its children.")); 0296 totalUsageSensor->setMin(0); 0297 totalUsageSensor->setMax(maximumCpuPercent); 0298 totalUsageSensor->setUnit(KSysGuard::UnitPercent); 0299 d->m_coreAttributes << totalUsageSensor; 0300 0301 auto niceLevelSensor = 0302 new ProcessSensor<int>(this, QStringLiteral("niceLevel"), i18n("Nice Level"), &KSysGuard::Process::niceLevel, KSysGuard::Process::NiceLevels); 0303 niceLevelSensor->setDescription(i18n( 0304 "The priority with which this process is being run. For the normal scheduler, this ranges from 19 (very nice, least priority) to -19 (top priority).")); 0305 d->m_coreAttributes << niceLevelSensor; 0306 0307 auto schedulerSensor = 0308 new ProcessSensor<uint>(this, QStringLiteral("scheduler"), i18n("Scheduler"), &KSysGuard::Process::scheduler, KSysGuard::Process::NiceLevels); 0309 d->m_coreAttributes << schedulerSensor; 0310 0311 auto ioPriorityClassSensor = new ProcessSensor<uint>(this, 0312 QStringLiteral("ioPriorityClass"), 0313 i18n("IO Priority Class"), 0314 &KSysGuard::Process::ioPriorityClass, 0315 KSysGuard::Process::NiceLevels); 0316 d->m_coreAttributes << ioPriorityClassSensor; 0317 0318 auto ioniceLevelSensor = 0319 new ProcessSensor<int>(this, QStringLiteral("ioniceLevel"), i18n("IO Nice Level"), &KSysGuard::Process::ioniceLevel, KSysGuard::Process::NiceLevels); 0320 ioniceLevelSensor->setUnit(KSysGuard::UnitNone); 0321 d->m_coreAttributes << ioniceLevelSensor; 0322 0323 auto vmSizeSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("vmSize"), i18n("VM Size"), &KSysGuard::Process::vmSize, KSysGuard::Process::VmSize); 0324 vmSizeSensor->setUnit(KSysGuard::UnitKiloByte); 0325 vmSizeSensor->setMin(0); 0326 vmSizeSensor->setMax(totalPhysicalMemory()); 0327 vmSizeSensor->setDescription( 0328 i18n("This is the amount of virtual memory space that the process is using, included shared libraries, graphics memory, files on disk, and so on. This " 0329 "number is almost meaningless.")); 0330 d->m_coreAttributes << vmSizeSensor; 0331 0332 auto vmRSSSensor = 0333 new ProcessSensor<qlonglong>(this, QStringLiteral("vmRSS"), i18n("RSS Memory Usage"), &KSysGuard::Process::vmRSS, KSysGuard::Process::VmRSS); 0334 vmRSSSensor->setUnit(KSysGuard::UnitKiloByte); 0335 vmRSSSensor->setMin(0); 0336 vmRSSSensor->setMax(totalPhysicalMemory()); 0337 vmRSSSensor->setDescription( 0338 i18n("This is the amount of physical memory that this process is using and includes the amount of memory used by shared libraries.")); 0339 0340 auto vmURSSSensor = 0341 new ProcessSensor<qlonglong>(this, QStringLiteral("vmURSS"), i18n("Private Memory Usage"), &KSysGuard::Process::vmURSS, KSysGuard::Process::VmURSS); 0342 vmURSSSensor->setUnit(KSysGuard::UnitKiloByte); 0343 vmURSSSensor->setShortName(i18n("Private")); 0344 vmURSSSensor->setMin(0); 0345 vmURSSSensor->setMax(totalPhysicalMemory()); 0346 vmURSSSensor->setDescription( 0347 i18n("This is the amount of physical memory that this process is using by itself, and approximates the Private memory usage of the process.<br>It does " 0348 "not include any swapped out memory, nor the code size of its shared libraries.")); 0349 d->m_coreAttributes << vmURSSSensor; 0350 0351 auto sharedMemorySensor = new ProcessSensor<qlonglong>( 0352 this, 0353 QStringLiteral("vmShared"), 0354 i18n("Shared Memory Usage"), 0355 [](KSysGuard::Process *p) -> qlonglong { 0356 if (p->vmRSS() - p->vmURSS() < 0 || p->vmURSS() == -1) { 0357 return 0; 0358 } 0359 return (qlonglong)(p->vmRSS() - p->vmURSS()); 0360 }, 0361 KSysGuard::Process::VmRSS); 0362 d->m_coreAttributes << sharedMemorySensor; 0363 sharedMemorySensor->setShortName(i18n("Shared")); 0364 sharedMemorySensor->setDescription( 0365 i18n("This is approximately the amount of real physical memory that this process's shared libraries are using.<br>This memory is shared among all " 0366 "processes that use this library.")); 0367 sharedMemorySensor->setUnit(KSysGuard::UnitKiloByte); 0368 sharedMemorySensor->setMin(0); 0369 sharedMemorySensor->setMax(totalPhysicalMemory()); 0370 0371 auto vmPSSSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("vmPSS"), i18n("Memory Usage"), &KSysGuard::Process::vmPSS, KSysGuard::Process::VmPSS); 0372 vmPSSSensor->setShortName(i18n("Memory")); 0373 vmPSSSensor->setUnit(KSysGuard::UnitKiloByte); 0374 vmPSSSensor->setMin(0); 0375 vmPSSSensor->setMax(totalPhysicalMemory()); 0376 vmPSSSensor->setRequiredUpdateFlags(Processes::Smaps); 0377 vmPSSSensor->setDescription( 0378 i18n("This is an approximation of the real amount of physical memory that this process is using. It is calculated by dividing the process' shared " 0379 "memory usage by the amount of processes sharing that memory, then adding the process' private memory.")); 0380 d->m_coreAttributes << vmPSSSensor; 0381 0382 auto nameSensor = 0383 new ProcessSensor<QString>(this, QStringLiteral("name"), i18n("Name"), &KSysGuard::Process::name, KSysGuard::Process::Name, ForwardFirstEntry); 0384 nameSensor->setDescription(i18n("The process name.")); 0385 d->m_coreAttributes << nameSensor; 0386 0387 auto commandSensor = new ProcessSensor<QString>(this, 0388 QStringLiteral("command"), 0389 i18n("Command"), 0390 &KSysGuard::Process::command, 0391 KSysGuard::Process::Command, 0392 ForwardFirstEntry); 0393 commandSensor->setDescription(i18n("The command with which this process was launched.")); 0394 d->m_coreAttributes << commandSensor; 0395 0396 auto statusSensor = 0397 new ProcessSensor<QString>(this, QStringLiteral("status"), i18n("Status"), &KSysGuard::Process::translatedStatus, KSysGuard::Process::Status); 0398 d->m_coreAttributes << statusSensor; 0399 0400 auto ioCharactersReadSensor = new ProcessSensor<qlonglong>(this, 0401 QStringLiteral("ioCharactersRead"), 0402 i18n("IO Characters Read"), 0403 &KSysGuard::Process::ioCharactersRead, 0404 KSysGuard::Process::IO); 0405 ioCharactersReadSensor->setUnit(KSysGuard::UnitByte); 0406 ioCharactersReadSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0407 d->m_coreAttributes << ioCharactersReadSensor; 0408 0409 auto ioCharactersWrittenSensor = new ProcessSensor<qlonglong>(this, 0410 QStringLiteral("ioCharactersWritten"), 0411 i18n("IO Characters Written"), 0412 &KSysGuard::Process::ioCharactersWritten, 0413 KSysGuard::Process::IO); 0414 ioCharactersWrittenSensor->setUnit(KSysGuard::UnitByte); 0415 ioCharactersWrittenSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0416 d->m_coreAttributes << ioCharactersWrittenSensor; 0417 0418 auto ioReadSyscallsSensor = new ProcessSensor<qlonglong>(this, 0419 QStringLiteral("ioReadSyscalls"), 0420 i18n("IO Read Syscalls"), 0421 &KSysGuard::Process::ioReadSyscalls, 0422 KSysGuard::Process::IO); 0423 ioReadSyscallsSensor->setUnit(KSysGuard::UnitRate); 0424 ioReadSyscallsSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0425 d->m_coreAttributes << ioReadSyscallsSensor; 0426 0427 auto ioReadSyscallsRateSensor = new ProcessSensor<qlonglong>(this, 0428 QStringLiteral("ioReadSyscallsRate"), 0429 i18n("IO Read Syscalls Rate"), 0430 &KSysGuard::Process::ioReadSyscallsRate, 0431 KSysGuard::Process::IO); 0432 ioReadSyscallsRateSensor->setUnit(KSysGuard::UnitRate); 0433 ioReadSyscallsRateSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0434 d->m_coreAttributes << ioReadSyscallsSensor; 0435 0436 auto ioWriteSyscallsSensor = new ProcessSensor<qlonglong>(this, 0437 QStringLiteral("ioWriteSyscalls"), 0438 i18n("IO Write Syscalls"), 0439 &KSysGuard::Process::ioWriteSyscalls, 0440 KSysGuard::Process::IO); 0441 ioWriteSyscallsSensor->setUnit(KSysGuard::UnitRate); 0442 ioWriteSyscallsSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0443 d->m_coreAttributes << ioWriteSyscallsSensor; 0444 0445 auto ioWriteSyscallsRateSensor = new ProcessSensor<qlonglong>(this, 0446 QStringLiteral("ioReadSyscallsRate"), 0447 i18n("IO Write Syscalls Rate"), 0448 &KSysGuard::Process::ioWriteSyscallsRate, 0449 KSysGuard::Process::IO); 0450 ioWriteSyscallsRateSensor->setUnit(KSysGuard::UnitRate); 0451 ioWriteSyscallsRateSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0452 d->m_coreAttributes << ioWriteSyscallsRateSensor; 0453 0454 auto ioCharactersActuallyReadSensor = new ProcessSensor<qlonglong>(this, 0455 QStringLiteral("ioCharactersActuallyRead"), 0456 i18n("IO Characters Actually Read"), 0457 &KSysGuard::Process::ioCharactersActuallyRead, 0458 KSysGuard::Process::IO); 0459 ioCharactersActuallyReadSensor->setUnit(KSysGuard::UnitByte); 0460 ioCharactersActuallyReadSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0461 d->m_coreAttributes << ioCharactersActuallyReadSensor; 0462 0463 auto ioCharactersReadRateSensor = new ProcessSensor<qlonglong>(this, 0464 QStringLiteral("ioCharactersReadRate"), 0465 i18n("IO Characters Read Rate"), 0466 &KSysGuard::Process::ioCharactersReadRate, 0467 KSysGuard::Process::IO); 0468 ioCharactersReadRateSensor->setDescription(i18n("The read rate for all of a process' IO, including disk cache and other nonphysical IO.")); 0469 ioCharactersReadRateSensor->setUnit(KSysGuard::UnitByteRate); 0470 ioCharactersReadRateSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0471 d->m_coreAttributes << ioCharactersReadRateSensor; 0472 0473 auto ioCharactersWrittenRateSensor = new ProcessSensor<qlonglong>(this, 0474 QStringLiteral("ioCharactersWrittenRate"), 0475 i18n("IO Characters Written Rate"), 0476 &KSysGuard::Process::ioCharactersWrittenRate, 0477 KSysGuard::Process::IO); 0478 ioCharactersWrittenRateSensor->setDescription(i18n("The write rate for all of a process' IO, including disk cache and other nonphysical IO.")); 0479 ioCharactersWrittenRateSensor->setUnit(KSysGuard::UnitByteRate); 0480 ioCharactersWrittenRateSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0481 d->m_coreAttributes << ioCharactersWrittenRateSensor; 0482 0483 auto ioCharactersActuallyReadRateSensor = new ProcessSensor<qlonglong>(this, 0484 QStringLiteral("ioCharactersActuallyReadRate"), 0485 i18n("Disk Read Rate"), 0486 &KSysGuard::Process::ioCharactersActuallyReadRate, 0487 KSysGuard::Process::IO); 0488 ioCharactersActuallyReadRateSensor->setUnit(KSysGuard::UnitByteRate); 0489 ioCharactersActuallyReadRateSensor->setShortName(i18n("Read")); 0490 ioCharactersActuallyReadRateSensor->setDescription(i18n("The rate of data being read from disk.")); 0491 ioCharactersActuallyReadRateSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0492 d->m_coreAttributes << ioCharactersActuallyReadRateSensor; 0493 0494 auto ioCharactersActuallyWrittenRateSensor = new ProcessSensor<qlonglong>(this, 0495 QStringLiteral("ioCharactersActuallyWrittenRate"), 0496 i18n("Disk Write Rate"), 0497 &KSysGuard::Process::ioCharactersActuallyWrittenRate, 0498 KSysGuard::Process::IO); 0499 ioCharactersActuallyWrittenRateSensor->setUnit(KSysGuard::UnitByteRate); 0500 ioCharactersActuallyWrittenRateSensor->setShortName(i18n("Write")); 0501 ioCharactersActuallyWrittenRateSensor->setDescription(i18n("The rate of data being written to the disk.")); 0502 ioCharactersActuallyWrittenRateSensor->setRequiredUpdateFlags(Processes::IOStatistics); 0503 d->m_coreAttributes << ioCharactersActuallyWrittenRateSensor; 0504 0505 auto numThreadsSensor = new ProcessSensor<int>(this, 0506 QStringLiteral("numThreads"), 0507 i18n("Threads"), 0508 &KSysGuard::Process::numThreads, 0509 KSysGuard::Process::NumThreads, 0510 ForwardFirstEntry); 0511 d->m_coreAttributes << numThreadsSensor; 0512 0513 connect(this, &KSysGuard::Processes::beginRemoveProcess, this, [this](KSysGuard::Process *process) { 0514 const auto attrs = attributes(); 0515 for (auto a : attrs) { 0516 a->clearData(process); 0517 } 0518 }); 0519 0520 connect(this, &KSysGuard::Processes::updated, this, [this]() { 0521 for (auto p : std::as_const(d->m_providers)) { 0522 if (p->enabled()) { 0523 p->update(); 0524 } 0525 } 0526 }); 0527 } 0528 0529 ExtendedProcesses::~ExtendedProcesses() 0530 { 0531 } 0532 0533 QVector<ProcessAttribute *> ExtendedProcesses::attributes() const 0534 { 0535 return d->m_coreAttributes + extendedAttributes(); 0536 } 0537 0538 QVector<ProcessAttribute *> ExtendedProcesses::extendedAttributes() const 0539 { 0540 QVector<ProcessAttribute *> rc; 0541 for (auto p : std::as_const(d->m_providers)) { 0542 rc << p->attributes(); 0543 } 0544 return rc; 0545 } 0546 0547 void ExtendedProcesses::Private::loadPlugins() 0548 { 0549 const QVector<KPluginMetaData> listMetaData = KPluginMetaData::findPlugins(QStringLiteral("ksysguard/process")); 0550 // instantiate all plugins 0551 for (const auto &pluginMetaData : listMetaData) { 0552 qCDebug(LIBKSYSGUARD_PROCESSCORE) << "loading plugin" << pluginMetaData.name(); 0553 auto provider = KPluginFactory::instantiatePlugin<ProcessDataProvider>(pluginMetaData, q); 0554 if (!provider.plugin) { 0555 qCCritical(LIBKSYSGUARD_PROCESSCORE) << "failed to instantiate ProcessDataProvider" << pluginMetaData.name(); 0556 continue; 0557 } 0558 m_providers << provider.plugin; 0559 } 0560 } 0561 0562 QSharedPointer<ExtendedProcesses> ExtendedProcesses::instance() 0563 { 0564 static QWeakPointer<ExtendedProcesses> instance; 0565 auto processes = instance.lock(); 0566 if (!processes) { 0567 processes = QSharedPointer<ExtendedProcesses>(new ExtendedProcesses, [](ExtendedProcesses *p) { 0568 delete p; 0569 }); 0570 instance = processes; 0571 } 0572 return processes; 0573 }