Testing actual parsing of /proc/<pid>/stat
This commit is contained in:
parent
1c91288dbc
commit
53f8871381
25
src/process.h
Normal file
25
src/process.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef PROCESS_MON_H
|
||||||
|
#define PROCESS_MON_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct st_process {
|
||||||
|
// For our own purposes
|
||||||
|
struct st_process *next;
|
||||||
|
struct st_process *prev;
|
||||||
|
// attributes identifying thread
|
||||||
|
int lxc;
|
||||||
|
int pid;
|
||||||
|
int ppid;
|
||||||
|
int tgid;
|
||||||
|
int level;
|
||||||
|
char *label;
|
||||||
|
int iskernel;
|
||||||
|
// statistics - each outputs 1 line per process
|
||||||
|
uint64_t cpuTime;
|
||||||
|
uint64_t childCpuTime;
|
||||||
|
uint64_t nThreads;
|
||||||
|
uint64_t resident;
|
||||||
|
} Process;
|
||||||
|
|
||||||
|
#endif
|
||||||
132
src/server.c
132
src/server.c
@ -1,10 +1,116 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
|
static inline uint64_t fast_str2ull(char** str) {
|
||||||
|
uint64_t result = 0;
|
||||||
|
int maxlen = 20; // length of maximum value of 18446744073709551615
|
||||||
|
|
||||||
|
while (maxlen-- && **str >= '0' && **str <= '9') {
|
||||||
|
result *= 10;
|
||||||
|
result += **str - '0';
|
||||||
|
(*str)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t fast_str2ll(char** str) {
|
||||||
|
bool neg = false;
|
||||||
|
|
||||||
|
if (**str == '-') {
|
||||||
|
neg = true;
|
||||||
|
(*str)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t res = fast_str2ull(str);
|
||||||
|
int64_t result = (int64_t) res;
|
||||||
|
|
||||||
|
return neg ? -result : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define skipRange(inclusive,exclusive) \
|
||||||
|
for (int i##inclusive=0; i##inclusive<exclusive-inclusive; i##inclusive++) \
|
||||||
|
location = strchr(location, ' ') + 1;
|
||||||
|
|
||||||
|
int parseStatFile(Process *proc, char *filedata) {
|
||||||
|
char *location = filedata;
|
||||||
|
// (1) pid - %d
|
||||||
|
proc->pid = fast_str2ull(&location);
|
||||||
|
location += 2;
|
||||||
|
|
||||||
|
// (2) comm - %s
|
||||||
|
char *end = strrchr(location, ')');
|
||||||
|
size_t length = end - location;
|
||||||
|
memcpy(proc->label, location, length);
|
||||||
|
proc->label[length] = 0;
|
||||||
|
location = end + 2;
|
||||||
|
|
||||||
|
// (3) State - %c
|
||||||
|
location += 2;
|
||||||
|
|
||||||
|
// (4) ppid - %d
|
||||||
|
proc->ppid = fast_str2ull(&location);
|
||||||
|
location += 1;
|
||||||
|
|
||||||
|
// (5) pgrp - %d
|
||||||
|
proc->tgid = fast_str2ll(&location);
|
||||||
|
location += 1;
|
||||||
|
|
||||||
|
if (proc->tgid != proc->pid) return -1;
|
||||||
|
|
||||||
|
// (6) session - %d
|
||||||
|
location = strchr(location, ' ') + 1;
|
||||||
|
|
||||||
|
// skip [7 - 14)
|
||||||
|
skipRange(7, 9);
|
||||||
|
|
||||||
|
// (9) flags - %u
|
||||||
|
proc->iskernel = fast_str2ull(&location) & PS_KTHREAD;
|
||||||
|
location += 1;
|
||||||
|
|
||||||
|
skipRange(10, 14);
|
||||||
|
|
||||||
|
// (14) utime - %lu
|
||||||
|
proc->cpuTime = fast_str2ull(&location);
|
||||||
|
location += 1;
|
||||||
|
|
||||||
|
// (15) stime - %lu
|
||||||
|
proc->cpuTime += fast_str2ull(&location);
|
||||||
|
location += 1;
|
||||||
|
|
||||||
|
// (16) cutime - %lu
|
||||||
|
proc->childCpuTime = fast_str2ull(&location);
|
||||||
|
location += 1;
|
||||||
|
|
||||||
|
// (17) cstime - %lu
|
||||||
|
proc->childCpuTime += fast_str2ull(&location);
|
||||||
|
location += 1;
|
||||||
|
|
||||||
|
// skip 18-19
|
||||||
|
skipRange(18, 20);
|
||||||
|
|
||||||
|
// (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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
struct dirent *pDirent;
|
struct dirent *pDirent;
|
||||||
@ -31,14 +137,24 @@ int main(int argc, char *argv[]) {
|
|||||||
char *fname = malloc(1024);
|
char *fname = malloc(1024);
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
|
Process *cur = malloc(sizeof(Process));
|
||||||
|
cur->label = malloc(256);
|
||||||
|
Process *head = cur;
|
||||||
|
|
||||||
while ((pDirent = readdir(pDir)) != NULL) {
|
while ((pDirent = readdir(pDir)) != NULL) {
|
||||||
char first = pDirent->d_name[0];
|
char first = pDirent->d_name[0];
|
||||||
if (first < '0' || first > '9') continue;
|
if (first < '0' || first > '9') continue;
|
||||||
sprintf(fname, "/proc/%s/stat", pDirent->d_name);
|
sprintf(fname, "/proc/%s/stat", pDirent->d_name);
|
||||||
file = fopen(fname, "rb");
|
file = fopen(fname, "rb");
|
||||||
fread(filedata, 1, 4096, file);
|
fread(filedata, 1, 4096, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
if (parseStatFile(cur, filedata)) continue;
|
||||||
|
cur->next = malloc(sizeof(Process));
|
||||||
|
cur->next->label = malloc(256);
|
||||||
|
cur->next->prev = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
|
||||||
strcat(fname, "us");
|
strcat(fname, "us");
|
||||||
file = fopen(fname, "rb");
|
file = fopen(fname, "rb");
|
||||||
fread(filedata, 1, 4096, file);
|
fread(filedata, 1, 4096, file);
|
||||||
@ -47,6 +163,18 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("[%s]\n", filedata);
|
printf("[%s]\n", filedata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cur = cur->prev;
|
||||||
|
free(cur->next);
|
||||||
|
cur->next = NULL;
|
||||||
|
|
||||||
|
int clocks = sysconf(_SC_CLK_TCK);
|
||||||
|
|
||||||
|
cur = head;
|
||||||
|
while (cur != NULL) {
|
||||||
|
printf("proc_cpu_time{pid=\"%d\",ppid=\"%d\",label=\"%s\"} %d\n", cur->pid, cur->ppid, cur->label, cur->cpuTime);
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
// Close directory and exit.
|
// Close directory and exit.
|
||||||
|
|
||||||
closedir(pDir);
|
closedir(pDir);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user