File indexing completed on 2024-05-05 17:39:48
0001 /* 0002 KSysGuard, the KDE System Guard 0003 0004 SPDX-FileCopyrightText: 1999-2001 Chris Schlaeger <cs@kde.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0007 0008 */ 0009 0010 #include "ksgrd_debug.h" 0011 #include <QCoreApplication> 0012 #include <QDebug> 0013 #include <kconfiggroup.h> 0014 #include <klocalizedstring.h> 0015 0016 #include "SensorShellAgent.h" 0017 #include "SensorSocketAgent.h" 0018 0019 #include "SensorManager.h" 0020 0021 using namespace KSGRD; 0022 0023 SensorManager::MessageEvent::MessageEvent(const QString &message) 0024 : QEvent(QEvent::User) 0025 , mMessage(message) 0026 { 0027 } 0028 0029 QString SensorManager::MessageEvent::message() const 0030 { 0031 return mMessage; 0032 } 0033 0034 SensorManager *KSGRD::SensorMgr; 0035 0036 SensorManager::SensorManager(QObject *parent) 0037 : QObject(parent) 0038 { 0039 retranslate(); 0040 } 0041 int SensorManager::count() const 0042 { 0043 return mAgents.count(); 0044 } 0045 void SensorManager::retranslate() 0046 { 0047 // Fill the sensor description dictionary. 0048 mDict.clear(); 0049 mDict.insert(QStringLiteral("Delta"), i18n("Change")); 0050 mDict.insert(QStringLiteral("Rate"), i18n("Rate")); 0051 0052 mDict.insert(QStringLiteral("cpu"), i18n("CPU Load")); 0053 mDict.insert(QStringLiteral("idle"), i18n("Idling")); 0054 mDict.insert(QStringLiteral("nice"), i18n("Nice Load")); 0055 mDict.insert(QStringLiteral("user"), i18n("User Load")); 0056 mDict.insert(QStringLiteral("sys"), i18nc("@item sensor description", "System Load")); 0057 mDict.insert(QStringLiteral("wait"), i18n("Waiting")); 0058 mDict.insert(QStringLiteral("intr"), i18n("Interrupt Load")); 0059 mDict.insert(QStringLiteral("TotalLoad"), i18n("Total Load")); 0060 0061 mDict.insert(QStringLiteral("mem"), i18n("Memory")); 0062 mDict.insert(QStringLiteral("physical"), i18n("Physical Memory")); 0063 mDict.insert(QStringLiteral("total"), i18n("Total Memory")); 0064 mDict.insert(QStringLiteral("swap"), i18n("Swap Memory")); 0065 mDict.insert(QStringLiteral("cached"), i18n("Cached Memory")); 0066 mDict.insert(QStringLiteral("buf"), i18n("Buffered Memory")); 0067 mDict.insert(QStringLiteral("used"), i18n("Used Memory")); 0068 mDict.insert(QStringLiteral("application"), i18n("Application Memory")); 0069 mDict.insert(QStringLiteral("allocated"), i18n("Allocated Memory")); 0070 mDict.insert(QStringLiteral("free"), i18n("Free Memory")); 0071 mDict.insert(QStringLiteral("available"), i18n("Available Memory")); 0072 mDict.insert(QStringLiteral("active"), i18n("Active Memory")); 0073 mDict.insert(QStringLiteral("inactive"), i18n("Inactive Memory")); 0074 mDict.insert(QStringLiteral("wired"), i18n("Wired Memory")); 0075 mDict.insert(QStringLiteral("execpages"), i18n("Exec Pages")); 0076 mDict.insert(QStringLiteral("filepages"), i18n("File Pages")); 0077 0078 /* Processes */ 0079 mDict.insert(QStringLiteral("processes"), i18n("Processes")); 0080 mDict.insert(QStringLiteral("ps"), i18n("Process Controller")); 0081 mDict.insert(QStringLiteral("lastpid"), i18n("Last Process ID")); 0082 mDict.insert(QStringLiteral("procspawn"), i18n("Process Spawn Count")); 0083 mDict.insert(QStringLiteral("pscount"), i18n("Process Count")); 0084 mDict.insert(QStringLiteral("psidle"), i18n("Idle Processes Count")); 0085 mDict.insert(QStringLiteral("psrun"), i18n("Running Processes Count")); 0086 mDict.insert(QStringLiteral("pssleep"), i18n("Sleeping Processes Count")); 0087 mDict.insert(QStringLiteral("psstop"), i18n("Stopped Processes Count")); 0088 mDict.insert(QStringLiteral("pszombie"), i18n("Zombie Processes Count")); 0089 mDict.insert(QStringLiteral("pswait"), i18n("Waiting Processes Count")); 0090 mDict.insert(QStringLiteral("pslock"), i18n("Locked Processes Count")); 0091 0092 mDict.insert(QStringLiteral("disk"), i18n("Disk Throughput")); 0093 mDict.insert(QStringLiteral("load"), i18nc("CPU Load", "Load")); 0094 mDict.insert(QStringLiteral("totalio"), i18n("Total Accesses")); 0095 mDict.insert(QStringLiteral("rio"), i18n("Read Accesses")); 0096 mDict.insert(QStringLiteral("wio"), i18n("Write Accesses")); 0097 mDict.insert(QStringLiteral("rblk"), i18n("Read Data")); 0098 mDict.insert(QStringLiteral("wblk"), i18n("Written Data")); 0099 mDict.insert(QStringLiteral("rtim"), i18n("Milliseconds spent reading")); 0100 mDict.insert(QStringLiteral("wtim"), i18n("Milliseconds spent writing")); 0101 mDict.insert(QStringLiteral("ioqueue"), i18n("I/Os currently in progress")); 0102 mDict.insert(QStringLiteral("pageIn"), i18n("Pages In")); 0103 mDict.insert(QStringLiteral("pageOut"), i18n("Pages Out")); 0104 mDict.insert(QStringLiteral("context"), i18n("Context Switches")); 0105 mDict.insert(QStringLiteral("trap"), i18n("Traps")); 0106 mDict.insert(QStringLiteral("syscall"), i18n("System Calls")); 0107 mDict.insert(QStringLiteral("network"), i18n("Network")); 0108 mDict.insert(QStringLiteral("interfaces"), i18n("Interfaces")); 0109 mDict.insert(QStringLiteral("receiver"), i18n("Receiver")); 0110 mDict.insert(QStringLiteral("transmitter"), i18n("Transmitter")); 0111 0112 mDict.insert(QStringLiteral("data"), i18n("Data Rate")); 0113 mDict.insert(QStringLiteral("compressed"), i18n("Compressed Packets Rate")); 0114 mDict.insert(QStringLiteral("drops"), i18n("Dropped Packets Rate")); 0115 mDict.insert(QStringLiteral("errors"), i18n("Error Rate")); 0116 mDict.insert(QStringLiteral("fifo"), i18n("FIFO Overruns Rate")); 0117 mDict.insert(QStringLiteral("frame"), i18n("Frame Error Rate")); 0118 mDict.insert(QStringLiteral("multicast"), i18n("Multicast Packet Rate")); 0119 mDict.insert(QStringLiteral("packets"), i18n("Packet Rate")); 0120 mDict.insert(QStringLiteral("carrier"), i18nc("@item sensor description ('carrier' is a type of network signal)", "Carrier Loss Rate")); 0121 mDict.insert(QStringLiteral("collisions"), i18n("Collisions")); 0122 0123 mDict.insert(QStringLiteral("dataTotal"), i18n("Data")); 0124 mDict.insert(QStringLiteral("compressedTotal"), i18n("Compressed Packets")); 0125 mDict.insert(QStringLiteral("dropsTotal"), i18n("Dropped Packets")); 0126 mDict.insert(QStringLiteral("errorsTotal"), i18n("Errors")); 0127 mDict.insert(QStringLiteral("fifoTotal"), i18n("FIFO Overruns")); 0128 mDict.insert(QStringLiteral("frameTotal"), i18n("Frame Errors")); 0129 mDict.insert(QStringLiteral("multicastTotal"), i18n("Multicast Packets")); 0130 mDict.insert(QStringLiteral("packetsTotal"), i18n("Packets")); 0131 mDict.insert(QStringLiteral("carrierTotal"), i18nc("@item sensor description ('carrier' is a type of network signal)", "Carrier Losses")); 0132 mDict.insert(QStringLiteral("collisionsTotal"), i18n("Collisions")); 0133 0134 /* Hardware monitors */ 0135 mDict.insert(QStringLiteral("sockets"), i18n("Sockets")); 0136 mDict.insert(QStringLiteral("count"), i18n("Total Number")); 0137 mDict.insert(QStringLiteral("list"), i18n("Table")); 0138 mDict.insert(QStringLiteral("apm"), i18n("Advanced Power Management")); 0139 mDict.insert(QStringLiteral("acpi"), i18n("ACPI")); 0140 mDict.insert(QStringLiteral("Cooling_Device"), i18n("Cooling Device")); 0141 mDict.insert(QStringLiteral("Current_State"), i18n("Current State")); 0142 mDict.insert(QStringLiteral("thermal_zone"), i18n("Thermal Zone")); 0143 mDict.insert(QStringLiteral("Thermal_Zone"), i18n("Thermal Zone")); 0144 mDict.insert(QStringLiteral("temperature"), i18n("Temperature")); 0145 mDict.insert(QStringLiteral("Temperature"), i18n("Temperature")); 0146 mDict.insert(QStringLiteral("AverageTemperature"), i18n("Average CPU Temperature")); 0147 mDict.insert(QStringLiteral("fan"), i18n("Fan")); 0148 mDict.insert(QStringLiteral("state"), i18n("State")); 0149 mDict.insert(QStringLiteral("battery"), i18n("Battery")); 0150 mDict.insert(QStringLiteral("batterycapacity"), i18n("Battery Capacity")); 0151 mDict.insert(QStringLiteral("batterycharge"), i18n("Battery Charge")); 0152 mDict.insert(QStringLiteral("batteryusage"), i18n("Battery Usage")); 0153 mDict.insert(QStringLiteral("batteryvoltage"), i18n("Battery Voltage")); 0154 mDict.insert(QStringLiteral("batteryrate"), i18n("Battery Discharge Rate")); 0155 mDict.insert(QStringLiteral("remainingtime"), i18n("Remaining Time")); 0156 mDict.insert(QStringLiteral("interrupts"), i18n("Interrupts")); 0157 mDict.insert(QStringLiteral("loadavg1"), i18n("Load Average (1 min)")); 0158 mDict.insert(QStringLiteral("loadavg5"), i18n("Load Average (5 min)")); 0159 mDict.insert(QStringLiteral("loadavg15"), i18n("Load Average (15 min)")); 0160 mDict.insert(QStringLiteral("clock"), i18n("Clock Frequency")); 0161 mDict.insert(QStringLiteral("AverageClock"), i18n("Average Clock Frequency")); 0162 mDict.insert(QStringLiteral("lmsensors"), i18n("Hardware Sensors")); 0163 mDict.insert(QStringLiteral("partitions"), i18n("Partition Usage")); 0164 mDict.insert(QStringLiteral("usedspace"), i18n("Used Space")); 0165 mDict.insert(QStringLiteral("freespace"), i18n("Free Space")); 0166 mDict.insert(QStringLiteral("filllevel"), i18n("Fill Level")); 0167 mDict.insert(QStringLiteral("usedinode"), i18n("Used Inodes")); 0168 mDict.insert(QStringLiteral("freeinode"), i18n("Free Inodes")); 0169 mDict.insert(QStringLiteral("inodelevel"), i18n("Inode Level")); 0170 mDict.insert(QStringLiteral("system"), i18n("System")); 0171 mDict.insert(QStringLiteral("uptime"), i18n("Uptime")); 0172 mDict.insert(QStringLiteral("SoftRaid"), i18n("Linux Soft Raid (md)")); 0173 mDict.insert(QStringLiteral("processors"), i18n("Processors")); 0174 mDict.insert(QStringLiteral("cores"), i18n("Cores")); 0175 mDict.insert(QStringLiteral("NumBlocks"), i18n("Number of Blocks")); 0176 mDict.insert(QStringLiteral("TotalDevices"), i18n("Total Number of Devices")); 0177 mDict.insert(QStringLiteral("FailedDevices"), i18n("Failed Devices")); 0178 mDict.insert(QStringLiteral("SpareDevices"), i18n("Spare Devices")); 0179 mDict.insert(QStringLiteral("NumRaidDevices"), i18n("Number of Raid Devices")); 0180 mDict.insert(QStringLiteral("WorkingDevices"), i18n("Working Devices")); 0181 mDict.insert(QStringLiteral("ActiveDevices"), i18n("Active Devices")); 0182 mDict.insert(QStringLiteral("DeviceNumber"), i18n("Number of Devices")); 0183 mDict.insert(QStringLiteral("ResyncingPercent"), i18n("Resyncing Percent")); 0184 mDict.insert(QStringLiteral("DiskInfo"), i18n("Disk Information")); 0185 mDict.insert(QStringLiteral("CPUTIN"), i18n("CPU Temperature")); 0186 mDict.insert(QStringLiteral("SYSTIN"), i18n("Motherboard Temperature")); 0187 mDict.insert(QStringLiteral("AUXTIN"), i18n("Power Supply Temperature")); 0188 0189 mDict.insert(QStringLiteral("__root__"), i18n("Filesystem Root")); 0190 0191 for (int i = 0; i < 5; i++) { 0192 mDict.insert(QLatin1String("AUXTIN") + QString::number(i), i18n("Extra Temperature Sensor %1", i + 1)); 0193 } 0194 0195 for (int i = 0; i < 3; i++) { 0196 mDict.insert(QLatin1String("PECI Agent ") + QString::number(i), i18n("PECI Temperature Sensor %1", i + 1)); 0197 mDict.insert(QLatin1String("PECI Agent %1 Calibration").arg(QString::number(i)), i18n("PECI Temperature Calibration %1", i + 1)); 0198 } 0199 0200 for (int i = 0; i < 32; i++) { 0201 mDict.insert(QLatin1String("cpu") + QString::number(i), i18n("CPU %1", i + 1)); 0202 mDict.insert(QLatin1String("disk") + QString::number(i), i18n("Disk %1", i + 1)); 0203 } 0204 0205 for (int i = 1; i < 10; i++) { 0206 mDict.insert(QLatin1String("batt") + QString::number(i), i18n("Battery %1", i)); 0207 mDict.insert(QLatin1String("fan") + QString::number(i), i18n("Fan %1", i)); 0208 mDict.insert(QLatin1String("temp") + QString::number(i), i18n("Temperature %1", i)); 0209 } 0210 0211 mDict.insert(QStringLiteral("int00"), i18n("Total")); 0212 mDict.insert(QStringLiteral("softint"), i18n("Software Interrupts")); 0213 mDict.insert(QStringLiteral("hardint"), i18n("Hardware Interrupts")); 0214 0215 QString num; 0216 for (int i = 1; i < 25; i++) { 0217 num = QString::asprintf("%.2d", i); 0218 mDict.insert(QLatin1String("int") + num, ki18n("Int %1").subs(i - 1, 3).toString()); 0219 num = QString::asprintf("%.3d", i + 255); 0220 mDict.insert(QLatin1String("int") + num, ki18n("Int %1").subs(i + 255, 4).toString()); 0221 } 0222 0223 mDict.insert(QStringLiteral("quality"), i18n("Link Quality")); 0224 mDict.insert(QStringLiteral("signal"), i18n("Signal Level")); 0225 mDict.insert(QStringLiteral("noise"), i18n("Noise Level")); 0226 mDict.insert(QStringLiteral("nwid"), i18n("Rx Invalid Nwid Packets")); 0227 mDict.insert(QStringLiteral("nwidTotal"), i18n("Total Rx Invalid Nwid Packets")); 0228 mDict.insert(QStringLiteral("crypt"), i18n("Rx Invalid Crypt Packets")); 0229 mDict.insert(QStringLiteral("cryptTotal"), i18n("Total Rx Invalid Crypt Packets")); 0230 mDict.insert(QStringLiteral("frag"), i18n("Rx Invalid Frag Packets")); 0231 mDict.insert(QStringLiteral("fragTotal"), i18n("Total Rx Invalid Frag Packets")); 0232 mDict.insert(QStringLiteral("retry"), i18n("Tx Excessive Retries Packets")); 0233 mDict.insert(QStringLiteral("retryTotal"), i18n("Total Tx Excessive Retries Packets")); 0234 mDict.insert(QStringLiteral("misc"), i18n("Invalid Misc Packets")); 0235 mDict.insert(QStringLiteral("miscTotal"), i18n("Total Invalid Misc Packets")); 0236 mDict.insert(QStringLiteral("beacon"), i18n("Missed Beacons")); 0237 mDict.insert(QStringLiteral("beaconTotal"), i18n("Total Missed Beacons")); 0238 0239 mDict.insert(QStringLiteral("logfiles"), i18n("Log Files")); 0240 0241 // TODO: translated descriptions not yet implemented. 0242 mUnits.clear(); 0243 mUnits.insert(QStringLiteral("1/s"), i18nc("the unit 1 per second", "1/s")); 0244 mUnits.insert(QStringLiteral("kBytes"), i18n("kBytes")); 0245 mUnits.insert(QStringLiteral("min"), i18nc("the unit minutes", "min")); 0246 mUnits.insert(QStringLiteral("MHz"), i18nc("the frequency unit", "MHz")); 0247 mUnits.insert(QStringLiteral("%"), i18nc("a percentage", "%")); 0248 mUnits.insert(QStringLiteral("mA"), i18nc("the unit milliamperes", "mA")); 0249 mUnits.insert(QStringLiteral("mAh"), i18nc("the unit milliampere hours", "mAh")); 0250 mUnits.insert(QStringLiteral("mW"), i18nc("the unit milliwatts", "mW")); 0251 mUnits.insert(QStringLiteral("mWh"), i18nc("the unit milliwatt hours", "mWh")); 0252 mUnits.insert(QStringLiteral("mV"), i18nc("the unit millivolts", "mV")); 0253 0254 mTypes.clear(); 0255 mTypes.insert(QStringLiteral("integer"), i18n("Integer Value")); 0256 mTypes.insert(QStringLiteral("float"), i18n("Floating Point Value")); 0257 mTypes.insert(QStringLiteral("table"), i18n("Process Controller")); 0258 mTypes.insert(QStringLiteral("listview"), i18n("Table")); 0259 mTypes.insert(QStringLiteral("logfile"), i18n("Log File")); 0260 0261 mBroadcaster = nullptr; 0262 } 0263 0264 SensorManager::~SensorManager() 0265 { 0266 } 0267 0268 bool SensorManager::engage(const QString &hostName, const QString &shell, const QString &command, int port) 0269 { 0270 if (!mAgents.contains(hostName)) { 0271 SensorAgent *agent = nullptr; 0272 0273 if (port == -1) 0274 agent = new SensorShellAgent(this); 0275 else 0276 agent = new SensorSocketAgent(this); 0277 0278 if (!agent->start(hostName.toLatin1(), shell, command, port)) { 0279 delete agent; 0280 return false; 0281 } 0282 0283 mAgents.insert(hostName, agent); 0284 connect(agent, &SensorAgent::reconfigure, this, &SensorManager::reconfigure); 0285 0286 Q_EMIT hostAdded(agent, hostName); 0287 return true; 0288 } 0289 0290 return false; 0291 } 0292 0293 bool SensorManager::disengage(SensorAgent *agent) 0294 { 0295 if (!agent) 0296 return false; 0297 const QString key = mAgents.key(const_cast<SensorAgent *>(agent)); 0298 return disengage(key); 0299 } 0300 0301 bool SensorManager::isConnected(const QString &hostName) 0302 { 0303 return mAgents.contains(hostName); 0304 } 0305 bool SensorManager::disengage(const QString &hostName) 0306 { 0307 if (mAgents.contains(hostName)) { 0308 mAgents.take(hostName)->deleteLater(); 0309 0310 Q_EMIT hostConnectionLost(hostName); 0311 return true; 0312 } 0313 0314 return false; 0315 } 0316 0317 bool SensorManager::resynchronize(const QString &hostName) 0318 { 0319 const SensorAgent *agent = mAgents.value(hostName); 0320 0321 if (!agent) 0322 return false; 0323 0324 QString shell, command; 0325 int port; 0326 hostInfo(hostName, shell, command, port); 0327 0328 mAgents.remove(hostName); 0329 0330 qCDebug(LIBKSYSGUARD_KSGRD) << "Re-synchronizing connection to " << hostName; 0331 0332 return engage(hostName, shell, command); 0333 } 0334 0335 void SensorManager::notify(const QString &msg) const 0336 { 0337 /* This function relays text messages to the toplevel widget that 0338 * displays the message in a pop-up box. It must be used for objects 0339 * that might have been deleted before the pop-up box is closed. */ 0340 if (mBroadcaster) { 0341 MessageEvent *event = new MessageEvent(msg); 0342 qApp->postEvent(mBroadcaster, event); 0343 } 0344 } 0345 0346 void SensorManager::setBroadcaster(QObject *wdg) 0347 { 0348 mBroadcaster = wdg; 0349 } 0350 0351 void SensorManager::reconfigure(const SensorAgent *) 0352 { 0353 Q_EMIT update(); 0354 } 0355 0356 bool SensorManager::sendRequest(const QString &hostName, const QString &req, SensorClient *client, int id) 0357 { 0358 SensorAgent *agent = mAgents.value(hostName); 0359 if (!agent && hostName == QLatin1String("localhost")) { 0360 // we should always be able to reconnect to localhost 0361 engage(QStringLiteral("localhost"), QLatin1String(""), QStringLiteral("ksysguardd"), -1); 0362 agent = mAgents.value(hostName); 0363 } 0364 if (agent) { 0365 agent->sendRequest(req, client, id); 0366 return true; 0367 } 0368 0369 return false; 0370 } 0371 0372 const QString SensorManager::hostName(const SensorAgent *agent) const 0373 { 0374 return mAgents.key(const_cast<SensorAgent *>(agent)); 0375 } 0376 0377 bool SensorManager::hostInfo(const QString &hostName, QString &shell, QString &command, int &port) 0378 { 0379 const SensorAgent *agent = mAgents.value(hostName); 0380 if (agent) { 0381 agent->hostInfo(shell, command, port); 0382 return true; 0383 } 0384 0385 return false; 0386 } 0387 0388 QString SensorManager::translateUnit(const QString &unit) const 0389 { 0390 if (!unit.isEmpty() && mUnits.contains(unit)) 0391 return mUnits[unit]; 0392 else 0393 return unit; 0394 } 0395 0396 QString SensorManager::translateSensorPath(const QString &path) const 0397 { 0398 if (!path.isEmpty() && mDict.contains(path)) 0399 return mDict[path]; 0400 else 0401 return path; 0402 } 0403 0404 QString SensorManager::translateSensorType(const QString &type) const 0405 { 0406 if (!type.isEmpty() && mTypes.contains(type)) 0407 return mTypes[type]; 0408 else 0409 return type; 0410 } 0411 0412 QString SensorManager::translateSensor(const QString &sensor) const 0413 { 0414 QString out; 0415 int start = 0, end = 0; 0416 for (;;) { 0417 end = sensor.indexOf(QLatin1Char('/'), start); 0418 if (end > 0) 0419 out += translateSensorPath(sensor.mid(start, end - start)) + QLatin1Char('/'); 0420 else { 0421 out += translateSensorPath(sensor.right(sensor.length() - start)); 0422 break; 0423 } 0424 start = end + 1; 0425 } 0426 0427 return out; 0428 } 0429 0430 void SensorManager::readProperties(const KConfigGroup &cfg) 0431 { 0432 mHostList = cfg.readEntry("HostList", QStringList()); 0433 mCommandList = cfg.readEntry("CommandList", QStringList()); 0434 } 0435 0436 void SensorManager::saveProperties(KConfigGroup &cfg) 0437 { 0438 cfg.writeEntry("HostList", mHostList); 0439 cfg.writeEntry("CommandList", mCommandList); 0440 } 0441 0442 void SensorManager::disconnectClient(SensorClient *client) 0443 { 0444 QHashIterator<QString, SensorAgent *> it(mAgents); 0445 0446 while (it.hasNext()) 0447 it.next().value()->disconnectClient(client); 0448 }