int acquire() { /* fork ourselves if not asked otherwise */ char* no_fork = getenv("no_fork"); if (! no_fork || strcmp("1", no_fork)) { if (fork()) return; // we are the child, complete the daemonization /* Close standard IO */ fclose(stdin); fclose(stdout); fclose(stderr); /* create new session and process group */ setsid(); } /* write the pid */ FILE* pid_file = fopen(pid_filename, "w"); fprintf(pid_file, "%d\n", getpid()); fclose(pid_file); /* loop each second */ while (1) { /* wait until next second */ time_t epoch = wait_until_next_second(); /* Reading /proc/stat */ FILE* f = fopen(PROC_STAT, "r"); // Read and ignore the 1rst line char buffer[1024]; fgets(buffer, 1024, f); /* open the spoolfile */ FILE* cache_file = fopen(cache_filename, "a"); /* lock */ flock(fileno(cache_file), LOCK_EX); while (! feof(f)) { if (fgets(buffer, 1024, f) == 0) { // EOF break; } // Not on CPU lines anymore if (strncmp(buffer, "cpu", 3)) break; char cpu_id[64]; long usr, nice, sys, idle, iowait, irq, softirq; sscanf(buffer, "%s %ld %ld %ld %ld %ld %ld %ld", cpu_id, &usr, &nice, &sys, &idle, &iowait, &irq, &softirq); long used = usr + nice + sys + iowait + irq + softirq; fprintf(cache_file, "%s.value %ld:%ld\n", cpu_id, epoch, used); } fclose(cache_file); fclose(f); } }
int acquire() { /* fork ourselves if not asked otherwise */ char* no_fork = getenv("no_fork"); if (! no_fork || strcmp("1", no_fork)) { if (fork()) return; // we are the child, complete the daemonization /* Close standard IO */ fclose(stdin); fclose(stdout); fclose(stderr); /* create new session and process group */ setsid(); } /* write the pid */ FILE* pid_file = fopen(pid_filename, "w"); fprintf(pid_file, "%d\n", getpid()); fclose(pid_file); /* Reading /proc/stat */ int f = open(PROC_STAT, O_RDONLY); /* open the spoolfile */ int cache_file = open(cache_filename, O_CREAT | O_APPEND | O_WRONLY); /* loop each second */ while (1) { /* wait until next second */ time_t epoch = wait_until_next_second(); const int buffer_size = 64 * 1024; char buffer[buffer_size]; if (lseek(f, 0, SEEK_SET) < 0) { return fail("cannot seek " PROC_STAT); } // whole /proc/stat can be read in 1 syscall if (read(f, buffer, buffer_size) <= 0) { return fail("cannot read " PROC_STAT); } // ignore the 1rst line char* line; const char* newl = "\n"; line = strtok(buffer, newl); /* lock */ flock(cache_file, LOCK_EX); for (line = strtok(NULL, newl); line; line = strtok(NULL, newl)) { // Not on CPU lines anymore if (strncmp(line, "cpu", 3)) break; char cpu_id[64]; long usr, nice, sys, idle, iowait, irq, softirq; sscanf(line, "%s %ld %ld %ld %ld %ld %ld %ld", cpu_id, &usr, &nice, &sys, &idle, &iowait, &irq, &softirq); long used = usr + nice + sys + iowait + irq + softirq; char out_buffer[1024]; sprintf(out_buffer, "%s.value %ld:%ld\n", cpu_id, epoch, used); write(cache_file, out_buffer, strlen(out_buffer)); } /* unlock */ flock(cache_file, LOCK_UN); } close(cache_file); close(f); return 0; }
int acquire() { /* fork ourselves if not asked otherwise */ char* no_fork = getenv("no_fork"); if (! no_fork || strcmp("1", no_fork)) { pid_t child_pid = fork(); if (child_pid) { printf("# acquire() launched as PID %d\n", child_pid); return 0; } // we are the child, complete the daemonization /* Close standard IO */ fclose(stdin); fclose(stdout); fclose(stderr); /* create new session and process group */ setsid(); } /* write the pid */ FILE* pid_file = fopen(pid_filename, "w"); fprintf(pid_file, "%d\n", getpid()); fclose(pid_file); /* Reading /proc/stat */ int f = open(PROC_STAT, O_RDONLY); if ( f == -1 ) { return fail("cannot open " PROC_STAT); } /* open the spoolfile */ int cache_file = open(cache_filename, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR); if ( cache_file == -1 ) { return fail("# cannot open cache_file"); } /* loop each second */ while (1) { /* wait until next second */ time_t epoch = wait_until_next_second(); const int buffer_size = 64 * 1024; char buffer[buffer_size]; if (lseek(f, 0, SEEK_SET) < 0) { return fail("cannot seek " PROC_STAT); } // whole PROC file can be read in 1 syscall if (read(f, buffer, buffer_size) <= 0) { return fail("cannot read " PROC_STAT); } // ignore the 1rst line char* line; char *saveptr; const char* newl = "\n"; /* lock */ flock(cache_file, LOCK_EX); int nif = -2; for (line = strtok_r(buffer, newl, &saveptr); line; line = strtok_r(NULL, newl, &saveptr)) { // Skip the header lines if (nif ++ < 0) { continue; } char if_id[64]; uint_fast64_t r_bytes, r_packets, r_errs, r_drop, r_fifo, r_frame, r_compressed, r_multicast; uint_fast64_t t_bytes, t_packets, t_errs, t_drop, t_fifo, t_frame, t_compressed, t_multicast; sscanf(line, "%s" " " "%llu %llu %llu %llu %llu %llu %llu %llu" " " "%llu %llu %llu %llu %llu %llu %llu %llu" , if_id , &r_bytes, &r_packets, &r_errs, &r_drop, &r_fifo, &r_frame, &r_compressed, &r_multicast , &t_bytes, &t_packets, &t_errs, &t_drop, &t_fifo, &t_frame, &t_compressed, &t_multicast ); // Remove trailing ':' of if_id if_id[strlen(if_id) - 1] = '\0'; char out_buffer[1024]; sprintf(out_buffer, "multigraph if_%s_1sec" "\n" "up.value %ld:%llu" "\n" "down.value %ld:%llu" "\n" , if_id , epoch, r_bytes , epoch, t_bytes ); write(cache_file, out_buffer, strlen(out_buffer)); } /* unlock */ flock(cache_file, LOCK_UN); } close(cache_file); close(f); return 0; }