Last active
October 24, 2021 16:33
-
-
Save zedchance/50066e09da8adfa236e5a8e0d6f2a32f to your computer and use it in GitHub Desktop.
Observe linux system information
This file contains 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
all: observer | |
observer: observer.c | |
clang observer.c -o observer | |
clean: | |
rm -f observer | |
test: observer | |
./observer | |
./observer -s | |
./observer -l 1 5 | |
This file contains 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
// observer - CS139 assignment 1 | |
// Zed Chance | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <time.h> | |
#include <unistd.h> | |
FILE * open_proc_file(char * filename) | |
{ | |
char path[30]; | |
sprintf(path, "/proc/%s", filename); | |
FILE * f = fopen(path, "r"); | |
if (!f) | |
{ | |
printf("Can't open %s for reading\n", filename); | |
exit(1); | |
} | |
return f; | |
} | |
char * get_proc_stat(char * filename, char * format) | |
{ | |
// open proc file | |
FILE * f = open_proc_file(filename); | |
char * stat = malloc(100 * sizeof(char)); | |
// search for match using format | |
char line[1000]; | |
while (fgets(line, 1000, f) != NULL) | |
{ | |
if (sscanf(line, format, stat) == 1) break; | |
} | |
fclose(f); | |
return stat; | |
} | |
void convert_seconds(long in, int * days, int * hours, int * mins, int * secs) | |
{ | |
// days | |
*days = 0; | |
while (in >= 24 * 60 * 60) | |
{ | |
in = in - (24 * 60 * 60); | |
*days = *days + 1; | |
} | |
// hours | |
*hours = 0; | |
while (in >= 60 * 60) | |
{ | |
in = in - (60 * 60); | |
*hours = *hours + 1; | |
} | |
// mins | |
*mins = 0; | |
while (in >= 60) | |
{ | |
in = in - 60; | |
*mins = *mins + 1; | |
} | |
// secs | |
*secs = in; | |
} | |
char * get_uptime() | |
{ | |
// read | |
long up_secs = 0; | |
char * up_str = get_proc_stat("uptime", "%s"); | |
sscanf(up_str, "%ld", &up_secs); | |
// convert | |
int days, hours, mins, secs; | |
convert_seconds(up_secs, &days, &hours, &mins, &secs); | |
// format | |
char * ret = malloc(12 * sizeof(char)); | |
sprintf(ret, "%02d:%02d:%02d:%02d", days, hours, mins, secs); | |
return ret; | |
} | |
char * get_datetime() | |
{ | |
// use system call to get time | |
time_t raw; | |
struct tm * timeinfo; | |
time(&raw); | |
timeinfo = localtime(&raw); | |
return asctime(timeinfo); | |
} | |
char * get_disk_read_writes() | |
{ | |
// read | |
long reads, writes = 0; | |
char * reads_str = get_proc_stat("diskstats", "%*s %*s sda %s"); | |
char * writes_str = get_proc_stat("diskstats", "%*s %*s sda %*s %*s %*s %*s %s"); | |
sscanf(reads_str, "%ld", &reads); | |
sscanf(writes_str, "%ld", &writes); | |
// format | |
char * ret = malloc(12 * sizeof(char)); | |
sprintf(ret, "%ld", reads + writes); | |
return ret; | |
} | |
void normal_mode() | |
{ | |
// CPU model name | |
printf("CPU:\t\t%s\n", get_proc_stat("cpuinfo", "model name\t: %100[^@\n]")); | |
// TODO free these mallocs | |
// Linux kernal version | |
printf("Linux version:\t%s\n", get_proc_stat("sys/kernel/osrelease", "%s")); | |
// Uptime dd:hh:mm:ss | |
printf("Uptime:\t\t%s\n", get_uptime()); | |
// Date | |
printf("Date:\t\t%s", get_datetime()); | |
// Hostname | |
printf("Hostname:\t%s\n", get_proc_stat("sys/kernel/hostname", "%s")); | |
} | |
void short_mode() | |
{ | |
// CPU time spent in user mode | |
printf("User time:\t%s\n", get_proc_stat("stat", "cpu %s")); | |
// CPU time spent in system mode | |
printf("System time:\t%s\n", get_proc_stat("stat", "cpu %*s %*s %s")); | |
// CPU time spent in idle mode | |
printf("Idle time:\t%s\n", get_proc_stat("stat", "cpu %*s %*s %*s %s")); | |
// total disk read/writes | |
printf("Read/writes:\t%s\n", get_disk_read_writes()); | |
// total context switches | |
printf("Ctx switches:\t%s\n", get_proc_stat("stat", "ctxt %s")); | |
// number of processes | |
printf("Processes:\t%s\n", get_proc_stat("stat", "processes %s")); | |
} | |
void long_mode(unsigned int sample_time, unsigned int total_time) | |
{ | |
// amount of memory | |
printf("Total mem:\t%s kB\n", get_proc_stat("meminfo", "MemTotal:\t%s")); | |
// memory available | |
printf("Processes mem:\t%s kB\n", get_proc_stat("meminfo", "MemFree:\t%s")); | |
// list of load averages over time | |
while(total_time > 0) | |
{ | |
printf("%s\n", get_proc_stat("loadavg", "%s")); | |
total_time = total_time - sample_time; | |
sleep(sample_time); | |
} | |
} | |
void usage() | |
{ | |
printf("Usage: observer [-s|-l int int]\n"); | |
exit(1); | |
} | |
int main(int argc, char * argv[]) | |
{ | |
// normal mode | |
if (argc < 2) | |
{ | |
normal_mode(); | |
} | |
// short mode | |
else if (strcmp(argv[1], "-s") == 0) | |
{ | |
normal_mode(); | |
short_mode(); | |
} | |
// long mode | |
else if (strcmp(argv[1], "-l") == 0) | |
{ | |
if (argc < 4) | |
{ | |
usage(); | |
} | |
normal_mode(); | |
short_mode(); | |
unsigned int sample_time, total_time = 0; | |
sscanf(argv[2], "%u", &sample_time); | |
sscanf(argv[3], "%u", &total_time); | |
long_mode(sample_time, total_time); | |
} | |
else | |
{ | |
usage(); | |
} | |
} | |
Author
zedchance
commented
Sep 24, 2021
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment