diff --git a/lib/bridge.cc b/lib/bridge.cc index 9611b91e92c176eca86788667495115115d1ae8b..f53737a1f606cab1a49dbe641114784462d447e7 100644 --- a/lib/bridge.cc +++ b/lib/bridge.cc @@ -7,12 +7,14 @@ #include #include #include + #ifdef __linux__ #include #include #include #include #include + #elif __APPLE__ #include #include diff --git a/lib/include/fork.h b/lib/include/fork.h index 204c86961630fa659ed140cb6d9c1b52333f7cfc..7ce089ae3c4a1af354628c6d98aabc81985447da 100644 --- a/lib/include/fork.h +++ b/lib/include/fork.h @@ -1,5 +1,6 @@ #ifndef FORK_H #define FORK_H + #include #include diff --git a/lib/include/rust.h b/lib/include/rust.h index e1da023242c2db06b38019d867eb281fb6dd878e..56440aecb363dac5b5a3748295f868251857a75e 100644 --- a/lib/include/rust.h +++ b/lib/include/rust.h @@ -14,6 +14,7 @@ #include #include #include + #if defined(_WIN32) #include #else diff --git a/lib/process.cc b/lib/process.cc index 38543ecc7a86e4b84f54c3a7b19b21299bb86df8..679844b18956ee832e26f4a5b81826f426ba4bfb 100644 --- a/lib/process.cc +++ b/lib/process.cc @@ -3,8 +3,17 @@ #include #include #include +#include +#include #include #include +#include +#include + +#ifdef __APPLE__ +#include +#include +#endif using namespace std; @@ -101,7 +110,22 @@ int64_t Runner::Run(const std::string &command, const std::string &shell, Vec> child_pid) { + return child_pid; + } + } + } + return pid; } diff --git a/lib/psutil.cc b/lib/psutil.cc index f1e77f71c97affcfdcb5dc3181c7c1797cc77ce6..8b3df3e8c487e9f41062ec1a7285b22edcee9919 100644 --- a/lib/psutil.cc +++ b/lib/psutil.cc @@ -1,76 +1,99 @@ -#include -#include -#include -#include -#include -#include -#include #include #include #include + #ifdef __APPLE__ #include #include +#include +#else +#include +#include +#include +#include +#include #endif -double get_process_cpu_usage_percentage(int64_t pid) { - auto get_cpu_time = [](int64_t pid) -> double { +int get_num_cores() { #ifdef __APPLE__ - struct proc_taskinfo pti; - int ret = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti)); - if (ret <= 0) { - return 0; + int nm[2]; + size_t len = 4; + uint32_t count; + + nm[0] = CTL_HW; nm[1] = HW_AVAILCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + + if(count < 1) { + nm[1] = HW_NCPU; + sysctl(nm, 2, &count, &len, NULL, 0); } - return (pti.pti_total_user + pti.pti_total_system) / 100000000.0; // Convert nanoseconds to seconds + return count > 0 ? static_cast(count) : 1; #else - std::string stat_path = "/proc/" + std::to_string(pid) + "/stat"; - std::ifstream stat_file(stat_path); - - if (!stat_file.is_open()) { - std::cerr << "Error: Unable to open " << stat_path << std::endl; - return -1.0; - } - - std::string line; - std::getline(stat_file, line); - stat_file.close(); - - std::istringstream iss(line); - std::string token; - std::vector tokens; - - while (std::getline(iss, token, ' ')) { - tokens.push_back(token); - } - - if (tokens.size() < 15) { - std::cerr << "Error: Invalid stat file format" << std::endl; - return -1.0; - } - - unsigned long long utime = std::stoull(tokens[13]); - unsigned long long stime = std::stoull(tokens[14]); - - return (utime + stime) / sysconf(_SC_CLK_TCK); + return static_cast(sysconf(_SC_NPROCESSORS_ONLN)); +#endif +} + +double get_cpu_time(int64_t pid) { +#ifdef __APPLE__ + struct proc_taskinfo pti; + int ret = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti)); + if (ret <= 0) { + return 0.0; + } + return (pti.pti_total_user + pti.pti_total_system) / 1e9; +#else + std::string stat_path = "/proc/" + std::to_string(pid) + "/stat"; + std::ifstream stat_file(stat_path); + + if (!stat_file.is_open()) { + return 0.0; + } + + std::string line; + std::getline(stat_file, line); + + std::istringstream iss(line); + std::string token; + std::vector tokens; + + while (std::getline(iss, token, ' ')) { + tokens.push_back(token); + } + + if (tokens.size() < 15) { + return 0.0; + } + + unsigned long long utime = std::stoull(tokens[13]); + unsigned long long stime = std::stoull(tokens[14]); + + return (utime + stime) / sysconf(_SC_CLK_TCK); #endif - }; +} + +extern "C++" double get_process_cpu_usage_percentage(int64_t pid) { + const std::chrono::milliseconds measurement_interval(300); - double cpu_time1 = get_cpu_time(pid); - if (cpu_time1 < 0) return -1.0; + double cpu_time_start = get_cpu_time(pid); + if (cpu_time_start < 0) { + return 0.0; + } - auto start = std::chrono::high_resolution_clock::now(); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - auto end = std::chrono::high_resolution_clock::now(); + auto start_time = std::chrono::steady_clock::now(); + std::this_thread::sleep_for(measurement_interval); + auto end_time = std::chrono::steady_clock::now(); - double cpu_time2 = get_cpu_time(pid); - if (cpu_time2 < 0) return -1.0; + double cpu_time_end = get_cpu_time(pid); + if (cpu_time_end < 0) { + return 0.0; + } - std::chrono::duration elapsed = end - start; + double cpu_time_diff = cpu_time_end - cpu_time_start; + std::chrono::duration elapsed = end_time - start_time; double elapsed_seconds = elapsed.count(); - double cpu_time_diff = cpu_time2 - cpu_time1; + double cpu_usage_percentage = (cpu_time_diff / elapsed_seconds) * 100.0; - long num_cores = sysconf(_SC_NPROCESSORS_ONLN); - double cpu_usage_percentage = (cpu_time_diff / elapsed_seconds) * 100.0 * num_cores; + long num_cores = get_num_cores(); return std::min(cpu_usage_percentage, 100.0 * num_cores); -} +} \ No newline at end of file diff --git a/src/webui/src/components/react/servers.tsx b/src/webui/src/components/react/servers.tsx index 4bc4e7b4378653882ba68d67f67669dedb59accb..68c7b3c153ed4e89d9452bf16f2c0c2b5c682b68 100644 --- a/src/webui/src/components/react/servers.tsx +++ b/src/webui/src/components/react/servers.tsx @@ -157,7 +157,7 @@ const Index = (props: { base: string }) => { src={getServerIcon(props.base, server.os.name)} className={classNames( server.daemon.running ? 'ring-emerald-400 bg-white' : 'ring-red-400 bg-red-500', - 'h-8 w-8 rounded-full ring-1' + 'h-8 w-8 rounded-full ring-2' )} />
{server.name == 'local' ? 'Internal' : server.name}
diff --git a/src/webui/src/components/react/status.tsx b/src/webui/src/components/react/status.tsx index 6b8ae4fa1e767866a4aa02478e710e028784ae09..58f4c1e1f5c76ca7ff240fd74a8a1c3be695c19d 100644 --- a/src/webui/src/components/react/status.tsx +++ b/src/webui/src/components/react/status.tsx @@ -125,7 +125,7 @@ const Status = (props: { name: string; base: string }) => { setItem(data); memoryUsage.pushMax(data.raw.memory_usage.rss); - cpuPercentage.pushMax(data.raw.cpu_percent + 1); + cpuPercentage.pushMax(data.raw.cpu_percent); if (!hasRun) { setLoaded(true);