15#include <sys/statvfs.h>
23 struct SystemMetricsLinuxHelper {
24 static int FindPid(
const String& sProcessName) {
26 auto arrMatches = Process::GetProcessesByName(sProcessName);
27 if (arrMatches.GetLength() > 0)
return arrMatches[0]->GetId();
31 static MemoryInfo ReadMem(
int iPid) {
34 if (iPid <= 0)
return info;
35 std::ifstream f(
"/proc/" + std::to_string(iPid) +
"/status");
36 std::string line;
long long rss = 0, vm = 0;
37 while (f.is_open() && std::getline(f, line)) {
38 if (line.rfind(
"VmRSS:", 0) == 0) std::istringstream(line.substr(6)) >> rss;
39 else if (line.rfind(
"VmSize:", 0) == 0) std::istringstream(line.substr(7)) >> vm;
41 info.lPhysicalMemoryBytes = rss * 1024LL; info.lPrivateBytes = vm * 1024LL;
45 static DiskInfo ReadDisk(
int iPid) {
48 if (iPid <= 0)
return info;
49 std::ifstream f(
"/proc/" + std::to_string(iPid) +
"/io");
51 while (f.is_open() && std::getline(f, line)) {
52 if (line.rfind(
"read_bytes:", 0) == 0) std::istringstream(line.substr(11)) >> info.lDiskReadBytes;
53 else if (line.rfind(
"write_bytes:", 0) == 0) std::istringstream(line.substr(12)) >> info.lDiskWriteBytes;
58 static NetworkUsageInfo ReadNet(
int iPid) {
60 NetworkUsageInfo info;
61 if (iPid <= 0)
return info;
62 std::ifstream f(
"/proc/" + std::to_string(iPid) +
"/net/dev");
63 std::string line;
long long totalRx = 0, totalTx = 0;
int cnt = 0;
64 while (f.is_open() && std::getline(f, line)) {
65 if (++cnt <= 2)
continue;
66 auto pos = line.find(
':');
67 if (pos != std::string::npos) {
68 std::istringstream iss(line.substr(pos + 1));
69 long long rx = 0, tx = 0, dummy = 0;
70 iss >> rx;
for (
int i = 0; i < 7; ++i) iss >> dummy; iss >> tx;
71 totalRx += rx; totalTx += tx;
74 info.lNetworkReadBytes = totalRx; info.lNetworkWriteBytes = totalTx;
78 static ProcessNetworkConnectionInfo ReadNetInfo(
int iPid) {
80 ProcessNetworkConnectionInfo info;
81 if (iPid <= 0)
return info;
82 std::ifstream f(
"/proc/net/tcp");
83 std::string line;
int cnt = 0;
84 while (f.is_open() && std::getline(f, line)) {
85 if (cnt++ == 0)
continue;
86 std::istringstream iss(line);
87 std::string sl, lAddr, rAddr, st;
88 if (iss >> sl >> lAddr >> rAddr >> st) {
89 auto c1 = lAddr.find(
':'), c2 = rAddr.find(
':');
90 if (c1 != std::string::npos && c2 != std::string::npos) {
91 int lp = std::stoi(lAddr.substr(c1 + 1),
nullptr, 16);
92 int rp = std::stoi(rAddr.substr(c2 + 1),
nullptr, 16);
93 NetworkConnectionInfo conn; conn.iLocalPort = lp; conn.iRemotePort = rp;
94 conn.sState = (st ==
"01") ?
"ESTABLISHED" :
"LISTEN";
95 info.lstConnections.Add(conn); info.lstOpenPorts.Add(lp);
96 if (st ==
"01") info.bHasEstablishedInboundConnection =
true;
103 static MemoryInfo GetSysMem() {
106 std::ifstream f(
"/proc/meminfo");
107 std::string line;
unsigned long long tot = 0, av = 0;
108 while (f.is_open() && std::getline(f, line)) {
109 if (line.rfind(
"MemTotal:", 0) == 0) std::istringstream(line.substr(9)) >> tot;
110 else if (line.rfind(
"MemAvailable:", 0) == 0) std::istringstream(line.substr(13)) >> av;
112 info.uMemoryTotalBytes = tot * 1024ULL;
113 info.uMemoryUsedBytes = (tot > av) ? (tot - av) * 1024ULL : 0ULL;
114 if (tot > 0) info.dMemoryUsagePercent = (
static_cast<double>(info.uMemoryUsedBytes) /
static_cast<double>(info.uMemoryTotalBytes)) * 100.0;
118 static double GetSysCpu() {
120 std::ifstream f(
"/proc/stat");
122 if (f.is_open() && std::getline(f, line) && line.rfind(
"cpu ", 0) == 0) {
123 std::istringstream iss(line.substr(4));
124 long long u, n, s, id, io, ir, so, st;
125 if (iss >> u >> n >> s >>
id >> io >> ir >> so >> st) {
126 long long idle =
id + io, nonIdle = u + n + s + ir + so + st, total = idle + nonIdle;
127 if (total > 0)
return (
static_cast<double>(nonIdle) /
static_cast<double>(total)) * 100.0;
133 static DiskInfo GetSysDisk() {
135 DiskInfo info;
struct statvfs vfs;
136 if (statvfs(
"/", &vfs) == 0) {
137 info.lDiskReadBytes =
static_cast<long long>(vfs.f_blocks * vfs.f_frsize);
138 info.lDiskWriteBytes =
static_cast<long long>((vfs.f_blocks - vfs.f_bfree) * vfs.f_frsize);
143 static double GetSysNet() {
145 std::ifstream f(
"/proc/net/dev");
146 std::string line;
long long total = 0;
int cnt = 0;
147 while (f.is_open() && std::getline(f, line)) {
148 if (++cnt <= 2)
continue;
149 auto pos = line.find(
':');
150 if (pos != std::string::npos) {
151 std::istringstream iss(line.substr(pos + 1));
152 long long rx = 0, tx = 0, dummy = 0;
153 iss >> rx;
for (
int i = 0; i < 7; ++i) iss >> dummy; iss >> tx;
157 return static_cast<double>(total);
160 static String ReadCmdLine(
int pid) {
162 if (pid <= 0)
return String(
"");
163 std::ifstream f(
"/proc/" + std::to_string(pid) +
"/cmdline", std::ios::binary);
164 std::string cmd;
char ch;
165 while (f.is_open() && f.get(ch)) cmd += (ch ==
'\0') ?
' ' : ch;
166 return String(cmd.c_str());
170 int SystemMetrics::FindPidByName(
const String& sProcessName) {
return SystemMetricsLinuxHelper::FindPid(sProcessName); }
171 MemoryInfo SystemMetrics::ReadLinuxProcessMemory(
int iPid) {
return SystemMetricsLinuxHelper::ReadMem(iPid); }
172 DiskInfo SystemMetrics::ReadLinuxProcessDisk(
int iPid) {
return SystemMetricsLinuxHelper::ReadDisk(iPid); }
173 NetworkUsageInfo SystemMetrics::ReadLinuxProcessNetwork(
int iPid) {
return SystemMetricsLinuxHelper::ReadNet(iPid); }
174 ProcessNetworkConnectionInfo SystemMetrics::ReadLinuxProcessNetworkInfo(
int iPid) {
return SystemMetricsLinuxHelper::ReadNetInfo(iPid); }
175 Collections::Generic::List<int> SystemMetrics::ReadLinuxProcessPorts(
int iPid) {
return SystemMetricsLinuxHelper::ReadNetInfo(iPid).lstOpenPorts; }
193 if (proc.iProcessId <= 0)
throw ArgumentException(
"Process ID must be greater than zero.");
195 proc.memory = ReadLinuxProcessMemory(proc.iProcessId);
196 proc.disk = ReadLinuxProcessDisk(proc.iProcessId);
197 proc.network = ReadLinuxProcessNetwork(proc.iProcessId);
198 if (bIncludeNetwork) {
199 auto netInfo = ReadLinuxProcessNetworkInfo(proc.iProcessId);
200 proc.lstOpenPorts = netInfo.lstOpenPorts;
201 proc.lstConnections = netInfo.lstConnections;
202 proc.bHasEstablishedConnection = netInfo.bHasEstablishedInboundConnection;
207 return Collections::Generic::List<ServiceInfo>();
Defines the exception thrown when an invalid argument is provided to a method.
Provides access to local and remote processes and enables you to start and stop local system processe...
Utility routines for high-performance UTF-8, UTF-16, and wide-character string conversions.
ArgumentException(const String &sMessage)
Initializes a new instance of the ArgumentException class with a specified error message.
static String GetProcessCommandLine(const String &sProcessName)
Queries the full command line used to launch a process by name.
static void EnrichProcessInfo(ProcessInfo &proc, bool bIncludeNetwork=true)
Enriches an existing ProcessInfo instance with CPU, memory, disk, and network telemetry.
static Collections::Generic::List< int > GetProcessNetworkPort(const String &sProcessName)
Retrieves open listening ports bound by a process by name.
static DiskInfo GetProcessDiskUsage(const String &sProcessName)
Queries disk transfer throughput for a process by name.
static MemoryInfo GetProcessMemoryUsage(const String &sProcessName)
Queries memory allocation details for a process by name.
static Collections::Generic::List< ServiceInfo > GetAllServices()
Enumerates all registered system background services and their current execution status.
static MemoryInfo GetSystemMemoryUsage()
Retrieves total and consumed physical memory metrics for the entire machine.
static double GetSystemCpuUsage()
Computes total system CPU usage percentage across all processors.
static double GetSystemNetworkUsage()
Computes total network traffic throughput across all operational interfaces in Megabits per second.
static NetworkUsageInfo GetProcessNetworkUsage(const String &sProcessName)
Queries network transfer metrics for a process by name.
static ProcessNetworkConnectionInfo GetProcessNetworkInfo(const String &sProcessName)
Queries detailed socket connections for a process by name.
static DiskInfo GetSystemDiskUsage()
Retrieves total disk read and write transfer rates for the system.
Rate or aggregate count of disk read and write operations.
Snapshot of physical and virtual memory utilization for the system or a specific process.
Network throughput counters for bytes transmitted and received.
Comprehensive telemetry snapshot for an operating system process.
Collection of open ports and active connections attributed to a specific process.