Added code to read status and io files
This commit is contained in:
parent
341a1228aa
commit
0068c483fc
39
py/stat_flags.py
Normal file
39
py/stat_flags.py
Normal file
@ -0,0 +1,39 @@
|
||||
reverse_lookup = {
|
||||
0x00000001: "PF_VCPU", # I'm a virtual CPU
|
||||
0x00000002: "PF_IDLE", # I am an IDLE thread
|
||||
0x00000004: "PF_EXITING", # Getting shut down
|
||||
0x00000008: "PF_POSTCOREDUMP", # Coredumps should ignore this task
|
||||
0x00000010: "PF_IO_WORKER", # Task is an IO worker
|
||||
0x00000020: "PF_WQ_WORKER", # I'm a workqueue worker
|
||||
0x00000040: "PF_FORKNOEXEC", # Forked but didn't exec
|
||||
0x00000080: "PF_MCE_PROCESS", # Process policy on mce errors
|
||||
0x00000100: "PF_SUPERPRIV", # Used super-user privileges
|
||||
0x00000200: "PF_DUMPCORE", # Dumped core
|
||||
0x00000400: "PF_SIGNALED", # Killed by a signal
|
||||
0x00000800: "PF_MEMALLOC", # Allocating memory
|
||||
0x00001000: "PF_NPROC_EXCEEDED", # set_user() noticed that RLIMIT_NPROC was exceeded
|
||||
0x00002000: "PF_USED_MATH", # If unset the fpu must be initialized before use
|
||||
0x00004000: "PF_USER_WORKER", # Kernel thread cloned from userspace thread
|
||||
0x00008000: "PF_NOFREEZE", # This thread should not be frozen
|
||||
0x00010000: "PF__HOLE__00010000",
|
||||
0x00020000: "PF_KSWAPD", # I am kswapd
|
||||
0x00040000: "PF_MEMALLOC_NOFS", # All allocation requests will inherit GFP_NOFS
|
||||
0x00080000: "PF_MEMALLOC_NOIO", # All allocation requests will inherit GFP_NOIO
|
||||
0x00100000: "PF_LOCAL_THROTTLE", # Throttle writes only against the bdi I write to, I am cleaning dirty pages from some other bdi.
|
||||
0x00200000: "PF_KTHREAD", # I am a kernel thread
|
||||
0x00400000: "PF_RANDOMIZE", # Randomize virtual address space
|
||||
0x00800000: "PF__HOLE__00800000",
|
||||
0x01000000: "PF__HOLE__01000000",
|
||||
0x02000000: "PF__HOLE__02000000",
|
||||
0x04000000: "PF_NO_SETAFFINITY", # Userland is not allowed to meddle with cpus_mask
|
||||
0x08000000: "PF_MCE_EARLY", # Early kill for mce process policy
|
||||
0x10000000: "PF_MEMALLOC_PIN", # Allocation context constrained to zones which allow long term pinning.
|
||||
0x20000000: "PF__HOLE__20000000",
|
||||
0x40000000: "PF__HOLE__40000000",
|
||||
0x80000000: "PF_SUSPEND_TASK", # This thread called freeze_processes() and should not be frozen
|
||||
}
|
||||
|
||||
def listFlags(flag):
|
||||
for i in reverse_lookup.keys():
|
||||
if flag & i:
|
||||
print(reverse_lookup[i])
|
||||
@ -14,13 +14,16 @@ typedef struct st_process {
|
||||
int ppid;
|
||||
int tgid;
|
||||
int level;
|
||||
char *label;
|
||||
char label[128];
|
||||
int iskernel;
|
||||
// statistics - each outputs 1 line per process
|
||||
uint64_t cpuTime;
|
||||
uint64_t childCpuTime;
|
||||
uint64_t nThreads;
|
||||
uint64_t resident;
|
||||
uint64_t swap;
|
||||
uint64_t written;
|
||||
uint64_t read;
|
||||
} Process;
|
||||
|
||||
#endif
|
||||
|
||||
141
src/server.c
141
src/server.c
@ -65,28 +65,17 @@ int parseStatFile(Process *proc, char *filedata) {
|
||||
proc->ppid = fast_str2ull(&location);
|
||||
location += 1;
|
||||
|
||||
// (5) pgrp - %d
|
||||
proc->tgid = fast_str2ll(&location);
|
||||
location += 1;
|
||||
|
||||
if (proc->tgid && proc->tgid != proc->pid) return -1;
|
||||
|
||||
// (6) session - %d
|
||||
location = strchr(location, ' ') + 1;
|
||||
|
||||
// skip [7 - 14)
|
||||
//skipRange(7,14);
|
||||
skipRange(7, 9);
|
||||
// skip [5 - 9)
|
||||
skipRange(5, 9);
|
||||
|
||||
// (9) flags - %u
|
||||
proc->flags = fast_str2ull(&location);
|
||||
location += 1;
|
||||
|
||||
printf("Flags for %d: %u %d\n", proc->pid, proc->flags, proc->flags & PF_KTHREAD);
|
||||
proc->iskernel = (proc->flags & PF_KTHREAD) ? true : false;
|
||||
location += 1;
|
||||
|
||||
//skipRange(10, 14);
|
||||
// skip [10 - 14)
|
||||
skipRange(10, 14);
|
||||
|
||||
// (14) utime - %lu
|
||||
proc->cpuTime = fast_str2ull(&location);
|
||||
@ -107,34 +96,45 @@ int parseStatFile(Process *proc, char *filedata) {
|
||||
// skip 18-19
|
||||
skipRange(18, 20);
|
||||
|
||||
// (20) - num_threads %ld
|
||||
// (20) num_threads - %ld
|
||||
proc->nThreads = fast_str2ull(&location);
|
||||
location += 1;
|
||||
|
||||
// Skip 21-23
|
||||
skipRange(21,24);
|
||||
|
||||
// (24) - rss %ld
|
||||
proc->resident = fast_str2ull(&location);
|
||||
location += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
inline int findAndParseField(char **filedata, char *fld) {
|
||||
char *field = strstr(filedata, fld);
|
||||
while (*(++field) != ':');
|
||||
while (*(++field) == ' ');
|
||||
*filedata = field;
|
||||
return fast_str2ull(filedata);
|
||||
}
|
||||
|
||||
int parseStatusFile(Process *proc, char *filedata) {
|
||||
proc->pid = findAndParseField(&filedata, "Pid");
|
||||
proc->tgid = findAndParseField(&filedata, "Tgid");
|
||||
|
||||
if (proc->pid != proc->tgid) return -1; // ignore child threads, as their stats are the same as the parent
|
||||
|
||||
proc->resident = 1024 * findAndParseField(&filedata, "VmRSS");
|
||||
proc->swap = 1024 * findAndParseField(&filedata, "VmSwap");
|
||||
}
|
||||
|
||||
int parseIOFile(Process *proc, char *filedata) {
|
||||
proc->read = findAndParseField(&filedata, "read_bytes");
|
||||
proc->written = findAndParseField(&filedata, "write_bytes");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *readProcesses(char *procdir) {
|
||||
int len, rc = 1;
|
||||
struct dirent *pDirent;
|
||||
DIR *pDir;
|
||||
|
||||
// Ensure correct argument count.
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: testprog <dirname>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Ensure we can open directory.
|
||||
|
||||
pDir = opendir(argv[1]);
|
||||
pDir = opendir(procdir);
|
||||
if (pDir == NULL) {
|
||||
printf("Cannot open directory '%s'\n", argv[1]);
|
||||
return 1;
|
||||
@ -144,35 +144,48 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
char *buffer = malloc(4096);
|
||||
char *fname = malloc(1024);
|
||||
char first;
|
||||
FILE *file;
|
||||
|
||||
Process *cur = malloc(sizeof(Process));
|
||||
cur->label = malloc(256);
|
||||
cur->prev = NULL;
|
||||
cur->next = NULL;
|
||||
Process *head = cur;
|
||||
|
||||
while ((pDirent = readdir(pDir)) != NULL) {
|
||||
char first = pDirent->d_name[0];
|
||||
first = pDirent->d_name[0];
|
||||
if (first < '0' || first > '9') continue;
|
||||
sprintf(fname, "/proc/%s/stat", pDirent->d_name);
|
||||
sprintf(fname, "/proc/%s/status", pDirent->d_name);
|
||||
file = fopen(fname, "rb");
|
||||
if (file == NULL) continue;
|
||||
fread(buffer, 1, 4096, file);
|
||||
fclose(file);
|
||||
|
||||
if (parseStatusFile(cur, buffer)) continue;
|
||||
|
||||
// truncate 'status' to 'stat'
|
||||
len = strlen(fname);
|
||||
fname[len-2] = 0;
|
||||
|
||||
file = fopen(fname, "rb");
|
||||
if (file == NULL) continue;
|
||||
fread(buffer, 1, 4096, file);
|
||||
fclose(file);
|
||||
|
||||
if (parseStatFile(cur, buffer)) continue;
|
||||
cur->next = malloc(sizeof(Process));
|
||||
cur->next->label = malloc(256);
|
||||
cur->next->prev = cur;
|
||||
cur = cur->next;
|
||||
|
||||
strcat(fname, "us");
|
||||
file = fopen(fname, "rb");
|
||||
if (file == NULL) continue;
|
||||
fread(buffer, 1, 4096, file);
|
||||
fclose(file);
|
||||
strtok(buffer, "\n");
|
||||
|
||||
if (parseIOFile(cur, buffer)) continue;
|
||||
|
||||
cur->next = malloc(sizeof(Process));
|
||||
cur->next->prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
closedir(pDir);
|
||||
|
||||
// clean up unused last node
|
||||
cur = cur->prev;
|
||||
free(cur->next);
|
||||
cur->next = NULL;
|
||||
@ -183,17 +196,33 @@ int main(int argc, char *argv[]) {
|
||||
while (cur != NULL) {
|
||||
// create process descriptor
|
||||
sprintf(buffer, "pid=\"%d\",ppid=\"%d\",label=\"%s\",kernel=\"%d\"", cur->pid, cur->ppid, cur->label, cur->iskernel);
|
||||
printf("proc_cpu_time{%s} %d\n", buffer, cur->cpuTime);
|
||||
printf("proc_child_cpu_time{%s} %d\n", buffer, cur->childCpuTime / clocks);
|
||||
printf("proc_num_threads{%s} %d\n", buffer, cur->nThreads);
|
||||
printf("proc_resident_bytes{%s} %d\n", buffer, cur->resident);
|
||||
printf("proc_cpu_time{%s} %lf\n", buffer, (double) cur->cpuTime / clocks);
|
||||
printf("proc_child_cpu_time{%s} %lf\n", buffer, (double) cur->childCpuTime / clocks);
|
||||
printf("proc_num_threads{%s} %llu\n", buffer, cur->nThreads);
|
||||
printf("proc_resident_bytes{%s} %llu\n", buffer, cur->resident);
|
||||
printf("proc_swap_bytes{%s} %llu\n", buffer, cur->swap);
|
||||
printf("proc_fileio_bytes_written{%s} %llu\n", buffer, cur->written);
|
||||
printf("proc_fileio_bytes_read{%s} %llu\n", buffer, cur->read);
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
rc = 0;
|
||||
|
||||
freeChain:
|
||||
cur = head;
|
||||
while (cur != NULL) {
|
||||
Process *prev = cur;
|
||||
cur = cur->next;
|
||||
free(prev);
|
||||
}
|
||||
|
||||
#define PORT 8080
|
||||
closedir(pDir);
|
||||
free(buffer);
|
||||
free(fname);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define PORT 9101
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
void handle_client(int client_socket) {
|
||||
@ -201,10 +230,10 @@ void handle_client(int client_socket) {
|
||||
const char *http_response =
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n"
|
||||
"Content-Length: 13\r\n"
|
||||
"Content-Length: 25\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n"
|
||||
"Hello, World!";
|
||||
"test{data=\"something\"} 25";
|
||||
|
||||
// Send the response to the client
|
||||
send(client_socket, http_response, strlen(http_response), 0);
|
||||
@ -213,7 +242,13 @@ void handle_client(int client_socket) {
|
||||
close(client_socket);
|
||||
}
|
||||
|
||||
int main2() {
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
if (argc == 1) {
|
||||
readProcesses("/proc");
|
||||
return;
|
||||
}
|
||||
|
||||
int server_socket, client_socket;
|
||||
struct sockaddr_in server_addr, client_addr;
|
||||
socklen_t addr_len = sizeof(client_addr);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user