@cryptotaxi247 / netdata-1 / commits / 7ee3c016f

various apps.plugin fixes - now it detects new processes on the fly; attempt to work around the huge page minor page faults of bash, without success

Costa Tsaousis (ktsaou) committed May 6, 2014 at 02:59 UTC 7ee3c016f16e650dee9b7f42dcac438d74ffc6cb
3 files changed +187 -60
apps_plugin.c
+82 -45
@@ -22,6 +22,7 @@
22 #include <arpa/inet.h>
23
24 #define MAX_COMPARE_NAME 15
25 +#define MAX_NAME 100
26
27
28 #define add_childs 1ULL
@@ -33,8 +34,8 @@ int debug = 0;
34
35 struct wanted {
36 char compare[MAX_COMPARE_NAME + 3];
36 - char id[FILENAME_MAX+1];
37 - char name[FILENAME_MAX+1];
37 + char id[MAX_NAME + 1];
38 + char name[MAX_NAME + 1];
39
40 unsigned long long minflt;
41 unsigned long long cminflt;
@@ -48,10 +49,11 @@ struct wanted {
49 unsigned long long rss;
50
51 unsigned long merge_count; // how many processes have been merged to this
52 + int exposed; // if set, we have sent this to netdata
53
54 struct wanted *target; // the one that will be reported to netdata
55 struct wanted *next;
54 -} *wanted_root = NULL;
56 +} *wanted_root = NULL, *default_target = NULL;
57
58 int update_every = 1;
59
@@ -63,8 +65,8 @@ struct wanted *add_wanted(const char *id, struct wanted *target)
65 return NULL;
66 }
67
66 - strncpy(w->id, id, FILENAME_MAX);
67 - strncpy(w->name, id, FILENAME_MAX);
68 + strncpy(w->id, id, MAX_NAME);
69 + strncpy(w->name, id, MAX_NAME);
70 snprintf(w->compare, MAX_COMPARE_NAME+1, "(%.*s)", MAX_COMPARE_NAME, id);
71 w->target = target;
72
@@ -99,7 +101,7 @@ void parse_args(int argc, char **argv)
101
102 while((t = strsep(&s, " "))) {
103 if(w && strcmp(t, "as") == 0 && s && *s) {
102 - strncpy(w->name, s, FILENAME_MAX);
104 + strncpy(w->name, s, MAX_NAME);
105 if(debug) fprintf(stderr, "Setting dimension name to '%s' on target '%s'\n", w->name, w->id);
106 break;
107 }
@@ -108,12 +110,15 @@ void parse_args(int argc, char **argv)
110 if(!w) w = n;
111 }
112 }
113 +
114 + default_target = add_wanted("all_other_processes", NULL);
115 + strncpy(default_target->name, "other", MAX_NAME);
116 }
117
118 // see: man proc
119 struct pid_stat {
120 int32_t pid;
116 - char comm[FILENAME_MAX+1];
121 + char comm[MAX_COMPARE_NAME + 3];
122 char state;
123 int32_t ppid;
124 int32_t pgrp;
@@ -163,6 +168,7 @@ struct pid_stat {
168 int new_entry;
169 unsigned long merge_count;
170 struct wanted *target;
171 + int target_inherited;
172 struct pid_stat *parent;
173 struct pid_stat *prev;
174 struct pid_stat *next;
@@ -209,6 +215,7 @@ void del_entry(pid_t pid)
215 int update_from_proc(void)
216 {
217 char buffer[PID_STAT_LINE_MAX + 1];
218 + char name[PID_STAT_LINE_MAX + 1];
219 char filename[FILENAME_MAX+1];
220 DIR *dir = opendir("/proc");
221 if(!dir) return 0;
@@ -224,6 +231,8 @@ int update_from_proc(void)
231 p->merged = 0;
232 p->new_entry = 0;
233 p->merge_count = 0;
234 +
235 + if(p->target_inherited) p->target = NULL;
236 }
237
238 while((file = readdir(dir))) {
@@ -269,7 +278,7 @@ int update_from_proc(void)
278 " %d %d" // exit_signal, processor
279 " %u %u" // rt_priority, policy
280 " %llu %lu %ld"
272 - , &p->pid, p->comm, &p->state
281 + , &p->pid, name, &p->state
282 , &p->ppid, &p->pgrp, &p->session, &p->tty_nr, &p->tpgid
283 , &p->flags, &p->minflt, &p->cminflt, &p->majflt, &p->cmajflt
284 , &p->utime, &p->stime, &p->cutime, &p->cstime
@@ -286,6 +295,8 @@ int update_from_proc(void)
295 , &p->rt_priority, &p->policy
296 , &p->delayacct_blkio_ticks, &p->guest_time, &p->cguest_time
297 );
298 + strncpy(p->comm, name, MAX_COMPARE_NAME + 2);
299 + p->comm[MAX_COMPARE_NAME + 2] = '\0';
300
301 if(parsed < 39) fprintf(stderr, "file %s gave %d results (expected 44)\n", filename, parsed);
302
@@ -335,7 +346,7 @@ void merge_processes(void)
346 {
347 struct pid_stat *p = NULL;
348
338 - // link all parents and update childs
349 + // link all parents and update childs count
350 for(p = root; p ; p = p->next) {
351 if(p->ppid > 1 && p->ppid <= pid_max && all_pids[p->ppid]) {
352 if(debug) fprintf(stderr, "\tParent of %d %s is %d %s\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm);
@@ -350,13 +361,18 @@ void merge_processes(void)
361 }
362 }
363
353 - // find all the procs with 0 childs and update their parents
354 - // continue, until nothing more can be done.
364 + // find all the procs with 0 childs and merge them to their parents
365 + // repeat, until nothing more can be done.
366 int found = 1;
367 for( ; found ; ) {
368 found = 0;
369 for(p = root; p ; p = p->next) {
359 - if(!p->childs && !p->merged && p->parent && p->parent->childs) {
370 + // if this process does not any childs, and
371 + // is not already merged, and
372 + // its parents has childs waiting to be merged, and
373 + // the target of this process and its parent is the same, or the parent does not have a target, or this process does not have a parent
374 + // then... merge them!
375 + if(!p->childs && !p->merged && p->parent && p->parent->childs && (p->target == p->parent->target || !p->parent->target || !p->target)) {
376 if(debug) fprintf(stderr, "\tMerging %d %s to %d %s (count: %lu)\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm, p->parent->merge_count+1);
377
378 p->parent->minflt += p->minflt;
@@ -380,7 +396,8 @@ void merge_processes(void)
396 // the parent inherits the child's target, if it does not have a target itself
397 if(p->target && !p->parent->target) {
398 p->parent->target = p->target;
383 - if(debug) fprintf(stderr, "\t\ttarget %s is inherited from %d %s by its child %d %s.\n", p->target->name, p->parent->pid, p->parent->comm, p->pid, p->comm);
399 + p->parent->target_inherited = 1;
400 + if(debug) fprintf(stderr, "\t\ttarget %s is inherited by %d %s from its child %d %s.\n", p->target->name, p->parent->pid, p->parent->comm, p->pid, p->comm);
401 }
402
403 found++;
@@ -416,21 +433,29 @@ void merge_processes(void)
433
434 // concentrate everything on the targets
435 for(p = root; p ; p = p->next) {
419 - if(!p->childs && !p->merged && !p->parent && p->target) {
420 - p->target->minflt += p->minflt;
421 - p->target->majflt += p->majflt;
422 - p->target->utime += p->utime;
423 - p->target->stime += p->stime;
424 - p->target->cminflt += p->cminflt;
425 - p->target->cmajflt += p->cmajflt;
426 - p->target->cutime += p->cutime;
427 - p->target->cstime += p->cstime;
428 - p->target->num_threads += p->num_threads;
429 - p->target->rss += p->rss;
430 -
431 - p->target->merge_count += p->merge_count + 1;
432 - if(debug) fprintf(stderr, "\tAgregating %s pid %d on %s (count: %lu)\n", p->comm, p->pid, p->target->name, p->target->merge_count);
436 + if(p->parent && !p->merged) fprintf(stderr, "\tprocess %s pid %d has a parent, but has not been merged!\n", p->comm, p->pid);
437 + if(p->childs) fprintf(stderr, "\tprocess %s pid %d has %d childs that have not been merged!\n", p->comm, p->pid, p->childs);
438 + if(p->merged) continue;
439 +
440 + if(!p->target) {
441 + p->target = default_target;
442 + p->target_inherited = 1;
443 + if(debug) fprintf(stderr, "\tprocess %s pid %d is orphan\n", p->comm, p->pid);
444 }
445 +
446 + p->target->minflt += p->minflt;
447 + p->target->majflt += p->majflt;
448 + p->target->utime += p->utime;
449 + p->target->stime += p->stime;
450 + p->target->cminflt += p->cminflt;
451 + p->target->cmajflt += p->cmajflt;
452 + p->target->cutime += p->cutime;
453 + p->target->cstime += p->cstime;
454 + p->target->num_threads += p->num_threads;
455 + p->target->rss += p->rss;
456 +
457 + p->target->merge_count += p->merge_count + 1;
458 + if(debug) fprintf(stderr, "\tAgregating %s pid %d on %s (count: %lu)\n", p->comm, p->pid, p->target->name, p->target->merge_count);
459 }
460 }
461
@@ -441,7 +466,7 @@ void show_dimensions(void)
466
467 fprintf(stdout, "BEGIN apps.cpu\n");
468 for (w = wanted_root; w ; w = w->next) {
444 - if(w->target) continue;
469 + if(w->target || (!w->merge_count && !w->exposed)) continue;
470
471 fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime + (w->cutime * add_childs) + (w->cstime * add_childs));
472 }
@@ -449,7 +474,7 @@ void show_dimensions(void)
474
475 fprintf(stdout, "BEGIN apps.cpu_user\n");
476 for (w = wanted_root; w ; w = w->next) {
452 - if(w->target) continue;
477 + if(w->target || (!w->merge_count && !w->exposed)) continue;
478
479 fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + (w->cutime * add_childs));
480 }
@@ -457,7 +482,7 @@ void show_dimensions(void)
482
483 fprintf(stdout, "BEGIN apps.cpu_system\n");
484 for (w = wanted_root; w ; w = w->next) {
460 - if(w->target) continue;
485 + if(w->target || (!w->merge_count && !w->exposed)) continue;
486
487 fprintf(stdout, "SET %s = %llu\n", w->name, w->stime + (w->cstime * add_childs));
488 }
@@ -465,7 +490,7 @@ void show_dimensions(void)
490
491 fprintf(stdout, "BEGIN apps.threads\n");
492 for (w = wanted_root; w ; w = w->next) {
468 - if(w->target) continue;
493 + if(w->target || (!w->merge_count && !w->exposed)) continue;
494
495 fprintf(stdout, "SET %s = %llu\n", w->name, w->num_threads);
496 }
@@ -473,7 +498,7 @@ void show_dimensions(void)
498
499 fprintf(stdout, "BEGIN apps.processes\n");
500 for (w = wanted_root; w ; w = w->next) {
476 - if(w->target) continue;
501 + if(w->target || (!w->merge_count && !w->exposed)) continue;
502
503 fprintf(stdout, "SET %s = %lu\n", w->name, w->merge_count);
504 }
@@ -481,7 +506,7 @@ void show_dimensions(void)
506
507 fprintf(stdout, "BEGIN apps.rss\n");
508 for (w = wanted_root; w ; w = w->next) {
484 - if(w->target) continue;
509 + if(w->target || (!w->merge_count && !w->exposed)) continue;
510
511 fprintf(stdout, "SET %s = %llu\n", w->name, (unsigned long long)w->rss);
512 }
@@ -489,7 +514,7 @@ void show_dimensions(void)
514
515 fprintf(stdout, "BEGIN apps.minor_faults\n");
516 for (w = wanted_root; w ; w = w->next) {
492 - if(w->target) continue;
517 + if(w->target || (!w->merge_count && !w->exposed)) continue;
518
519 fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt + (w->cminflt * add_childs));
520 }
@@ -497,7 +522,7 @@ void show_dimensions(void)
522
523 fprintf(stdout, "BEGIN apps.major_faults\n");
524 for (w = wanted_root; w ; w = w->next) {
500 - if(w->target) continue;
525 + if(w->target || (!w->merge_count && !w->exposed)) continue;
526
527 fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt + (w->cmajflt * add_childs));
528 }
@@ -509,59 +534,72 @@ void show_dimensions(void)
534 void show_charts(void)
535 {
536 struct wanted *w;
537 + int newly_added = 0;
538
539 + for(w = wanted_root ; w ; w = w->next)
540 + if(!w->exposed && w->merge_count) {
541 + newly_added++;
542 + w->exposed = 1;
543 + if(debug) fprintf(stderr, "%s just added - regenerating charts.\n", w->name);
544 + }
545 +
546 + // nothing more to show
547 + if(!newly_added) return;
548 +
549 + // we have something new to show
550 + // update the charts
551 fprintf(stdout, "CHART apps.cpu '' 'Applications CPU Time' 'cpu time %%' apps apps stacked 20001 %d\n", update_every);
552 for (w = wanted_root; w ; w = w->next) {
515 - if(w->target) continue;
553 + if(w->target || (!w->merge_count && !w->exposed)) continue;
554
555 fprintf(stdout, "DIMENSION %s '' incremental 100 %llu\n", w->name, Hertz);
556 }
557
558 fprintf(stdout, "CHART apps.rss '' 'Applications Memory' 'MB' apps apps stacked 20002 %d\n", update_every);
559 for (w = wanted_root; w ; w = w->next) {
522 - if(w->target) continue;
560 + if(w->target || (!w->merge_count && !w->exposed)) continue;
561
562 fprintf(stdout, "DIMENSION %s '' absolute %ld %ld\n", w->name, sysconf(_SC_PAGESIZE), 1024L*1024L);
563 }
564
565 fprintf(stdout, "CHART apps.threads '' 'Applications Threads' 'threads' apps apps stacked 20005 %d\n", update_every);
566 for (w = wanted_root; w ; w = w->next) {
529 - if(w->target) continue;
567 + if(w->target || (!w->merge_count && !w->exposed)) continue;
568
569 fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
570 }
571
572 fprintf(stdout, "CHART apps.processes '' 'Applications Processes' 'processes' apps apps stacked 20004 %d\n", update_every);
573 for (w = wanted_root; w ; w = w->next) {
536 - if(w->target) continue;
574 + if(w->target || (!w->merge_count && !w->exposed)) continue;
575
576 fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
577 }
578
579 fprintf(stdout, "CHART apps.cpu_user '' 'Applications CPU User Time' 'cpu time %%' apps none stacked 20020 %d\n", update_every);
580 for (w = wanted_root; w ; w = w->next) {
543 - if(w->target) continue;
581 + if(w->target || (!w->merge_count && !w->exposed)) continue;
582
583 fprintf(stdout, "DIMENSION %s '' incremental 100 %llu\n", w->name, Hertz);
584 }
585
586 fprintf(stdout, "CHART apps.cpu_system '' 'Applications CPU System Time' 'cpu time %%' apps none stacked 20021 %d\n", update_every);
587 for (w = wanted_root; w ; w = w->next) {
550 - if(w->target) continue;
588 + if(w->target || (!w->merge_count && !w->exposed)) continue;
589
590 fprintf(stdout, "DIMENSION %s '' incremental 100 %llu\n", w->name, Hertz);
591 }
592
593 fprintf(stdout, "CHART apps.major_faults '' 'Applications Major Page Faults' 'page faults/s' apps apps stacked 20010 %d\n", update_every);
594 for (w = wanted_root; w ; w = w->next) {
557 - if(w->target) continue;
595 + if(w->target || (!w->merge_count && !w->exposed)) continue;
596
597 fprintf(stdout, "DIMENSION %s '' incremental 1 1\n", w->name);
598 }
599
600 fprintf(stdout, "CHART apps.minor_faults '' 'Applications Minor Page Faults' 'page faults/s' apps apps stacked 20011 %d\n", update_every);
601 for (w = wanted_root; w ; w = w->next) {
564 - if(w->target) continue;
602 + if(w->target || (!w->merge_count && !w->exposed)) continue;
603
604 fprintf(stdout, "DIMENSION %s '' incremental 1 1\n", w->name);
605 }
@@ -633,8 +671,6 @@ int main(int argc, char **argv)
671 exit(1);
672 }
673
636 - show_charts();
637 -
674 unsigned long long counter = 1;
675 unsigned long long usec = 0, susec = 0;
676 struct timeval last, now;
@@ -648,6 +684,7 @@ int main(int argc, char **argv)
684 }
685
686 merge_processes();
687 + show_charts(); // this is smart enough to show only newly added apps, when needed
688 show_dimensions();
689
690 if(debug) fprintf(stderr, "Done Loop No %llu\n", counter);
netdata.c
+87 -13
@@ -313,15 +313,38 @@ FILE *mypopen(const char *command, pid_t *pidptr)
313 for(i = sysconf(_SC_OPEN_MAX); i > 0; i--)
314 if(i != STDIN_FILENO && i != STDERR_FILENO && i != pipefd[PIPE_WRITE]) close(i);
315
316 - // ignore all signals
317 - for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV) signal(i, SIG_DFL);
318 -
316 // move the pipe to stdout
317 if(pipefd[PIPE_WRITE] != STDOUT_FILENO) {
318 dup2(pipefd[PIPE_WRITE], STDOUT_FILENO);
319 close(pipefd[PIPE_WRITE]);
320 }
321
322 +/*
323 + // fork again to become session leader
324 + pid = fork();
325 + if(pid == -1) fprintf(stderr, "Cannot fork again on pid %d\n", getpid());
326 + if(pid != 0) {
327 + // the parent
328 + exit(0);
329 + }
330 +
331 + // set a new process group id for just this child
332 + if( setpgid(0, 0) != 0 )
333 + fprintf(stderr, "Cannot set a new process group for pid %d (%s)\n", getpid(), strerror(errno));
334 +
335 + if( getpgid(0) != getpid() )
336 + fprintf(stderr, "Process group set is incorrect. Expected %d, found %d\n", getpid(), getpgid(0));
337 +
338 + if( setsid() != 0 )
339 + fprintf(stderr, "Cannot set session id for pid %d (%s)\n", getpid(), strerror(errno));
340 +*/
341 +
342 + // ignore all signals
343 + for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV) signal(i, SIG_DFL);
344 +
345 + fprintf(stdout, "MYPID %d\n", getpid());
346 + fflush(NULL);
347 +
348 fprintf(stderr, "executing command: '%s'\n", command);
349 execl("/bin/sh", "sh", "-c", command, NULL);
350 exit(1);
@@ -5533,6 +5556,8 @@ void *tc_main(void *ptr)
5556 if(pid != tc_child_pid)
5557 error("tc-qos-helper reports wrong pid %d (expected %d).", pid, tc_child_pid);
5558
5559 + // tc_child_pid = pid;
5560 +
5561 debug(D_TC_LOOP, "TC: Child PID is %d.", tc_child_pid);
5562 }
5563 }
@@ -5664,6 +5689,9 @@ void *pluginsd_worker_thread(void *arg)
5689 struct plugind *cd = (struct plugind *)arg;
5690 char line[PLUGINSD_LINE_MAX + 1];
5691
5692 + unsigned long long usec = 0, susec = 0;
5693 + struct timeval last, now;
5694 +
5695 while(1) {
5696 // FILE *fp = popen(cd->cmd, "r");
5697 FILE *fp = mypopen(cd->cmd, &cd->pid);
@@ -5863,6 +5891,7 @@ void *pluginsd_worker_thread(void *arg)
5891 kill(cd->pid, SIGTERM);
5892 break;
5893 }
5894 + // cd->pid = pid;
5895
5896 debug(D_PLUGINSD, "PLUGINSD: %s is on pid %d", cd->id, cd->pid);
5897 }
@@ -5872,6 +5901,28 @@ void *pluginsd_worker_thread(void *arg)
5901 kill(cd->pid, SIGTERM);
5902 break;
5903 }
5904 + else if(!strcmp(s, "STOPPING_WAKE_ME_UP_PLEASE")) {
5905 + error("PLUGINSD: script '%s' (pid %d) called STOPPING_WAKE_ME_UP_PLEASE.", cd->fullfilename, cd->pid);
5906 +
5907 + gettimeofday(&now, NULL);
5908 + if(!usec && !susec) {
5909 + // our first run
5910 + susec = cd->update_every * 1000000ULL;
5911 + }
5912 + else {
5913 + // second+ run
5914 + usec = usecdiff(&now, &last) - susec;
5915 + error("PLUGINSD: %s last loop took %llu usec (worked for %llu, sleeped for %llu).\n", cd->fullfilename, usec + susec, usec, susec);
5916 + if(usec < (update_every * 1000000ULL)) susec = (update_every * 1000000ULL) - usec;
5917 + else susec = 100000ULL;
5918 + }
5919 +
5920 + error("PLUGINSD: %s sleeping for %llu. Will kill pid %d to wake it up.\n", cd->fullfilename, susec, cd->pid);
5921 + usleep(susec);
5922 + kill(cd->pid, SIGCONT);
5923 + bcopy(&now, &last, sizeof(struct timeval));
5924 + break;
5925 + }
5926 else {
5927 error("PLUGINSD: script %s is sending command '%s' which is not known by netdata. Disabling it.", cd->fullfilename, s);
5928 cd->enabled = 0;
@@ -5961,7 +6012,39 @@ void *pluginsd_main(void *ptr)
6012 cd->update_every = config_get_number(cd->id, "update every", update_every);
6013
6014 char *def = "";
5964 - if(strcmp(cd->id, "plugin:apps") == 0) def = "mplayer squid 'apache apache2 as apache' mysqld asterisk dovecot 'master as postfix' 'smbd nmbd as samba' sshd 'gdm as X' named 'clamd freshclam as clam' 'cupsd as cups' 'ntpd as ntp' 'deluge deluged as deluge' netdata";
6015 + if(strcmp(cd->id, "plugin:apps") == 0)
6016 + def =
6017 + " 'mplayer vlc xine mediatomb as media'"
6018 + " 'squid squid3 as squid'"
6019 + " 'apache apache2 as apache'"
6020 + " 'mysql mysqld as mysql'"
6021 + " asterisk"
6022 + " opensips"
6023 + " dovecot"
6024 + " nginx"
6025 + " lighttpd"
6026 + " 'proftpd in.tftpd as ftpd'"
6027 + " 'master as postfix'"
6028 + " 'smbd nmbd winbindd as samba'"
6029 + " 'rpcbind rpc.statd rpc.idmapd rpc.mountd as nfs'"
6030 + " 'ssh sshd as ssh'"
6031 + " 'gdm X lightdm xdm gnome-session gconfd-2 gnome-terminal gnome-screensaver gnome-settings-daemon pulseaudio as X'"
6032 + " 'named as bind'"
6033 + " 'clamd freshclam as clam'"
6034 + " 'cupsd cups-browsed as cups'"
6035 + " 'ntpq ntpd as ntp'"
6036 + " 'deluge deluged as deluge'"
6037 + " 'vboxwebsrv VBoxXPCOMIPCD VBoxSVC as vbox'"
6038 + " 'ulogd syslogd syslog-ng rsyslogd logrotate as log'"
6039 + " 'snmpd vnstatd smokeping zabbix_agentd monit munin-node mon as nms'"
6040 + " 'ppp pppd pptpd pptpctrl as ppp'"
6041 + " 'inetd xinetd as inetd'"
6042 + " openvpn"
6043 + " 'cron atd as cron'"
6044 + " 'corosync hs_logd stonithd as ha'"
6045 + " 'ipvs_syncmaster ipvs_syncbackup as ipvs'"
6046 + " netdata"
6047 + ;
6048 snprintf(cd->cmd, PLUGINSD_CMD_MAX, "exec %s %d %s", cd->fullfilename, cd->update_every, config_get(cd->id, "command options", def));
6049
6050 // link it
@@ -6005,13 +6088,6 @@ void kill_childs()
6088 }
6089 }
6090
6008 -void bye(void)
6009 -{
6010 - error("exiting. bye...");
6011 - kill_childs();
6012 - tc_child_pid = 0;
6013 -}
6014 -
6091 void sig_handler(int signo)
6092 {
6093 switch(signo) {
@@ -6421,8 +6497,6 @@ int main(int argc, char **argv)
6497
6498 error("NetData started on pid %d", getpid());
6499
6424 - // make sure we cleanup correctly
6425 - atexit(bye);
6500
6501 // catch all signals
6502 for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV) signal(i, sig_handler);
plugins.d/charts.d.plugin
+18 -2
@@ -3,6 +3,10 @@
3 # -----------------------------------------------------------------------------
4 # insternal defaults
5
6 +pause_method="sleep" # use either "suspend" or "sleep"
7 + # DO NOT USE SUSPEND - LINUX WILL SUSPEND NETDATA TOO
8 + # THE WHOLE PROCESS GROUP - NOT JUST THE SHELL
9 +
10 pluginsd="plugins.d"
11 confd="conf.d"
12 chartsd="charts.d"
@@ -86,6 +90,12 @@ if [ -f "$myconfig" ]
90 fi
91 fi
92
93 +if [ "$pause_method" = "suspend" ]
94 +then
95 + # enable bash job control
96 + # this is required for suspend to work
97 + set -m
98 +fi
99
100 # -----------------------------------------------------------------------------
101 # internal checks
@@ -275,6 +285,12 @@ do
285 fi
286 done
287
278 - # wait the time you are required to
279 - loopsleepms $debug_time $update_every
288 + if [ "$pause_method" = "suspend" ]
289 + then
290 + echo "STOPPING_WAKE_ME_UP_PLEASE"
291 + suspend || ( echo >&2 "suspend returned error $?, falling back to sleep."; loopsleepms $debug_time $update_every )
292 + else
293 + # wait the time you are required to
294 + loopsleepms $debug_time $update_every
295 + fi
296 done