Skip to content

Instantly share code, notes, and snippets.

@zedchance
Last active October 24, 2021 16:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zedchance/50066e09da8adfa236e5a8e0d6f2a32f to your computer and use it in GitHub Desktop.
Save zedchance/50066e09da8adfa236e5a8e0d6f2a32f to your computer and use it in GitHub Desktop.
Observe linux system information
all: observer
observer: observer.c
clang observer.c -o observer
clean:
rm -f observer
test: observer
./observer
./observer -s
./observer -l 1 5
// 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();
}
}
@zedchance
Copy link
Author

./observer
CPU:		AMD EPYC 7601 32-Core Processor
Linux version:	5.4.0-65-generic
Uptime:		228:20:29:22
Date:		Thu Sep 23 17:33:11 2021
Hostname:	mojo
./observer -s
CPU:		AMD EPYC 7601 32-Core Processor
Linux version:	5.4.0-65-generic
Uptime:		228:20:29:22
Date:		Thu Sep 23 17:33:11 2021
Hostname:	mojo
User time:	7391923
System time:	3680574
Idle time:	1962963643
Read/writes:	48770617
Ctx switches:	1314771549
Processes:	3404891
./observer -l 1 5
CPU:		AMD EPYC 7601 32-Core Processor
Linux version:	5.4.0-65-generic
Uptime:		228:20:29:22
Date:		Thu Sep 23 17:33:11 2021
Hostname:	mojo
User time:	7391923
System time:	3680575
Idle time:	1962963643
Read/writes:	48770617
Ctx switches:	1314771701
Processes:	3404892
Total mem:	1004768 kB
Processes mem:	81224 kB
0.00
0.00
0.00
0.00
0.00

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment