diff --git a/src/metrics/Collector.cpp b/src/metrics/Collector.cpp index 2ab0c65..22ed9af 100644 --- a/src/metrics/Collector.cpp +++ b/src/metrics/Collector.cpp @@ -2,17 +2,45 @@ #include #include +#include #include #include #include #include #include +#include namespace metrics { Collector::Collector(const std::vector> &disks) : disks(disks) { + std::vector cpuLogicalIds; + for (const auto &cpuDir : std::filesystem::directory_iterator("/sys/devices/system/cpu")) + { + std::string name = cpuDir.path().filename().string(); + if (name.find("cpu") != 0) + continue; + std::string suffix = name.substr(3); + if (!std::all_of(suffix.begin(), suffix.end(), ::isdigit)) + continue; + cpuLogicalIds.push_back(std::stoi(suffix)); + } + + std::sort(cpuLogicalIds.begin(), cpuLogicalIds.end()); + + // строим логическое → физическое + logicalToPhysical.resize(cpuLogicalIds.size()); + for (size_t i = 0; i < cpuLogicalIds.size(); ++i) + { + int cpu = cpuLogicalIds[i]; + std::ifstream f("/sys/devices/system/cpu/cpu" + std::to_string(cpu) + "/topology/core_id"); + if (!f) + throw std::runtime_error("Cannot read core_id for cpu" + std::to_string(cpu)); + int coreId; + f >> coreId; + logicalToPhysical[i] = coreId; + } } Host Collector::collect() @@ -32,6 +60,7 @@ namespace metrics prevCpu = curCpu; + host.cpu.coreTemps = readCpuCoreTemps(); host.memory = readMemory(); for (const std::vector &disk : disks) host.disks.push_back(readDisk(disk)); @@ -72,6 +101,47 @@ namespace metrics return out; } + std::vector Collector::readCpuCoreTemps() + { + std::vector physTemps; + std::vector logicTemps(logicalToPhysical.size()); + + for (const auto &hwmon : std::filesystem::directory_iterator("/sys/class/hwmon")) + { + std::string name; + std::ifstream nameFile(hwmon.path() / "name"); + if (nameFile) + std::getline(nameFile, name); + + // проверяем на CPU + if (name != "coretemp" && name != "k10temp") + continue; + + // читаем все temp*_input + for (const auto &f : std::filesystem::directory_iterator(hwmon)) + { + std::string fname = f.path().filename(); + if (fname.find("temp") == 0 && fname.find("_input") != std::string::npos) + { + int millideg = 0; + std::ifstream tempFile(f.path()); + tempFile >> millideg; + physTemps.push_back(millideg / 1000.0f); // °C + } + } + + for (size_t i = 0; i < logicalToPhysical.size(); ++i) + { + int phys = logicalToPhysical[i]; + if (phys >= static_cast(physTemps.size())) + phys = physTemps.size() - 1; // safety + logicTemps[i] = physTemps[phys]; + } + } + + return logicTemps; + } + float Collector::cpuLoad(const Collector::CpuTimes &prev, const Collector::CpuTimes &cur) { diff --git a/src/metrics/Collector.h b/src/metrics/Collector.h index c4585a3..f16404a 100644 --- a/src/metrics/Collector.h +++ b/src/metrics/Collector.h @@ -22,10 +22,12 @@ namespace metrics }; std::pair> prevCpu; + std::vector logicalToPhysical; std::pair> readCpuTimes(); const std::vector> disks; float cpuLoad(const CpuTimes &prev, const CpuTimes &cur); + std::vector readCpuCoreTemps(); Memory readMemory(); Disk readDisk(const std::vector &disk = {"R", "/"}); void readLoad(float &l1, float &l5, float &l15); diff --git a/src/metrics/Cpu.h b/src/metrics/Cpu.h index 8321617..93e59b6 100644 --- a/src/metrics/Cpu.h +++ b/src/metrics/Cpu.h @@ -7,5 +7,6 @@ namespace metrics { float totalLoad; std::vector coreLoads; // длина = num_cores + std::vector coreTemps; }; } // namespace metrics \ No newline at end of file diff --git a/src/metrics/Host.cpp b/src/metrics/Host.cpp index 0631310..fad836f 100644 --- a/src/metrics/Host.cpp +++ b/src/metrics/Host.cpp @@ -39,6 +39,8 @@ namespace metrics buf.writeUint8(static_cast(cpu.coreLoads.size())); for (float f : cpu.coreLoads) buf.writeFloat(f); + for (float f : cpu.coreTemps) + buf.writeFloat(f); // Memory buf.writeUint64(memory.memory.used); @@ -81,6 +83,10 @@ namespace metrics h.cpu.coreLoads.reserve(numCpu); for (uint8_t i = 0; i < numCpu; ++i) h.cpu.coreLoads.push_back(buf.readFloat()); + h.cpu.coreTemps.clear(); + h.cpu.coreTemps.reserve(numCpu); + for (uint8_t i = 0; i < numCpu; ++i) + h.cpu.coreTemps.push_back(buf.readFloat()); // Memory h.memory.memory.used = buf.readUint64();