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