From 89551ddfc2879530981eba3db9ab857b88409ad8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 20 Sep 2008 11:59:36 +0200 Subject: Lese /proc/loadavg f?r weitere Statusinformationen aus --- src/Client/CommandParser.cpp | 3 +- src/Common/Backends/SystemBackendProc.cpp | 20 +++++++++++ src/Common/Backends/SystemBackendProc.h | 4 ++- .../RequestHandlers/StatusRequestHandler.cpp | 3 +- src/Common/SystemBackend.h | 14 ++++++++ src/Net/Packets/HostListPacket.h | 7 ++++ src/Net/Packets/HostStatusPacket.cpp | 31 ++++++++++++++--- src/Net/Packets/HostStatusPacket.h | 40 +++++++++++++++++++--- 8 files changed, 109 insertions(+), 13 deletions(-) diff --git a/src/Client/CommandParser.cpp b/src/Client/CommandParser.cpp index 34c7e4f..ccf5a74 100644 --- a/src/Client/CommandParser.cpp +++ b/src/Client/CommandParser.cpp @@ -74,8 +74,7 @@ void CommandParser::printHostStatus(const Net::Packets::HostStatusPacket &packet std::printf("%lu:%02lu", hours, minutes); - if(packet.getIdleTime()) - std::printf(" (load average: %.1f%%)", 100.0f-(packet.getIdleTime()*100.0f/packet.getUptime())); + std::printf(" (load average: %.2f %.2f %.2f, %lu processes)", packet.getLoadAverage1(), packet.getLoadAverage5(), packet.getLoadAverage15(), (unsigned long)packet.getProcessNumber()); std::printf("\n\n"); } diff --git a/src/Common/Backends/SystemBackendProc.cpp b/src/Common/Backends/SystemBackendProc.cpp index f2d9152..51e14f8 100644 --- a/src/Common/Backends/SystemBackendProc.cpp +++ b/src/Common/Backends/SystemBackendProc.cpp @@ -20,6 +20,7 @@ #include "SystemBackendProc.h" #include +#include namespace Mad { namespace Common { @@ -86,6 +87,25 @@ SystemBackend::MemoryInfo SystemBackendProc::getMemoryInfo() { return memInfo; } +SystemBackend::LoadInfo SystemBackendProc::getLoadInfo() { + LoadInfo loadInfo = {0, 0, 0, 0, 0}; + + loadFile.seekg(0, std::ios::beg); + + if(!loadFile.good()) + return loadInfo; + + std::string line; + std::getline(loadFile, line); + + if(line.empty()) + return loadInfo; + + std::sscanf(line.c_str(), "%f %f %f %lu/%lu", &loadInfo.loadAvg1, &loadInfo.loadAvg5, &loadInfo.loadAvg15, &loadInfo.currentLoad, &loadInfo.nProcesses); + + return loadInfo; +} + } } } diff --git a/src/Common/Backends/SystemBackendProc.h b/src/Common/Backends/SystemBackendProc.h index fb9ecf5..8caa080 100644 --- a/src/Common/Backends/SystemBackendProc.h +++ b/src/Common/Backends/SystemBackendProc.h @@ -32,8 +32,9 @@ class SystemBackendProc : public SystemBackend { private: std::ifstream uptimeFile; std::ifstream meminfoFile; + std::ifstream loadFile; - SystemBackendProc() : uptimeFile("/proc/uptime"), meminfoFile("/proc/meminfo") {} + SystemBackendProc() : uptimeFile("/proc/uptime"), meminfoFile("/proc/meminfo"), loadFile("/proc/loadavg") {} public: static void useBackend() { @@ -42,6 +43,7 @@ class SystemBackendProc : public SystemBackend { virtual UptimeInfo getUptimeInfo(); virtual MemoryInfo getMemoryInfo(); + virtual LoadInfo getLoadInfo(); }; } diff --git a/src/Common/RequestHandlers/StatusRequestHandler.cpp b/src/Common/RequestHandlers/StatusRequestHandler.cpp index a3f8675..6280ab3 100644 --- a/src/Common/RequestHandlers/StatusRequestHandler.cpp +++ b/src/Common/RequestHandlers/StatusRequestHandler.cpp @@ -41,9 +41,10 @@ void StatusRequestHandler::handlePacket(Net::Connection *connection, const Net:: SystemBackend::UptimeInfo uptimeInfo = SystemBackend::getBackend()->getUptimeInfo(); SystemBackend::MemoryInfo memInfo = SystemBackend::getBackend()->getMemoryInfo(); + SystemBackend::LoadInfo loadInfo = SystemBackend::getBackend()->getLoadInfo(); connection->send(Net::Packets::HostStatusPacket(Net::Packet::OK, packet.getRequestId(), uptimeInfo.uptime, uptimeInfo.idleTime, - memInfo.totalMem, memInfo.freeMem, memInfo.totalSwap, memInfo.freeSwap)); + memInfo.totalMem, memInfo.freeMem, memInfo.totalSwap, memInfo.freeSwap, loadInfo.currentLoad, loadInfo.nProcesses, loadInfo.loadAvg1, loadInfo.loadAvg5, loadInfo.loadAvg15)); signalFinished().emit(); } diff --git a/src/Common/SystemBackend.h b/src/Common/SystemBackend.h index 9157e07..8ba1e7d 100644 --- a/src/Common/SystemBackend.h +++ b/src/Common/SystemBackend.h @@ -21,6 +21,7 @@ #define MAD_COMMON_SYSTEMBACKEND_H_ #include +#include #include namespace Mad { @@ -50,6 +51,14 @@ class SystemBackend { unsigned long freeSwap; }; + struct LoadInfo { + unsigned long currentLoad; + unsigned long nProcesses; + float loadAvg1; + float loadAvg5; + float loadAvg15; + }; + virtual ~SystemBackend() {} virtual UptimeInfo getUptimeInfo() { @@ -62,6 +71,11 @@ class SystemBackend { return ret; } + virtual LoadInfo getLoadInfo() { + LoadInfo ret = {0, 0, 0, 0, 0}; + return ret; + } + static SystemBackend *getBackend() { return backend.get(); } diff --git a/src/Net/Packets/HostListPacket.h b/src/Net/Packets/HostListPacket.h index aba6461..4d0b2d0 100644 --- a/src/Net/Packets/HostListPacket.h +++ b/src/Net/Packets/HostListPacket.h @@ -61,6 +61,13 @@ class HostListPacket : public Packet { return *this; } + HostListPacket& operator=(const HostListPacket &p) { + Packet::operator=(p); + parsePacket(); + + return *this; + } + const std::vector& getHostInfo() const { return hostList; } diff --git a/src/Net/Packets/HostStatusPacket.cpp b/src/Net/Packets/HostStatusPacket.cpp index 3e50cd6..f998c2c 100644 --- a/src/Net/Packets/HostStatusPacket.cpp +++ b/src/Net/Packets/HostStatusPacket.cpp @@ -19,16 +19,24 @@ #include "HostStatusPacket.h" +#include +#include +#include + namespace Mad { namespace Net { namespace Packets { HostStatusPacket::HostStatusPacket(Type type, uint16_t requestId, uint32_t uptime, uint32_t idleTime, - uint32_t totalMem, uint32_t freeMem, uint32_t totalSwap, uint32_t freeSwap) -: Packet(type, requestId) + uint32_t totalMem, uint32_t freeMem, uint32_t totalSwap, uint32_t freeSwap, + uint32_t currentLoad, uint32_t nProcesses, float loadAvg1val, float loadAvg5val, float loadAvg15val) +: Packet(type, requestId), loadAvg1(loadAvg1val), loadAvg5(loadAvg5val), loadAvg15(loadAvg15val) { - setLength(sizeof(CoreStatusData)); + char buf[20]; + std::snprintf(buf, sizeof(buf), "%.2f %.2f %.2f", loadAvg1, loadAvg5, loadAvg15); + + setLength(sizeof(CoreStatusData) + strlen(buf)); coreStatusData = (CoreStatusData*)&rawData->data; coreStatusData->uptime = htonl(uptime); @@ -38,17 +46,30 @@ HostStatusPacket::HostStatusPacket(Type type, uint16_t requestId, uint32_t uptim coreStatusData->freeMem = htonl(freeMem); coreStatusData->totalSwap = htonl(totalSwap); coreStatusData->freeSwap = htonl(freeSwap); + + coreStatusData->currentLoad = htonl(currentLoad); + coreStatusData->nProcesses = htonl(nProcesses); + + std::memcpy(coreStatusData->charData, buf, strlen(buf)); } HostStatusPacket& HostStatusPacket::operator=(const Packet &p) { Packet::operator=(p); - - setLength(sizeof(CoreStatusData)); + if(getLength() < sizeof(CoreStatusData)) + setLength(sizeof(CoreStatusData)); coreStatusData = (CoreStatusData*)&rawData->data; + parsePacket(); + return *this; } +void HostStatusPacket::parsePacket() { + coreStatusData = (CoreStatusData*)&rawData->data; + + std::sscanf(std::string((char*)coreStatusData->charData, getLength()-sizeof(coreStatusData)).c_str(), "%f %f %f", &loadAvg1, &loadAvg5, &loadAvg15); +} + } } } diff --git a/src/Net/Packets/HostStatusPacket.h b/src/Net/Packets/HostStatusPacket.h index 0de63de..fa0910c 100644 --- a/src/Net/Packets/HostStatusPacket.h +++ b/src/Net/Packets/HostStatusPacket.h @@ -36,21 +36,33 @@ class HostStatusPacket : public Packet { uint32_t freeMem; uint32_t totalSwap; uint32_t freeSwap; + + uint32_t currentLoad; + uint32_t nProcesses; + + uint8_t charData[0]; }; CoreStatusData *coreStatusData; + float loadAvg1, loadAvg5, loadAvg15; + + void parsePacket(); + public: HostStatusPacket(Type type, uint16_t requestId, uint32_t uptime = 0, uint32_t idleTime = 0, - uint32_t totalMem = 0, uint32_t freeMem = 0, uint32_t totalSwap = 0, uint32_t freeSwap = 0); + uint32_t totalMem = 0, uint32_t freeMem = 0, uint32_t totalSwap = 0, uint32_t freeSwap = 0, + uint32_t currentLoad = 0, uint32_t nProcesses = 0, float loadAvg1val = 0, float loadAvg5val = 0, float loadAvg15val = 0); HostStatusPacket(const Packet &p) : Packet(p) { - setLength(sizeof(CoreStatusData)); - coreStatusData = (CoreStatusData*)&rawData->data; + if(getLength() < sizeof(CoreStatusData)) + setLength(sizeof(CoreStatusData)); + + parsePacket(); } HostStatusPacket(const HostStatusPacket &p) : Packet(p) { - coreStatusData = (CoreStatusData*)&rawData->data; + parsePacket(); } HostStatusPacket& operator=(const Packet &p); @@ -82,6 +94,26 @@ class HostStatusPacket : public Packet { uint32_t getFreeSwap() const { return ntohl(coreStatusData->freeSwap); } + + uint32_t getCurrentLoad() const { + return ntohl(coreStatusData->currentLoad); + } + + uint32_t getProcessNumber() const { + return ntohl(coreStatusData->nProcesses); + } + + float getLoadAverage1() const { + return loadAvg1; + } + + float getLoadAverage5() const { + return loadAvg5; + } + + float getLoadAverage15() const { + return loadAvg15; + } }; } -- cgit v1.2.3