Skip to content

Commit 98c4bd2

Browse files
authored
Merge pull request #7 from Acik-Kaynak-Gelistirme-Toplulugu/fix/system-monitors
feat: implement system monitors (CPU, GPU, RAM)
2 parents 5cbedec + 7aac727 commit 98c4bd2

6 files changed

Lines changed: 306 additions & 13 deletions

File tree

src/backend/monitor/cpumonitor.cpp

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,91 @@
1-
// CPU istatistikleri
2-
31
#include "cpumonitor.h"
42

3+
#include <QFile>
4+
#include <QTextStream>
5+
#include <QDir>
6+
57
CpuMonitor::CpuMonitor(QObject *parent)
68
: QObject(parent)
7-
{}
9+
{
10+
connect(&m_timer, &QTimer::timeout, this, &CpuMonitor::poll);
11+
}
12+
13+
void CpuMonitor::start(int intervalMs)
14+
{
15+
poll();
16+
m_timer.start(intervalMs);
17+
}
18+
19+
void CpuMonitor::stop()
20+
{
21+
m_timer.stop();
22+
}
23+
24+
void CpuMonitor::poll()
25+
{
26+
// ── CPU Yükü (/proc/stat) ────────────────────────────────────────────────
27+
// /proc/stat ilk satırı: "cpu user nice system idle iowait irq softirq..."
28+
QFile statFile(QStringLiteral("/proc/stat"));
29+
if (statFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
30+
QTextStream stream(&statFile);
31+
const QString line = stream.readLine(); // "cpu ..." satırı
32+
33+
const QStringList parts = line.split(QLatin1Char(' '), Qt::SkipEmptyParts);
34+
if (parts.size() >= 5) {
35+
// idle = index 4, total = tüm değerlerin toplamı
36+
long long idle = parts[4].toLongLong();
37+
long long total = 0;
38+
for (int i = 1; i < parts.size(); ++i)
39+
total += parts[i].toLongLong();
40+
41+
// Delta ile yük hesapla
42+
const long long diffIdle = idle - m_prevIdle;
43+
const long long diffTotal = total - m_prevTotal;
44+
45+
if (diffTotal > 0) {
46+
const int load = static_cast<int>(100 * (1.0 - static_cast<double>(diffIdle) / diffTotal));
47+
if (load != m_load) {
48+
m_load = load;
49+
emit loadChanged();
50+
}
51+
}
52+
53+
m_prevIdle = idle;
54+
m_prevTotal = total;
55+
}
56+
}
57+
58+
// ── CPU Sıcaklığı (hwmon) ────────────────────────────────────────────────
59+
const int temp = readCpuTemp();
60+
if (temp > 0 && temp != m_temperature) {
61+
m_temperature = temp;
62+
emit temperatureChanged();
63+
}
64+
}
65+
66+
int CpuMonitor::readCpuTemp() const
67+
{
68+
// /sys/class/hwmon/ altındaki sıcaklık sensörlerini tara
69+
const QDir hwmonDir(QStringLiteral("/sys/class/hwmon"));
70+
const QStringList hwmons = hwmonDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
71+
72+
for (const QString &hwmon : hwmons) {
73+
const QString namePath = hwmonDir.filePath(hwmon + QStringLiteral("/name"));
74+
QFile nameFile(namePath);
75+
if (!nameFile.open(QIODevice::ReadOnly))
76+
continue;
77+
78+
const QString name = QString::fromUtf8(nameFile.readAll()).trimmed();
79+
80+
// k10temp (AMD) veya coretemp (Intel) sensörü
81+
if (name == QStringLiteral("k10temp") || name == QStringLiteral("coretemp")) {
82+
QFile tempFile(hwmonDir.filePath(hwmon + QStringLiteral("/temp1_input")));
83+
if (tempFile.open(QIODevice::ReadOnly)) {
84+
const int milliCelsius = QString::fromUtf8(tempFile.readAll()).trimmed().toInt();
85+
return milliCelsius / 1000; // milli-Celsius → Celsius
86+
}
87+
}
88+
}
89+
90+
return 0;
91+
}

src/backend/monitor/cpumonitor.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,40 @@
11
#pragma once
22

33
#include <QObject>
4+
#include <QTimer>
45

5-
// Gerçek zamanlı CPU istatistikleri
6+
// CpuMonitor: /proc/stat üzerinden gerçek zamanlı CPU istatistikleri.
67
class CpuMonitor : public QObject
78
{
89
Q_OBJECT
910

11+
Q_PROPERTY(int load READ load NOTIFY loadChanged)
12+
Q_PROPERTY(int temperature READ temperature NOTIFY temperatureChanged)
13+
1014
public:
1115
explicit CpuMonitor(QObject *parent = nullptr);
16+
17+
int load() const { return m_load; }
18+
int temperature() const { return m_temperature; }
19+
20+
Q_INVOKABLE void start(int intervalMs = 1000);
21+
Q_INVOKABLE void stop();
22+
23+
signals:
24+
void loadChanged();
25+
void temperatureChanged();
26+
27+
private slots:
28+
void poll();
29+
30+
private:
31+
int readCpuTemp() const;
32+
33+
QTimer m_timer;
34+
int m_load = 0;
35+
int m_temperature = 0;
36+
37+
// /proc/stat için önceki değerler (delta hesabı)
38+
long long m_prevIdle = 0;
39+
long long m_prevTotal = 0;
1240
};

src/backend/monitor/gpumonitor.cpp

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,78 @@
1-
// GPU istatistikleri
2-
31
#include "gpumonitor.h"
2+
#include "system/commandrunner.h"
43

54
GpuMonitor::GpuMonitor(QObject *parent)
65
: QObject(parent)
7-
{}
6+
{
7+
connect(&m_timer, &QTimer::timeout, this, &GpuMonitor::poll);
8+
}
9+
10+
void GpuMonitor::start(int intervalMs)
11+
{
12+
poll(); // İlk veriyi hemen al
13+
m_timer.start(intervalMs);
14+
}
15+
16+
void GpuMonitor::stop()
17+
{
18+
m_timer.stop();
19+
}
20+
21+
void GpuMonitor::poll()
22+
{
23+
CommandRunner runner;
24+
25+
// nvidia-smi'den tek seferde tüm değerleri çek
26+
// Çıktı formatı: "temperature,utilization,vram_used,vram_total"
27+
const auto result = runner.run(
28+
QStringLiteral("nvidia-smi"),
29+
{
30+
QStringLiteral("--query-gpu=temperature.gpu,utilization.gpu,memory.used,memory.total"),
31+
QStringLiteral("--format=csv,noheader,nounits")
32+
}
33+
);
34+
35+
if (!result.success()) {
36+
if (m_available) {
37+
m_available = false;
38+
emit availableChanged();
39+
}
40+
return;
41+
}
42+
43+
// "72, 45, 2048, 8192" formatını parse et
44+
const QStringList parts = result.stdout.trimmed().split(QStringLiteral(", "));
45+
if (parts.size() < 4)
46+
return;
47+
48+
bool ok = false;
49+
50+
const int temp = parts[0].trimmed().toInt(&ok);
51+
if (ok && temp != m_temperature) {
52+
m_temperature = temp;
53+
emit temperatureChanged();
54+
}
55+
56+
const int load = parts[1].trimmed().toInt(&ok);
57+
if (ok && load != m_load) {
58+
m_load = load;
59+
emit loadChanged();
60+
}
61+
62+
const int vramUsed = parts[2].trimmed().toInt(&ok);
63+
if (ok && vramUsed != m_vramUsed) {
64+
m_vramUsed = vramUsed;
65+
emit vramUsedChanged();
66+
}
67+
68+
const int vramTotal = parts[3].trimmed().toInt(&ok);
69+
if (ok && vramTotal != m_vramTotal) {
70+
m_vramTotal = vramTotal;
71+
emit vramTotalChanged();
72+
}
73+
74+
if (!m_available) {
75+
m_available = true;
76+
emit availableChanged();
77+
}
78+
}

src/backend/monitor/gpumonitor.h

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,51 @@
11
#pragma once
22

33
#include <QObject>
4+
#include <QTimer>
45

5-
// Gerçek zamanlı GPU istatistikleri
6+
// GpuMonitor: nvidia-smi üzerinden gerçek zamanlı GPU istatistikleri.
7+
// QML bu sınıfın property'lerine bağlanır — otomatik güncellenir.
68
class GpuMonitor : public QObject
79
{
810
Q_OBJECT
911

12+
// QML'den okunabilir property'ler
13+
Q_PROPERTY(int temperature READ temperature NOTIFY temperatureChanged)
14+
Q_PROPERTY(int load READ load NOTIFY loadChanged)
15+
Q_PROPERTY(int vramUsed READ vramUsed NOTIFY vramUsedChanged)
16+
Q_PROPERTY(int vramTotal READ vramTotal NOTIFY vramTotalChanged)
17+
Q_PROPERTY(bool available READ available NOTIFY availableChanged)
18+
1019
public:
1120
explicit GpuMonitor(QObject *parent = nullptr);
12-
};
21+
22+
int temperature() const { return m_temperature; }
23+
int load() const { return m_load; }
24+
int vramUsed() const { return m_vramUsed; }
25+
int vramTotal() const { return m_vramTotal; }
26+
bool available() const { return m_available; }
27+
28+
// Polling'i başlat/durdur (ms cinsinden interval)
29+
Q_INVOKABLE void start(int intervalMs = 1000);
30+
Q_INVOKABLE void stop();
31+
32+
signals:
33+
void temperatureChanged();
34+
void loadChanged();
35+
void vramUsedChanged();
36+
void vramTotalChanged();
37+
void availableChanged();
38+
39+
private slots:
40+
void poll();
41+
42+
private:
43+
QTimer m_timer;
44+
45+
int m_temperature = 0;
46+
int m_load = 0;
47+
int m_vramUsed = 0;
48+
int m_vramTotal = 0;
49+
bool m_available = false;
50+
};
51+

src/backend/monitor/rammonitor.cpp

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,52 @@
1-
// RAM istatistikleri
2-
31
#include "rammonitor.h"
42

3+
#include <QFile>
4+
#include <QTextStream>
5+
56
RamMonitor::RamMonitor(QObject *parent)
67
: QObject(parent)
7-
{}
8+
{
9+
connect(&m_timer, &QTimer::timeout, this, &RamMonitor::poll);
10+
}
11+
12+
void RamMonitor::start(int intervalMs)
13+
{
14+
poll();
15+
m_timer.start(intervalMs);
16+
}
17+
18+
void RamMonitor::stop()
19+
{
20+
m_timer.stop();
21+
}
22+
23+
void RamMonitor::poll()
24+
{
25+
// /proc/meminfo formatı: "MemTotal: 16384000 kB"
26+
QFile memFile(QStringLiteral("/proc/meminfo"));
27+
if (!memFile.open(QIODevice::ReadOnly | QIODevice::Text))
28+
return;
29+
30+
long long memTotal = 0, memAvailable = 0;
31+
32+
QTextStream stream(&memFile);
33+
while (!stream.atEnd()) {
34+
const QString line = stream.readLine();
35+
if (line.startsWith(QStringLiteral("MemTotal:")))
36+
memTotal = line.split(QLatin1Char(' '), Qt::SkipEmptyParts)[1].toLongLong();
37+
else if (line.startsWith(QStringLiteral("MemAvailable:")))
38+
memAvailable = line.split(QLatin1Char(' '), Qt::SkipEmptyParts)[1].toLongLong();
39+
}
40+
41+
if (memTotal <= 0)
42+
return;
43+
44+
// kB → MB
45+
const int totalMb = static_cast<int>(memTotal / 1024);
46+
const int usedMb = static_cast<int>((memTotal - memAvailable) / 1024);
47+
const int percent = static_cast<int>(100.0 * usedMb / totalMb);
48+
49+
if (totalMb != m_totalMb) { m_totalMb = totalMb; emit totalMbChanged(); }
50+
if (usedMb != m_usedMb) { m_usedMb = usedMb; emit usedMbChanged(); }
51+
if (percent != m_usedPercent) { m_usedPercent = percent; emit usedPercentChanged(); }
52+
}

src/backend/monitor/rammonitor.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,38 @@
11
#pragma once
22

33
#include <QObject>
4+
#include <QTimer>
45

5-
// Gerçek zamanlı RAM istatistikleri
6+
// RamMonitor: /proc/meminfo üzerinden RAM kullanımı.
67
class RamMonitor : public QObject
78
{
89
Q_OBJECT
910

11+
Q_PROPERTY(int totalMb READ totalMb NOTIFY totalMbChanged)
12+
Q_PROPERTY(int usedMb READ usedMb NOTIFY usedMbChanged)
13+
Q_PROPERTY(int usedPercent READ usedPercent NOTIFY usedPercentChanged)
14+
1015
public:
1116
explicit RamMonitor(QObject *parent = nullptr);
17+
18+
int totalMb() const { return m_totalMb; }
19+
int usedMb() const { return m_usedMb; }
20+
int usedPercent() const { return m_usedPercent; }
21+
22+
Q_INVOKABLE void start(int intervalMs = 2000);
23+
Q_INVOKABLE void stop();
24+
25+
signals:
26+
void totalMbChanged();
27+
void usedMbChanged();
28+
void usedPercentChanged();
29+
30+
private slots:
31+
void poll();
32+
33+
private:
34+
QTimer m_timer;
35+
int m_totalMb = 0;
36+
int m_usedMb = 0;
37+
int m_usedPercent = 0;
1238
};

0 commit comments

Comments
 (0)