Created
November 21, 2024 17:27
-
-
Save yetimdasturchi/b8a59db2e249bcada70bc5c4d2c01a5d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <limits.h> | |
#include <stdint.h> | |
#include <pthread.h> | |
void restart_program() { | |
char program_path[100]; | |
ssize_t len = readlink("/proc/self/exe", program_path, sizeof(program_path) - 1); | |
if (len == -1) { | |
perror("Error reading program path"); | |
exit(1); | |
} | |
program_path[len] = '\0'; | |
char *args[] = { program_path, NULL }; | |
printf("Restarting program...\n"); | |
execv(program_path, args); | |
perror("Error restarting program"); | |
_exit(1); | |
} | |
double get_memory_usage() { | |
FILE *file = fopen("/proc/self/statm", "r"); | |
if (file == NULL) { | |
perror("Could not open /proc/self/statm"); | |
return -1.0; | |
} | |
long resident_memory; | |
if (fscanf(file, "%*s %ld", &resident_memory) != 1) { | |
perror("Failed to read memory usage"); | |
fclose(file); | |
return -1.0; | |
} | |
fclose(file); | |
long page_size = sysconf(_SC_PAGESIZE); | |
return (resident_memory * page_size) / (1024.0 * 1024.0); | |
} | |
double get_cpu_usage(long *prev_total_time, long *prev_proc_time) { | |
FILE *file = fopen("/proc/self/stat", "r"); | |
if (file == NULL) { | |
perror("Could not open /proc/self/stat"); | |
return -1.0; | |
} | |
long user_time, kernel_time; | |
if (fscanf(file, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %ld %ld", &user_time, &kernel_time) != 2) { | |
perror("Failed to read CPU usage"); | |
fclose(file); | |
return -1.0; | |
} | |
fclose(file); | |
long proc_time = user_time + kernel_time; | |
file = fopen("/proc/stat", "r"); | |
if (file == NULL) { | |
perror("Could not open /proc/stat"); | |
return -1.0; | |
} | |
long total_time = 0; | |
char line[256]; | |
if (fgets(line, sizeof(line), file) != NULL) { | |
long user, nice, system, idle, iowait, irq, softirq, steal; | |
if (sscanf(line, "cpu %ld %ld %ld %ld %ld %ld %ld %ld", | |
&user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal) == 8) { | |
total_time = user + nice + system + idle + iowait + irq + softirq + steal; | |
} | |
} | |
fclose(file); | |
if (*prev_total_time == 0 && *prev_proc_time == 0) { | |
*prev_total_time = total_time; | |
*prev_proc_time = proc_time; | |
return 0.0; | |
} | |
double cpu_usage = 0.0; | |
long total_diff = total_time - *prev_total_time; | |
long proc_diff = proc_time - *prev_proc_time; | |
if (total_diff > 0) { | |
cpu_usage = 100.0 * proc_diff / total_diff; | |
} | |
*prev_total_time = total_time; | |
*prev_proc_time = proc_time; | |
return cpu_usage; | |
} | |
void get_disk_io(long *read_bytes, long *write_bytes) { | |
FILE *file = fopen("/proc/self/io", "r"); | |
if (file == NULL) { | |
perror("Could not open /proc/self/io"); | |
return; | |
} | |
char label[32]; | |
long value; | |
while (fscanf(file, "%s %ld", label, &value) == 2) { | |
if (strcmp(label, "read_bytes:") == 0) { | |
*read_bytes = value / 1024; | |
} else if (strcmp(label, "write_bytes:") == 0) { | |
*write_bytes = value / 1024; | |
} | |
} | |
fclose(file); | |
} | |
void get_network_usage(double *rx_mb, double *tx_mb) { | |
FILE *file = fopen("/proc/net/dev", "r"); | |
if (file == NULL) { | |
perror("Could not open /proc/net/dev"); | |
return; | |
} | |
char line[256]; | |
long total_rx_bytes = 0; | |
long total_tx_bytes = 0; | |
fgets(line, sizeof(line), file); | |
fgets(line, sizeof(line), file); | |
while (fgets(line, sizeof(line), file) != NULL) { | |
char iface[16]; | |
long rx, tx; | |
if (sscanf(line, "%s %ld %*d %*d %*d %*d %*d %*d %*d %ld", iface, &rx, &tx) == 3) { | |
total_rx_bytes += rx; | |
total_tx_bytes += tx; | |
} | |
} | |
fclose(file); | |
*rx_mb = total_rx_bytes / (1024.0 * 1024.0); | |
*tx_mb = total_tx_bytes / (1024.0 * 1024.0); | |
} | |
void *monitor_usage() { | |
long prev_total_time = 0, prev_proc_time = 0; | |
long prev_read_bytes = 0, prev_write_bytes = 0; | |
double prev_rx_mb = 0, prev_tx_mb = 0; | |
while (1) { | |
double memory_in_mb = get_memory_usage(); | |
double cpu_usage = get_cpu_usage(&prev_total_time, &prev_proc_time); | |
long read_bytes = 0, write_bytes = 0; | |
get_disk_io(&read_bytes, &write_bytes); | |
double rx_mb = 0, tx_mb = 0; | |
get_network_usage(&rx_mb, &tx_mb); | |
if (memory_in_mb < 0) { | |
fprintf(stderr, "Error: Failed to retrieve memory usage.\n"); | |
} | |
if (cpu_usage < 0) { | |
fprintf(stderr, "Error: Failed to retrieve CPU usage.\n"); | |
} | |
if (read_bytes < 0 || write_bytes < 0) { | |
fprintf(stderr, "Error: Failed to retrieve disk I/O usage.\n"); | |
} | |
if (rx_mb < 0 || tx_mb < 0) { | |
fprintf(stderr, "Error: Failed to retrieve network usage.\n"); | |
} | |
printf("--------\n"); | |
printf("Resource Usage:\n"); | |
if (memory_in_mb >= 0) { | |
printf("Memory Usage: %.2f MB\n", memory_in_mb); | |
} | |
if (cpu_usage >= 0) { | |
printf("CPU Usage: %.2f%%\n", cpu_usage); | |
} | |
if (read_bytes >= 0 && write_bytes >= 0) { | |
printf("Disk I/O: Read %ld KB, Write %ld KB\n", read_bytes - prev_read_bytes, write_bytes - prev_write_bytes); | |
} | |
if (rx_mb >= 0 && tx_mb >= 0) { | |
printf("Network: RX %.2f MB, TX %.2f MB\n", rx_mb - prev_rx_mb, tx_mb - prev_tx_mb); | |
} | |
printf("--------\n"); | |
prev_read_bytes = read_bytes; | |
prev_write_bytes = write_bytes; | |
prev_rx_mb = rx_mb; | |
prev_tx_mb = tx_mb; | |
sleep(1); | |
} | |
return NULL; | |
} | |
int main() { | |
monitor_usage(); | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment