@cryptotaxi247 / netdata-1 / commits / c227f68b6

added debug log and flags in command line; various fixes and more debugging info

Costa Tsaousis (ktsaou) committed Apr 23, 2014 at 02:40 UTC c227f68b697668375e4fcda874c628021015c20e
2 files changed +90 -48
netdata.c
+86 -46
@@ -103,11 +103,15 @@
103 #define CT_APPLICATION_VND_MS_FONTOBJ 13
104 #define CT_IMAGE_SVG_XML 14
105
106 -// configuration
106 +
107 #define DEBUG (D_WEB_CLIENT_ACCESS|D_LISTENER|D_RRD_STATS)
108 //#define DEBUG 0xffffffff
109 //#define DEBUG (0)
110
111 +unsigned long long debug_flags = DEBUG;
112 +char *debug_log = NULL;
113 +int debug_fd = -1;
114 +
115 #define EXIT_FAILURE 1
116 #define LISTEN_BACKLOG 100
117
@@ -169,7 +173,7 @@ void debug_int( const char *file, const char *function, const unsigned long line
173
174 va_list args;
175
172 - if(DEBUG & type) {
176 + if(debug_flags & type) {
177 log_date();
178 va_start( args, fmt );
179 fprintf(stderr, "DEBUG (%04lu@%-15.15s): ", line, function);
@@ -706,12 +710,14 @@ int rrd_stats_dimension_set(RRD_STATS *st, char *id, void *data, void *obsolete)
710 return 0;
711 }
712
709 -void rrd_stats_next(RRD_STATS *st)
713 +unsigned long long rrd_stats_next(RRD_STATS *st)
714 {
711 - struct timeval *now;
715 + struct timeval *now, *old;
716
717 pthread_mutex_lock(&st->mutex);
718
719 + old = &st->times[st->current_entry];
720 +
721 // st->current_entry should never be outside the array
722 // or, the parallel threads may end up crashing
723 // st->last_entry = st->current_entry;
@@ -723,6 +729,8 @@ void rrd_stats_next(RRD_STATS *st)
729 st->last_updated = now->tv_sec;
730
731 // leave mutex locked
732 +
733 + return usecdiff(now, old);
734 }
735
736 void rrd_stats_done(RRD_STATS *st)
@@ -1091,8 +1099,8 @@ unsigned long rrd_stats_json(int type, RRD_STATS *st, struct web_buffer *wb, siz
1099 }
1100
1101 // check the options
1094 - if(entries_to_show <= 0) entries_to_show = 1;
1095 - if(group_count <= 0) group_count = 1;
1102 + if(entries_to_show < 1) entries_to_show = 1;
1103 + if(group_count < 1) group_count = 1;
1104 // if(group_count > st->entries / 20) group_count = st->entries / 20;
1105
1106 size_t printed = 0; // the lines of JSON data we have generated so far
@@ -1180,7 +1188,16 @@ unsigned long rrd_stats_json(int type, RRD_STATS *st, struct web_buffer *wb, siz
1188 // to allow grouping on the same values, we need a pad
1189 long pad = before % group_count;
1190
1183 - // debug(D_RRD_STATS, "after = %lu, before = %lu, diff = %lu, pad = %ld, count = %ld, entries_to_show = %lu, group_count = %lu, current_entry = %lu, t = %lu", after, before, before - after, pad, count, entries_to_show, group_count, current_entry, t);
1191 + // checks for debuging
1192 + if(before < after)
1193 + error("WARNING: The newest value in the database (%lu) is earlier than the oldest (%lu)", before, after);
1194 +
1195 + if((before - after) > st->entries * update_every)
1196 + error("WARNING: The time difference between the oldest and the newest entries (%lu) is higher than the capacity of the database (%lu)", before - after, st->entries * update_every);
1197 +
1198 + // we need these at the end for debugging
1199 + long count_start = count;
1200 + size_t t_start = t;
1201
1202 // the loop in dimension data
1203 int annotate_reset = 0;
@@ -1197,14 +1214,14 @@ unsigned long rrd_stats_json(int type, RRD_STATS *st, struct web_buffer *wb, siz
1214 web_buffer_increase(wb, line_size);
1215
1216 // prefer the most recent last entries
1200 - if(((count-pad) / group_count) >= entries_to_show) continue;
1217 + if(((count - pad) / group_count) >= entries_to_show) continue;
1218
1219 // ok. we will use this entry!
1220 // find how much usec since the previous entry
1221
1222 usec = usecdiff(&st->times[t], &st->times[lt]);
1223
1207 - if(((count-pad) % group_count) == 0) {
1224 + if(((count - pad) % group_count) == 0) {
1225 if(printed >= entries_to_show) {
1226 // debug(D_RRD_STATS, "Already printed all rows. Stopping.");
1227 break;
@@ -1310,7 +1327,8 @@ unsigned long rrd_stats_json(int type, RRD_STATS *st, struct web_buffer *wb, siz
1327 if(printed) wb->bytes += sprintf(&wb->buffer[wb->bytes], "]}");
1328 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\n ]\n}\n");
1329
1313 - // debug(D_RRD_STATS, "last_timestamp = %lu", last_timestamp);
1330 + if(!printed)
1331 + error("WARNING: NOTHING PRINTED: %s, after = %lu, before = %lu, diff = %lu, pad = %ld, count = %ld, entries_to_show = %lu, group_count = %lu, current_entry = %lu, t = %lu", st->name, after, before, before - after, pad, count_start, entries_to_show, group_count, current_entry, t_start);
1332
1333 pthread_mutex_unlock(&st->mutex);
1334 return last_timestamp;
@@ -1547,14 +1565,14 @@ int web_client_data_request(struct web_client *w, char *url, int datasource_type
1565 // parse the lines required
1566 tok = mystrsep(&url, "/");
1567 if(tok) lines = atoi(tok);
1550 - if(lines < 5) lines = save_history;
1568 + if(lines < 1) lines = 1;
1569 }
1570 if(url) {
1571 // parse the group count required
1572 tok = mystrsep(&url, "/");
1573 if(tok) group_count = atoi(tok);
1574 if(group_count < 1) group_count = 1;
1557 - if(group_count > save_history / 20) group_count = save_history / 20;
1575 + //if(group_count > save_history / 20) group_count = save_history / 20;
1576 }
1577 if(url) {
1578 // parse the grouping method required
@@ -1643,7 +1661,7 @@ int web_client_data_request(struct web_client *w, char *url, int datasource_type
1661 google_responseHandler, google_version, google_reqId, st->last_updated);
1662 }
1663
1646 - debug(D_WEB_CLIENT_ACCESS, "%llu: Sending RRD data '%s' (id %s, %d lines, %d group_count, %d group_method).", w->id, st->name, st->id, lines, group_count, group_method);
1664 + debug(D_WEB_CLIENT_ACCESS, "%llu: Sending RRD data '%s' (id %s, %d lines, %d group, %d group_method, %lu after, %lu before).", w->id, st->name, st->id, lines, group_count, group_method, after, before);
1665 unsigned long timestamp_in_data = rrd_stats_json(datasource_type, st, w->data, lines, group_count, group_method, after, before);
1666
1667 if(datasource_type == DATASOURCE_GOOGLE_JSONP) {
@@ -2048,29 +2066,29 @@ void web_client_send_chunk_header(struct web_client *w, int len)
2066
2067 if(bytes > 0) debug(D_DEFLATE, "%llu: Sent chunk header %d bytes.", w->id, bytes);
2068 else if(bytes == 0) debug(D_DEFLATE, "%llu: Did not send chunk header to the client.", w->id);
2051 - else debug(D_DEFLATE, "%llu: Failed to send chunk header to client.", w->id);
2069 + else debug(D_DEFLATE, "%llu: Failed to send chunk header to client. Reason: %s", w->id, strerror(errno));
2070 }
2071
2072 void web_client_send_chunk_close(struct web_client *w)
2073 {
2056 - debug(D_DEFLATE, "%llu: CLOSE CHUNK.", w->id);
2074 + //debug(D_DEFLATE, "%llu: CLOSE CHUNK.", w->id);
2075
2076 int bytes = send(w->ofd, "\r\n", 2, MSG_DONTWAIT);
2077
2078 if(bytes > 0) debug(D_DEFLATE, "%llu: Sent chunk suffix %d bytes.", w->id, bytes);
2079 else if(bytes == 0) debug(D_DEFLATE, "%llu: Did not send chunk suffix to the client.", w->id);
2062 - else debug(D_DEFLATE, "%llu: Failed to send chunk suffix to client.", w->id);
2080 + else debug(D_DEFLATE, "%llu: Failed to send chunk suffix to client. Reason: %s", w->id, strerror(errno));
2081 }
2082
2083 void web_client_send_chunk_finalize(struct web_client *w)
2084 {
2067 - debug(D_DEFLATE, "%llu: FINALIZE CHUNK.", w->id);
2085 + //debug(D_DEFLATE, "%llu: FINALIZE CHUNK.", w->id);
2086
2087 int bytes = send(w->ofd, "\r\n0\r\n\r\n", 7, MSG_DONTWAIT);
2088
2089 if(bytes > 0) debug(D_DEFLATE, "%llu: Sent chunk suffix %d bytes.", w->id, bytes);
2090 else if(bytes == 0) debug(D_DEFLATE, "%llu: Did not send chunk suffix to the client.", w->id);
2073 - else debug(D_DEFLATE, "%llu: Failed to send chunk suffix to client.", w->id);
2091 + else debug(D_DEFLATE, "%llu: Failed to send chunk suffix to client. Reason: %s", w->id, strerror(errno));
2092 }
2093
2094 ssize_t web_client_send_deflate(struct web_client *w)
@@ -2080,7 +2098,7 @@ ssize_t web_client_send_deflate(struct web_client *w)
2098 // when using compression,
2099 // w->data->sent is the amount of bytes passed through compression
2100
2083 - debug(D_DEFLATE, "%llu: TEST w->data->bytes = %d, w->data->sent = %d, w->zhave = %d, w->zsent = %d, w->zstream.avail_in = %d, w->zstream.avail_out = %d, w->zstream.total_in = %d, w->zstream.total_out = %d.", w->id, w->data->bytes, w->data->sent, w->zhave, w->zsent, w->zstream.avail_in, w->zstream.avail_out, w->zstream.total_in, w->zstream.total_out);
2101 + // debug(D_DEFLATE, "%llu: TEST w->data->bytes = %d, w->data->sent = %d, w->zhave = %d, w->zsent = %d, w->zstream.avail_in = %d, w->zstream.avail_out = %d, w->zstream.total_in = %d, w->zstream.total_out = %d.", w->id, w->data->bytes, w->data->sent, w->zhave, w->zsent, w->zstream.avail_in, w->zstream.avail_out, w->zstream.total_in, w->zstream.total_out);
2102
2103 if(w->data->bytes - w->data->sent == 0 && w->zstream.avail_in == 0 && w->zhave == w->zsent && w->zstream.avail_out != 0) {
2104 // there is nothing to send
@@ -2168,7 +2186,7 @@ ssize_t web_client_send_deflate(struct web_client *w)
2186 debug(D_WEB_CLIENT, "%llu: Sent %d bytes.", w->id, bytes);
2187 }
2188 else if(bytes == 0) debug(D_WEB_CLIENT, "%llu: Did not send any bytes to the client.", w->id);
2171 - else debug(D_WEB_CLIENT, "%llu: Failed to send data to client.", w->id);
2189 + else debug(D_WEB_CLIENT, "%llu: Failed to send data to client. Reason: %s", w->id, strerror(errno));
2190
2191 return(bytes);
2192 }
@@ -2212,7 +2230,7 @@ ssize_t web_client_send(struct web_client *w)
2230 debug(D_WEB_CLIENT, "%llu: Sent %d bytes.", w->id, bytes);
2231 }
2232 else if(bytes == 0) debug(D_WEB_CLIENT, "%llu: Did not send any bytes to the client.", w->id);
2215 - else debug(D_WEB_CLIENT, "%llu: Failed to send data to client.", w->id);
2233 + else debug(D_WEB_CLIENT, "%llu: Failed to send data to client. Reason: %s", w->id, strerror(errno));
2234
2235
2236 return(bytes);
@@ -2302,7 +2320,7 @@ void *new_client(void *ptr)
2320 tv.tv_sec = 30;
2321 tv.tv_usec = 0;
2322
2305 - debug(D_WEB_CLIENT, "%llu: Waiting for input: %s, output: %s ...", w->id, w->wait_receive?"YES":"NO", w->wait_send?"YES":"NO");
2323 + debug(D_WEB_CLIENT, "%llu: Waiting socket async I/O for %s %s", w->id, w->wait_receive?"INPUT":"", w->wait_send?"OUTPUT":"");
2324 retval = select(fdmax+1, &ifds, &ofds, &efds, &tv);
2325
2326 if(retval == -1) {
@@ -2496,7 +2514,6 @@ int do_proc_net_dev() {
2514 c = strchr(buffer, ':');
2515 if(c) *c = '\t';
2516
2499 - // if(DEBUG) printf("%s\n", buffer);
2517 r = sscanf(buffer, "%s %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
2518 iface,
2519 &rbytes, &rpackets, &rerrors, &rdrops, &rfifo, &rframe, &rcompressed, &rmulticast,
@@ -2619,7 +2636,6 @@ int do_proc_diskstats() {
2636 p = fgets(buffer, MAX_PROC_DISKSTATS_LINE, fp);
2637 if(!p) break;
2638
2622 - // if(DEBUG) printf("%s\n", buffer);
2639 r = sscanf(buffer, "%llu %llu %s %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
2640 &major, &minor, disk,
2641 &reads, &reads_merged, &readsectors, &readms, &writes, &writes_merged, &writesectors, &writems, &currentios, &iosms, &wiosms
@@ -4085,7 +4101,7 @@ int do_proc_vmstat() {
4101
4102 void *proc_main(void *ptr)
4103 {
4088 - struct timeval last, now, tmp;
4104 + struct timeval last, now;
4105
4106 gettimeofday(&last, NULL);
4107 last.tv_sec -= update_every;
@@ -4101,13 +4117,9 @@ void *proc_main(void *ptr)
4117 int vdo_proc_meminfo = 0;
4118 int vdo_proc_vmstat = 0;
4119
4120 + gettimeofday(&last, NULL);
4121 + unsigned long long usec = 0, susec = 0;
4122 for(;1;) {
4105 - unsigned long long usec, susec;
4106 - gettimeofday(&now, NULL);
4107 -
4108 - // calculate the time it took for a full loop
4109 - usec = usecdiff(&now, &last);
4110 - debug(D_PROCNETDEV_LOOP, "PROCNETDEV: Last full loop took %llu usec.", usec);
4123
4124 // BEGIN -- the job to be done
4125 if(!vdo_proc_net_dev) vdo_proc_net_dev = do_proc_net_dev(usec);
@@ -4122,9 +4134,9 @@ void *proc_main(void *ptr)
4134 // END -- the job is done
4135
4136 // find the time to sleep in order to wait exactly update_every seconds
4125 - gettimeofday(&tmp, NULL);
4126 - usec = usecdiff(&tmp, &now);
4127 - debug(D_PROCNETDEV_LOOP, "PROCNETDEV: This loop's work took %llu usec.", usec);
4137 + gettimeofday(&now, NULL);
4138 + usec = usecdiff(&now, &last) - susec;
4139 + debug(D_PROCNETDEV_LOOP, "PROCNETDEV: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec);
4140
4141 if(usec < (update_every * 1000000)) susec = (update_every * 1000000) - usec;
4142 else susec = 0;
@@ -4132,7 +4144,6 @@ void *proc_main(void *ptr)
4144 // make sure we will wait at least 100ms
4145 if(susec < 100000) susec = 100000;
4146
4135 - debug(D_PROCNETDEV_LOOP, "PROCNETDEV: Sleeping for %llu usec.", susec);
4147 usleep(susec);
4148
4149 // copy now to last
@@ -4184,7 +4195,7 @@ void tc_device_commit(struct tc_device *d)
4195 for ( c = d->classes ; c ; c = c->next) {
4196 for ( x = d->classes ; x ; x = x->next) {
4197 if(x->parentid[0] && (strcmp(c->id, x->parentid) == 0 || strcmp(c->leafid, x->parentid) == 0)) {
4187 - // debug(D_TC_LOOP, "In device '%s', class '%s' (leafid: '%s') has leaf the class '%s' (parentid: '%s').", d->name, c->name, c->leafid, x->name, x->parentid);
4198 + // debug(D_TC_LOOP, "TC: In device '%s', class '%s' (leafid: '%s') has leaf the class '%s' (parentid: '%s').", d->name, c->name, c->leafid, x->name, x->parentid);
4199 c->isleaf = 0;
4200 x->hasparent = 1;
4201 }
@@ -4194,8 +4205,8 @@ void tc_device_commit(struct tc_device *d)
4205 // debugging:
4206 /*
4207 for ( c = d->classes ; c ; c = c->next) {
4197 - if(c->isleaf && c->hasparent) debug(D_TC_LOOP, "Device %s, class %s, OK", d->name, c->id);
4198 - else debug(D_TC_LOOP, "Device %s, class %s, IGNORE (isleaf: %d, hasparent: %d, parent: %s)", d->name, c->id, c->isleaf, c->hasparent, c->parentid);
4208 + if(c->isleaf && c->hasparent) debug(D_TC_LOOP, "TC: Device %s, class %s, OK", d->name, c->id);
4209 + else debug(D_TC_LOOP, "TC: Device %s, class %s, IGNORE (isleaf: %d, hasparent: %d, parent: %s)", d->name, c->id, c->isleaf, c->hasparent, c->parentid);
4210 }
4211 */
4212
@@ -4203,14 +4214,14 @@ void tc_device_commit(struct tc_device *d)
4214 if(c->isleaf && c->hasparent) break;
4215 }
4216 if(!c) {
4206 - debug(D_TC_LOOP, "Ignoring TC device '%s'. No leaf classes.", d->name);
4217 + debug(D_TC_LOOP, "TC: Ignoring TC device '%s'. No leaf classes.", d->name);
4218 return;
4219 }
4220
4210 - debug(D_TC_LOOP, "Committing TC device '%s'", d->name);
4211 -
4221 RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_TC, d->id);
4222 if(!st) {
4223 + debug(D_TC_LOOP, "TC: Committing new TC device '%s'", d->name);
4224 +
4225 st = rrd_stats_create(RRD_TYPE_TC, d->id, d->name, d->group, "Class usage for ", "kilobits/s", save_history);
4226
4227 for ( c = d->classes ; c ; c = c->next) {
@@ -4218,7 +4229,10 @@ void tc_device_commit(struct tc_device *d)
4229 rrd_stats_dimension_add(st, c->id, c->name, sizeof(unsigned long long), 0, 8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
4230 }
4231 }
4221 - else rrd_stats_next(st);
4232 + else {
4233 + unsigned long long usec = rrd_stats_next(st);
4234 + debug(D_TC_LOOP, "TC: Committing TC device '%s' after %llu usec", d->name, usec);
4235 + }
4236
4237 for ( c = d->classes ; c ; c = c->next) {
4238 if(c->isleaf && c->hasparent) {
@@ -4416,7 +4430,7 @@ void *tc_main(void *ptr)
4430 else if((strcmp(p, "MYPID") == 0)) {
4431 char *id = strsep(&b, " \n");
4432 tc_child_pid = atol(id);
4419 - debug(D_TC_LOOP, "Child PID is %d.", tc_child_pid);
4433 + debug(D_TC_LOOP, "TC: Child PID is %d.", tc_child_pid);
4434 }
4435 }
4436 pclose(fp);
@@ -4566,9 +4580,18 @@ void become_daemon()
4580
4581 // close all files
4582 for(i = sysconf(_SC_OPEN_MAX); i > 0; i--)
4569 - close(i);
4583 + if(i != debug_fd) close(i);
4584
4571 - silent = 1;
4585 + if(debug_fd >= 0) {
4586 + silent = 0;
4587 +
4588 + if(dup2(debug_fd, STDOUT_FILENO) < 0)
4589 + silent = 1;
4590 +
4591 + if(dup2(debug_fd, STDERR_FILENO) < 0)
4592 + silent = 1;
4593 + }
4594 + else silent = 1;
4595 }
4596
4597 int main(int argc, char **argv)
@@ -4598,6 +4621,21 @@ int main(int argc, char **argv)
4621 }
4622 i++;
4623 }
4624 + else if(strcmp(argv[i], "-dl") == 0 && (i+1) < argc) {
4625 + debug_log = argv[i+1];
4626 + debug_fd = open(debug_log, O_WRONLY | O_APPEND | O_CREAT, 0666);
4627 + if(debug_fd < 0) {
4628 + fprintf(stderr, "Cannot open file '%s'. Reason: %s\n", debug_log, strerror(errno));
4629 + exit(1);
4630 + }
4631 + debug(D_OPTIONS, "Debug LOG set to '%s'.", debug_log);
4632 + i++;
4633 + }
4634 + else if(strcmp(argv[i], "-df") == 0 && (i+1) < argc) {
4635 + debug_flags = strtoull(argv[i+1], NULL, 0);
4636 + debug(D_OPTIONS, "Debug flags set to '0x%8llx'.", debug_flags);
4637 + i++;
4638 + }
4639 else if(strcmp(argv[i], "-t") == 0 && (i+1) < argc) {
4640 update_every = atoi(argv[i+1]);
4641 if(update_every < 1 || update_every > 600) {
@@ -4626,12 +4664,14 @@ int main(int argc, char **argv)
4664 }
4665 else {
4666 fprintf(stderr, "Cannot understand option '%s'.\n", argv[i]);
4629 - fprintf(stderr, "\nUSAGE: %s [-d] [-l LINES_TO_SAVE] [-u UPDATE_TIMER] [-p LISTEN_PORT].\n\n", argv[0]);
4667 + fprintf(stderr, "\nUSAGE: %s [-d] [-l LINES_TO_SAVE] [-u UPDATE_TIMER] [-p LISTEN_PORT] [-dl debug log file] [-df debug flags].\n\n", argv[0]);
4668 fprintf(stderr, " -d enable daemon mode (run in background).\n");
4669 fprintf(stderr, " -l LINES_TO_SAVE can be from 5 to %d lines in JSON data. Default: %d.\n", HISTORY_MAX, HISTORY);
4670 fprintf(stderr, " -t UPDATE_TIMER can be from 1 to %d seconds. Default: %d.\n", UPDATE_EVERY_MAX, UPDATE_EVERY);
4671 fprintf(stderr, " -p LISTEN_PORT can be from 1 to %d. Default: %d.\n", 65535, LISTEN_PORT);
4672 fprintf(stderr, " -u USERNAME can be any system username to run as. Default: none.\n");
4673 + fprintf(stderr, " -dl FILENAME write debug log to FILENAME. Default: none.\n");
4674 + fprintf(stderr, " -df FLAGS debug options. Default: 0x%8llx.\n", debug_flags);
4675 exit(1);
4676 }
4677 }
netdata.start
+4 -2
@@ -40,8 +40,10 @@ if [ $NETDATA_CONFIG_DEBUG -eq 1 ]
40 then
41 ulimit -c unlimited
42 gcc -Wall -ggdb -o netdata netdata.c -lpthread -lz || exit 1
43 + debug_opts="-df 0xfffffedf -dl netdata.log"
44 else
45 gcc -Wall -O3 -o netdata netdata.c -lpthread -lz || exit 1
46 + debug_opts=
47 fi
48
49 NETDATA_TITLE_DEFAULT=
@@ -57,11 +59,11 @@ then
59 chown -R "$NETDATA_CONFIG_USER" web || exit 1
60 chmod 0775 web || exit 1
61 chmod -R 0664 web/* || exit 1
60 - `pwd`/netdata -d -u $NETDATA_CONFIG_USER -t $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_CONFIG_INTERNAL_HISTORY_LINES -p $NETDATA_CONFIG_PORT || exit 1
62 + `pwd`/netdata $debug_opts -d -u $NETDATA_CONFIG_USER -t $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_CONFIG_INTERNAL_HISTORY_LINES -p $NETDATA_CONFIG_PORT || exit 1
63 else
64 echo >&2 "WARNING: NOT RUNNING AS ROOT - CANNOT SWITCH TO USER $NETDATA_CONFIG_USER"
65 echo >&2 "WARNING: MAKE SURE FILES IN web/ ARE OWNED BY $USER - or it will not work"
64 - `pwd`/netdata -d -t $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_CONFIG_INTERNAL_HISTORY_LINES -p $NETDATA_CONFIG_PORT || exit 1
66 + `pwd`/netdata $debug_opts -d -t $NETDATA_CONFIG_INTERNAL_UPDATE_EVERY -l $NETDATA_CONFIG_INTERNAL_HISTORY_LINES -p $NETDATA_CONFIG_PORT || exit 1
67 fi
68 sleep 2
69