Add core temperatures

This commit is contained in:
2025-12-29 16:44:22 +00:00
parent 8a0d2e8bdc
commit 0f4cb0eaaf
4 changed files with 79 additions and 0 deletions
+70
View File
@@ -2,17 +2,45 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <filesystem>
#include <sys/statvfs.h> #include <sys/statvfs.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h> #include <limits.h>
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
#include <algorithm>
namespace metrics namespace metrics
{ {
Collector::Collector(const std::vector<std::vector<std::string>> &disks) : disks(disks) Collector::Collector(const std::vector<std::vector<std::string>> &disks) : disks(disks)
{ {
std::vector<int> 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() Host Collector::collect()
@@ -32,6 +60,7 @@ namespace metrics
prevCpu = curCpu; prevCpu = curCpu;
host.cpu.coreTemps = readCpuCoreTemps();
host.memory = readMemory(); host.memory = readMemory();
for (const std::vector<std::string> &disk : disks) for (const std::vector<std::string> &disk : disks)
host.disks.push_back(readDisk(disk)); host.disks.push_back(readDisk(disk));
@@ -72,6 +101,47 @@ namespace metrics
return out; return out;
} }
std::vector<float> Collector::readCpuCoreTemps()
{
std::vector<float> physTemps;
std::vector<float> 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<int>(physTemps.size()))
phys = physTemps.size() - 1; // safety
logicTemps[i] = physTemps[phys];
}
}
return logicTemps;
}
float Collector::cpuLoad(const Collector::CpuTimes &prev, float Collector::cpuLoad(const Collector::CpuTimes &prev,
const Collector::CpuTimes &cur) const Collector::CpuTimes &cur)
{ {
+2
View File
@@ -22,10 +22,12 @@ namespace metrics
}; };
std::pair<CpuTimes, std::vector<CpuTimes>> prevCpu; std::pair<CpuTimes, std::vector<CpuTimes>> prevCpu;
std::vector<int> logicalToPhysical;
std::pair<CpuTimes, std::vector<CpuTimes>> readCpuTimes(); std::pair<CpuTimes, std::vector<CpuTimes>> readCpuTimes();
const std::vector<std::vector<std::string>> disks; const std::vector<std::vector<std::string>> disks;
float cpuLoad(const CpuTimes &prev, const CpuTimes &cur); float cpuLoad(const CpuTimes &prev, const CpuTimes &cur);
std::vector<float> readCpuCoreTemps();
Memory readMemory(); Memory readMemory();
Disk readDisk(const std::vector<std::string> &disk = {"R", "/"}); Disk readDisk(const std::vector<std::string> &disk = {"R", "/"});
void readLoad(float &l1, float &l5, float &l15); void readLoad(float &l1, float &l5, float &l15);
+1
View File
@@ -7,5 +7,6 @@ namespace metrics
{ {
float totalLoad; float totalLoad;
std::vector<float> coreLoads; // длина = num_cores std::vector<float> coreLoads; // длина = num_cores
std::vector<float> coreTemps;
}; };
} // namespace metrics } // namespace metrics
+6
View File
@@ -39,6 +39,8 @@ namespace metrics
buf.writeUint8(static_cast<uint8_t>(cpu.coreLoads.size())); buf.writeUint8(static_cast<uint8_t>(cpu.coreLoads.size()));
for (float f : cpu.coreLoads) for (float f : cpu.coreLoads)
buf.writeFloat(f); buf.writeFloat(f);
for (float f : cpu.coreTemps)
buf.writeFloat(f);
// Memory // Memory
buf.writeUint64(memory.memory.used); buf.writeUint64(memory.memory.used);
@@ -81,6 +83,10 @@ namespace metrics
h.cpu.coreLoads.reserve(numCpu); h.cpu.coreLoads.reserve(numCpu);
for (uint8_t i = 0; i < numCpu; ++i) for (uint8_t i = 0; i < numCpu; ++i)
h.cpu.coreLoads.push_back(buf.readFloat()); 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 // Memory
h.memory.memory.used = buf.readUint64(); h.memory.memory.used = buf.readUint64();