]> arthur.barton.de Git - netdata.git/commitdiff
fixed all crashes; empty responses are now formatted properly; fixed exit procedure...
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Mon, 7 Dec 2015 20:42:57 +0000 (22:42 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Mon, 7 Dec 2015 20:42:57 +0000 (22:42 +0200)
src/log.c
src/main.c
src/rrd2json.c
src/web_buffer.c
src/web_client.c
web/dashboard.js

index 21c44afc866870e8fff989b6d879a6a011727ded..db5ed15701d337a552c7ae7ca341be4013ca10ea 100755 (executable)
--- a/src/log.c
+++ b/src/log.c
@@ -32,10 +32,10 @@ void log_date(FILE *out)
 {
                char outstr[200];
                time_t t;
-               struct tm *tmp;
+               struct tm *tmp, tmbuf;
 
                t = time(NULL);
-               tmp = localtime(&t);
+               tmp = localtime_r(&t, &tmbuf);
 
                if (tmp == NULL) return;
                if (strftime(outstr, sizeof(outstr), "%y-%m-%d %H:%M:%S", tmp) == 0) return;
@@ -142,7 +142,9 @@ void log_access( const char *fmt, ... )
                vfprintf( stdaccess, fmt, args );
                va_end( args );
                fprintf( stdaccess, "\n");
+#ifdef NETDATA_INTERNAL_CHECKS
                fflush( stdaccess );
+#endif
        }
 
        if(access_log_syslog) {
index 7288d073af39f19dcc9eb9d65c259ca47387fa45..d73dd5901d85a071185efae4869df6c2c2da3d3d 100755 (executable)
@@ -157,7 +157,7 @@ void kill_childs()
        if(tc_child_pid) {
                info("Killing tc-qos-helper procees");
                if(killpid(tc_child_pid, SIGTERM) != -1)
-                       waitid(tc_child_pid, 0, &info, WEXITED);
+                       waitid(P_PID, tc_child_pid, &info, WEXITED);
        }
        tc_child_pid = 0;
 
@@ -170,10 +170,14 @@ void kill_childs()
                if(cd->pid && !cd->obsolete) {
                        debug(D_EXIT, "killing %s plugin process", cd->id);
                        if(killpid(cd->pid, SIGTERM) != -1)
-                               waitid(cd->pid, 0, &info, WEXITED);
+                               waitid(P_PID, cd->pid, &info, WEXITED);
                }
        }
 
+       // if, for any reason there is any child exited
+       // catch it here
+       waitid(P_PID, 0, &info, WEXITED|WNOHANG);
+
        debug(D_EXIT, "All threads/childs stopped.");
 }
 
index 38ebff7a86e2dcd33d702589a59556450cdfa82b..bbf132b2c36d08b12cd7a95fa64efe8a9d7f6dc4 100755 (executable)
@@ -427,6 +427,7 @@ void rrdr_buffer_print_format(BUFFER *wb, uint32_t format)
 
 void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, uint32_t options, int string_value)
 {
+       //info("JSONWRAPPER(): %s: BEGIN", r->st->id);
        char kq[2] = "",                                        // key quote
                sq[2] = "";                                             // string quote
 
@@ -511,6 +512,7 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, uint32_t opti
                        );
 
        if(string_value) buffer_strcat(wb, sq);
+       //info("JSONWRAPPER(): %s: END", r->st->id);
 }
 
 void rrdr_json_wrapper_end(RRDR *r, BUFFER *wb, uint32_t format, uint32_t options, int string_value)
@@ -534,6 +536,7 @@ void rrdr_json_wrapper_end(RRDR *r, BUFFER *wb, uint32_t format, uint32_t option
 
 static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
 {
+       //info("RRD2JSON(): %s: BEGIN", r->st->id);
        int row_annotations = 0, dates = JSON_DATES_JS, dates_with_new = 0;
        char kq[2] = "",                                        // key quote
                sq[2] = "",                                             // string quote
@@ -639,12 +642,8 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
 
        // if all dimensions are hidden, print a null
        if(!i) {
-               buffer_strcat(wb, pre_value);
-               if(options & RRDR_OPTION_NULL2ZERO)
-                       buffer_strcat(wb, "0");
-               else
-                       buffer_strcat(wb, "null");
-               buffer_strcat(wb, post_value);
+               buffer_strcat(wb, finish);
+               return;
        }
 
        long start = 0, end = rrdr_rows(r), step = 1;
@@ -663,8 +662,8 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
 
                if(dates == JSON_DATES_JS) {
                        // generate the local date time
-                       struct tm *tm = localtime(&now);
-                       if(!tm) { error("localtime() failed."); continue; }
+                       struct tm tmbuf, *tm = localtime_r(&now, &tmbuf);
+                       if(!tm) { error("localtime_r() failed."); continue; }
 
                        if(likely(i != start)) buffer_strcat(wb, ",\n");
                        buffer_strcat(wb, pre_date);
@@ -738,10 +737,12 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
        }
 
        buffer_strcat(wb, finish);
+       //info("RRD2JSON(): %s: END", r->st->id);
 }
 
 static void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t options, const char *startline, const char *separator, const char *endline)
 {
+       //info("RRD2CSV(): %s: BEGIN", r->st->id);
        long c, i;
        RRDDIM *d;
 
@@ -789,7 +790,7 @@ static void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t options, const char *startlin
                }
                else {
                        // generate the local date time
-                       struct tm *tm = localtime(&now);
+                       struct tm tmbuf, *tm = localtime_r(&now, &tmbuf);
                        if(!tm) { error("localtime() failed."); continue; }
                        buffer_date(wb, tm->tm_year + 1900, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
                }
@@ -817,10 +818,12 @@ static void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t options, const char *startlin
 
                buffer_strcat(wb, endline);
        }
+       //info("RRD2CSV(): %s: END", r->st->id);
 }
 
 static void rrdr2ssv(RRDR *r, BUFFER *wb, uint32_t options, const char *prefix, const char *separator, const char *suffix)
 {
+       //info("RRD2SSV(): %s: BEGIN", r->st->id);
        long c, i;
        RRDDIM *d;
 
@@ -885,6 +888,7 @@ static void rrdr2ssv(RRDR *r, BUFFER *wb, uint32_t options, const char *prefix,
                        buffer_rrd_value(wb, sum);
        }
        buffer_strcat(wb, suffix);
+       //info("RRD2SSV(): %s: END", r->st->id);
 }
 
 inline static calculated_number *rrdr_line_values(RRDR *r)
@@ -962,11 +966,10 @@ static RRDR *rrdr_create(RRDSET *st, int n)
                return NULL;
        }
 
-       RRDR *r = malloc(sizeof(RRDR));
+       RRDR *r = calloc(1, sizeof(RRDR));
        if(unlikely(!r)) goto cleanup;
 
        r->st = st;
-       r->has_st_lock = 0;
 
        rrdr_lock_rrdset(r);
 
@@ -988,17 +991,10 @@ static RRDR *rrdr_create(RRDSET *st, int n)
        if(unlikely(!r->od)) goto cleanup;
 
        r->c = -1;
-       r->rows = 0;
 
        r->group = 1;
        r->update_every = 1;
 
-       r->min = 0.0;
-       r->max = 0.0;
-
-       r->before = 0;
-       r->after = 0;
-
        return r;
 
 cleanup:
@@ -1042,11 +1038,11 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
 
        // the duration of the chart
        time_t duration = before - after;
-       if(duration <= 0) return NULL;
-
-       // how many points does the chart has?
        long available_points = duration / st->update_every;
 
+       if(duration <= 0 || available_points <= 0)
+               return rrdr_create(st, 1);
+
        // check the wanted points
        if(points < 0) points = -points;
        if(points > available_points) points = available_points;
@@ -1067,6 +1063,7 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
        long    start_at_slot = rrdset_time2slot(st, before_new),
                        stop_at_slot = rrdset_time2slot(st, after_new);
 
+#ifdef NETDATA_INTERNAL_CHECKS
        if(after_new < first_entry_t) {
                error("after_new %u is too small, minimum %u", after_new, first_entry_t);
        }
@@ -1081,17 +1078,16 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
        }
        if(start_at_slot < 0 || start_at_slot >= st->entries) {
                error("start_at_slot is invalid %ld, expected %ld to %ld", start_at_slot, 0, st->entries - 1);
-               start_at_slot = st->current_entry;
        }
        if(stop_at_slot < 0 || stop_at_slot >= st->entries) {
                error("stop_at_slot is invalid %ld, expected %ld to %ld", stop_at_slot, 0, st->entries - 1);
-               stop_at_slot = 0;
        }
        if(points_new > (before_new - after_new) / group / st->update_every + 1) {
                error("points_new %ld is more than points %ld", points_new, (before_new - after_new) / group / st->update_every + 1);
        }
+#endif
 
-       // error("SHIFT: %s: wanted %ld points, got %ld - group=%ld, wanted duration=%u, got %u - wanted %ld - %ld, got %ld - %ld", st->id, points, points_new, group, before - after, before_new - after_new, after, before, after_new, before_new);
+       //info("RRD2RRDR(): %s: wanted %ld points, got %ld - group=%ld, wanted duration=%u, got %u - wanted %ld - %ld, got %ld - %ld", st->id, points, points_new, group, before - after, before_new - after_new, after, before, after_new, before_new);
 
        after = after_new;
        before = before_new;
@@ -1112,10 +1108,7 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
 
        RRDR *r = rrdr_create(st, points);
        if(!r) return NULL;
-       if(!r->d) {
-               rrdr_free(r);
-               return NULL;
-       }
+       if(!r->d) return r;
 
        // find how many dimensions we have
        long dimensions = r->d;
@@ -1180,6 +1173,8 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
        r->before = now;
        r->after = now;
 
+       //info("RRD2RRDR(): %s: STARTING", st->id);
+
        long slot = start_at_slot, counter = 0, stop_now = 0, added = 0, group_count = 0, add_this = 0;
        for(; !stop_now ; now -= dt, slot--, counter++) {
                if(unlikely(slot < 0)) slot = st->entries - 1;
@@ -1211,7 +1206,7 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
                }
 
                // do the calculations
-               for(rd = st->dimensions, c = 0 ; likely(rd && c < dimensions) ; rd = rd->next, c++) {
+               for(rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
                        storage_number n = rd->values[slot];
                        if(unlikely(!does_storage_number_exist(n))) continue;
 
@@ -1286,6 +1281,7 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
        }
 
        rrdr_done(r);
+       //info("RRD2RRDR(): %s: END %ld loops made, %ld points generated", st->id, counter, rrdr_rows(r));
        //error("SHIFT: %s: wanted %ld points, got %ld", st->id, points, rrdr_rows(r));
        return r;
 }
@@ -1650,7 +1646,7 @@ unsigned long rrd_stats_json(int type, RRDSET *st, BUFFER *wb, int points, int g
                                }
 
                                // generate the local date time
-                               struct tm *tm = localtime(&now);
+                               struct tm tmbuf, *tm = localtime_r(&now, &tmbuf);
                                if(!tm) { error("localtime() failed."); continue; }
                                if(now > last_timestamp) last_timestamp = now;
 
index 694f77afe2b50fe5def701af0ac1a384ba104a3b..c2e6b03c8e05f9ed273ac24a5b34f0b2e1b725dc 100755 (executable)
@@ -20,7 +20,11 @@ static inline void buffer_overflow_init(BUFFER *b)
        strcpy(&b->buffer[b->size + 1], BUFFER_OVERFLOW_EOF);
 }
 
+#ifdef NETDATA_INTERNAL_CHECKS
 #define buffer_overflow_check(b) _buffer_overflow_check(b, __FILE__, __FUNCTION__, __LINE__)
+#else
+#define buffer_overflow_check(b)
+#endif
 
 static inline void _buffer_overflow_check(BUFFER *b, const char *file, const char *function, const unsigned long line)
 {
index e13226142f3a2ec16ae695cfda10af87a0cc6d03..47a8950cd423b58ac27ab5993ac583143a913d6b 100755 (executable)
@@ -527,10 +527,10 @@ int web_client_api_request_v1_chart(struct web_client *w, char *url)
                // they are not null and not empty
 
                if(!strcmp(name, "chart")) chart = value;
-               else {
-                       buffer_sprintf(w->response.data, "Unknown parameter '%s' in request.", name);
-                       goto cleanup;
-               }
+               //else {
+               ///     buffer_sprintf(w->response.data, "Unknown parameter '%s' in request.", name);
+               //      goto cleanup;
+               //}
        }
 
        if(!chart || !*chart) {
@@ -1009,7 +1009,7 @@ void web_client_process(struct web_client *w) {
                                datasource_type = DATASOURCE_JSON;
                                code = web_client_api_request(w, url);
                        }
-#ifdef WEB_EXIT
+#ifdef NETDATA_INTERNAL_CHECKS
                        else if(strcmp(tok, "exit") == 0) {
                                netdata_exit = 1;
                                code = 200;
index 52efd81e8d31f425014e620d1c681ef1990c03d2..26c374eb0afdb8a201d66fdaf295706549ab952f 100755 (executable)
                        element_chart_id: null,
                        element_legend: null,   // the element with the legend of the chart (if created by us)
                        element_legend_id: null,
-                       
+
                        chart_url: null,                // string - the url to download chart info
                        chart: null,                    // object - the chart as downloaded from the server
 
                                        this.library.initialize(function() { this_state_object.updateChart(callback); });
                                        return;
                                }
-                               
+
                                this.clearSelection();
                                this.chartURL();
                                if(this.debug) this.log('updating from ' + this.current.url);
                                var this_state_object = this;
                                $.ajax( {
                                        url: this.current.url,
-                                       crossDomain: true
+                                       crossDomain: true,
+                                       cache: false
                                })
                                .then(function(data) {
                                        this_state_object.updateChartWithData(data);
 
                                        $.ajax( {
                                                url:  this.chart_url,
-                                               crossDomain: true
+                                               crossDomain: true,
+                                               cache: false
                                        })
                                        .done(function(chart) {
                                                chart.url = this_state_object.chart_url;
                                this.element.innerHTML = '<div class="netdata-message netdata-' + type + '-message" style="font-size: x-small; overflow: hidden; width: 100%; height: 100%;"><small>'
                                        + msg
                                        + '</small></div>';
-                               
+
                                // reset the creation datetime
                                // since we overwrote the whole element
                                this.created_ms = 0
 
        NETDATA.peityInitialize = function(callback) {
                if(typeof netdataNoPeitys == 'undefined' || !netdataNoPeitys) {
-                       $.getScript(NETDATA.peity_js)
+                       $.ajax({
+                               url: NETDATA.peity_js,
+                               cache: true,
+                               dataType: "script"
+                       })
                                .done(function() {
                                        NETDATA.registerChartLibrary('peity', NETDATA.peity_js);
                                })
 
        NETDATA.sparklineInitialize = function(callback) {
                if(typeof netdataNoSparklines == 'undefined' || !netdataNoSparklines) {
-                       $.getScript(NETDATA.sparkline_js)
+                       $.ajax({
+                               url: NETDATA.sparkline_js,
+                               cache: true,
+                               dataType: "script"
+                       })
                                .done(function() {
                                        NETDATA.registerChartLibrary('sparkline', NETDATA.sparkline_js);
                                })
 
        NETDATA.dygraphInitialize = function(callback) {
                if(typeof netdataNoDygraphs == 'undefined' || !netdataNoDygraphs) {
-                       $.getScript(NETDATA.dygraph_js)
+                       $.ajax({
+                               url: NETDATA.dygraph_js,
+                               cache: true,
+                               dataType: "script"
+                       })
                                .done(function() {
                                        NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js);
                                })
                        else {
                                NETDATA._loadCSS(NETDATA.morris_css);
 
-                               $.getScript(NETDATA.morris_js)
+                               $.ajax({
+                                       url: NETDATA.morris_js,
+                                       cache: true,
+                                       dataType: "script"
+                               })
                                        .done(function() {
                                                NETDATA.registerChartLibrary('morris', NETDATA.morris_js);
                                        })
 
        NETDATA.raphaelInitialize = function(callback) {
                if(typeof netdataStopRaphael == 'undefined') {
-                       $.getScript(NETDATA.raphael_js)
+                       $.ajax({
+                               url: NETDATA.raphael_js,
+                               cache: true,
+                               dataType: "script"
+                       })
                                .done(function() {
                                        NETDATA.registerChartLibrary('raphael', NETDATA.raphael_js);
                                })
 
        NETDATA.googleInitialize = function(callback) {
                if(typeof netdataNoGoogleCharts == 'undefined' || !netdataNoGoogleCharts) {
-                       $.getScript(NETDATA.google_js)
+                       $.ajax({
+                               url: NETDATA.google_js,
+                               cache: true,
+                               dataType: "script"
+                       })
                                .done(function() {
                                        NETDATA.registerChartLibrary('google', NETDATA.google_js);
 
 
        NETDATA.errorReset();
        NETDATA._loadjQuery(function() {
-               $.getScript(NETDATA.serverDefault + 'lib/visible.js').then(function() {
+               $.ajax({
+                       url: NETDATA.serverDefault + 'lib/visible.js',
+                       cache: true,
+                       dataType: "script"
+               })
+               .then(function() {
                        NETDATA._loadCSS(NETDATA.dashboard_css);
 
                        if(typeof netdataDontStart == 'undefined' || !netdataDontStart)