]> arthur.barton.de Git - netdata.git/blobdiff - src/rrd2json.c
Merge pull request #1822 from l2isbad/mongodb_plugin
[netdata.git] / src / rrd2json.c
index 26163aa0a12f8c7d7807b2fc956d86f4168f2f50..2a46fb134568721be224599c6168fac301d20d0d 100644 (file)
@@ -2,7 +2,7 @@
 
 void rrd_stats_api_v1_chart_with_data(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memory_used)
 {
-    pthread_rwlock_rdlock(&st->rwlock);
+    rrdset_rdlock(st);
 
     buffer_sprintf(wb,
         "\t\t{\n"
@@ -43,7 +43,7 @@ void rrd_stats_api_v1_chart_with_data(RRDSET *st, BUFFER *wb, size_t *dimensions
 
     size_t dimensions = 0;
     RRDDIM *rd;
-    for(rd = st->dimensions; rd ; rd = rd->next) {
+    rrddim_foreach_read(rd, st) {
         if(rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)) continue;
 
         memory += rd->memsize;
@@ -71,7 +71,7 @@ void rrd_stats_api_v1_chart_with_data(RRDSET *st, BUFFER *wb, size_t *dimensions
         "\n\t\t}"
         );
 
-    pthread_rwlock_unlock(&st->rwlock);
+    rrdset_unlock(st);
 }
 
 void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb) {
@@ -92,13 +92,14 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb)
         ",\n\t\"charts\": {"
         , host->hostname
         , program_version
-        , os_type
+        , host->os
         , host->rrd_update_every
         , host->rrd_history_entries
         );
 
-    pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
-    for(st = host->rrdset_root, c = 0; st ; st = st->next) {
+    c = 0;
+    rrdhost_rdlock(host);
+    rrdset_foreach_read(st, host) {
         if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
             if(c) buffer_strcat(wb, ",");
             buffer_strcat(wb, "\n\t\t\"");
@@ -114,19 +115,45 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb)
         if(rc->rrdset)
             alarms++;
     }
-    pthread_rwlock_unlock(&host->rrdset_root_rwlock);
+    rrdhost_unlock(host);
 
     buffer_sprintf(wb, "\n\t}"
                     ",\n\t\"charts_count\": %zu"
                     ",\n\t\"dimensions_count\": %zu"
                     ",\n\t\"alarms_count\": %zu"
                     ",\n\t\"rrd_memory_bytes\": %zu"
-                    "\n}\n"
+                    ",\n\t\"hosts_count\": %zu"
+                    ",\n\t\"hosts\": ["
                    , c
                    , dimensions
                    , alarms
                    , memory
+                   , rrd_hosts_available
     );
+
+    if(unlikely(rrd_hosts_available > 1)) {
+        rrd_rdlock();
+        RRDHOST *h;
+        rrdhost_foreach_read(h)
+            buffer_sprintf(wb,
+                    "%s\n\t\t{"
+                    "\n\t\t\t\"hostname\": \"%s\""
+                    "\n\t\t}"
+                    , (h != localhost)?",":""
+                    , h->hostname
+            );
+        rrd_unlock();
+    }
+    else {
+        buffer_sprintf(wb,
+                "\n\t\t{"
+                "\n\t\t\t\"hostname\": \"%s\""
+                "\n\t\t}"
+                , host->hostname
+        );
+    }
+
+    buffer_sprintf(wb, "\n\t]\n}\n");
 }
 
 // ----------------------------------------------------------------------------
@@ -150,25 +177,25 @@ static inline size_t prometheus_name_copy(char *d, const char *s, size_t usable)
 #define PROMETHEUS_ELEMENT_MAX 256
 
 void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb) {
-    pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
+    rrdhost_rdlock(host);
 
     char hostname[PROMETHEUS_ELEMENT_MAX + 1];
-    prometheus_name_copy(hostname, config_get("global", "hostname", "localhost"), PROMETHEUS_ELEMENT_MAX);
+    prometheus_name_copy(hostname, host->hostname, PROMETHEUS_ELEMENT_MAX);
 
     // for each chart
     RRDSET *st;
-    for(st = host->rrdset_root; st ; st = st->next) {
+    rrdset_foreach_read(st, host) {
         char chart[PROMETHEUS_ELEMENT_MAX + 1];
         prometheus_name_copy(chart, st->id, PROMETHEUS_ELEMENT_MAX);
 
         buffer_strcat(wb, "\n");
         if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
-            pthread_rwlock_rdlock(&st->rwlock);
+            rrdset_rdlock(st);
 
             // for each dimension
             RRDDIM *rd;
-            for(rd = st->dimensions; rd ; rd = rd->next) {
-                if(rd->counter) {
+            rrddim_foreach_read(rd, st) {
+                if(rd->collections_counter) {
                     char dimension[PROMETHEUS_ELEMENT_MAX + 1];
                     prometheus_name_copy(dimension, rd->id, PROMETHEUS_ELEMENT_MAX);
 
@@ -196,11 +223,11 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb) {
                 }
             }
 
-            pthread_rwlock_unlock(&st->rwlock);
+            rrdset_unlock(st);
         }
     }
 
-    pthread_rwlock_unlock(&host->rrdset_root_rwlock);
+    rrdhost_unlock(host);
 }
 
 // ----------------------------------------------------------------------------
@@ -224,23 +251,23 @@ static inline size_t shell_name_copy(char *d, const char *s, size_t usable) {
 #define SHELL_ELEMENT_MAX 100
 
 void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) {
-    pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
+    rrdhost_rdlock(host);
 
     // for each chart
     RRDSET *st;
-    for(st = host->rrdset_root; st ; st = st->next) {
+    rrdset_foreach_read(st, host) {
         calculated_number total = 0.0;
         char chart[SHELL_ELEMENT_MAX + 1];
         shell_name_copy(chart, st->id, SHELL_ELEMENT_MAX);
 
         buffer_sprintf(wb, "\n# chart: %s (name: %s)\n", st->id, st->name);
         if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
-            pthread_rwlock_rdlock(&st->rwlock);
+            rrdset_rdlock(st);
 
             // for each dimension
             RRDDIM *rd;
-            for(rd = st->dimensions; rd ; rd = rd->next) {
-                if(rd->counter) {
+            rrddim_foreach_read(rd, st) {
+                if(rd->collections_counter) {
                     char dimension[SHELL_ELEMENT_MAX + 1];
                     shell_name_copy(dimension, rd->id, SHELL_ELEMENT_MAX);
 
@@ -259,7 +286,7 @@ void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) {
 
             total = roundl(total);
             buffer_sprintf(wb, "NETDATA_%s_VISIBLETOTAL=\"%0.0Lf\"      # %s\n", chart, total, st->units);
-            pthread_rwlock_unlock(&st->rwlock);
+            rrdset_unlock(st);
         }
     }
 
@@ -287,7 +314,7 @@ void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) {
         buffer_sprintf(wb, "NETDATA_ALARM_%s_%s_STATUS=\"%s\"\n", chart, alarm, rrdcalc_status2string(rc->status));
     }
 
-    pthread_rwlock_unlock(&host->rrdset_root_rwlock);
+    rrdhost_unlock(host);
 }
 
 // ----------------------------------------------------------------------------
@@ -296,7 +323,7 @@ unsigned long rrd_stats_one_json(RRDSET *st, char *options, BUFFER *wb)
 {
     time_t now = now_realtime_sec();
 
-    pthread_rwlock_rdlock(&st->rwlock);
+    rrdset_rdlock(st);
 
     buffer_sprintf(wb,
         "\t\t{\n"
@@ -350,7 +377,7 @@ unsigned long rrd_stats_one_json(RRDSET *st, char *options, BUFFER *wb)
     unsigned long memory = st->memsize;
 
     RRDDIM *rd;
-    for(rd = st->dimensions; rd ; rd = rd->next) {
+    rrddim_foreach_read(rd, st) {
 
         memory += rd->memsize;
 
@@ -394,7 +421,7 @@ unsigned long rrd_stats_one_json(RRDSET *st, char *options, BUFFER *wb)
         , memory
         );
 
-    pthread_rwlock_unlock(&st->rwlock);
+    rrdset_unlock(st);
     return memory;
 }
 
@@ -411,20 +438,20 @@ void rrd_stats_graph_json(RRDSET *st, char *options, BUFFER *wb)
 void rrd_stats_all_json(RRDHOST *host, BUFFER *wb)
 {
     unsigned long memory = 0;
-    long c;
+    long c = 0;
     RRDSET *st;
 
     buffer_strcat(wb, RRD_GRAPH_JSON_HEADER);
 
-    pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
-    for(st = host->rrdset_root, c = 0; st ; st = st->next) {
+    rrdhost_rdlock(host);
+    rrdset_foreach_read(st, host) {
         if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
             if(c) buffer_strcat(wb, ",\n");
             memory += rrd_stats_one_json(st, NULL, wb);
             c++;
         }
     }
-    pthread_rwlock_unlock(&host->rrdset_root_rwlock);
+    rrdhost_unlock(host);
 
     buffer_sprintf(wb, "\n\t],\n"
         "\t\"hostname\": \"%s\",\n"
@@ -542,6 +569,8 @@ static void rrdr_dump(RRDR *r)
 */
 
 void rrdr_disable_not_selected_dimensions(RRDR *r, uint32_t options, const char *dims) {
+    rrdset_check_rdlock(r->st);
+
     if(unlikely(!dims || !*dims)) return;
 
     char b[strlen(dims) + 1];
@@ -647,6 +676,8 @@ void rrdr_buffer_print_format(BUFFER *wb, uint32_t format)
 
 uint32_t rrdr_check_options(RRDR *r, uint32_t options, const char *dims)
 {
+    rrdset_check_rdlock(r->st);
+
     (void)dims;
 
     if(options & RRDR_OPTION_NONZERO) {
@@ -682,6 +713,8 @@ uint32_t rrdr_check_options(RRDR *r, uint32_t options, const char *dims)
 
 void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, uint32_t options, int string_value)
 {
+    rrdset_check_rdlock(r->st);
+
     long rows = rrdr_rows(r);
     long c, i;
     RRDDIM *rd;
@@ -863,6 +896,8 @@ 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)
 {
+    rrdset_check_rdlock(r->st);
+
     //info("RRD2JSON(): %s: BEGIN", r->st->id);
     int row_annotations = 0, dates, dates_with_new = 0;
     char kq[2] = "",                    // key quote
@@ -1089,6 +1124,8 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
 
 static void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t options, const char *startline, const char *separator, const char *endline, const char *betweenlines)
 {
+    rrdset_check_rdlock(r->st);
+
     //info("RRD2CSV(): %s: BEGIN", r->st->id);
     long c, i;
     RRDDIM *d;
@@ -1194,6 +1231,8 @@ static void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t options, const char *startlin
 }
 
 inline static calculated_number rrdr2value(RRDR *r, long i, uint32_t options, int *all_values_are_null) {
+    rrdset_check_rdlock(r->st);
+
     long c;
     RRDDIM *d;
 
@@ -1344,7 +1383,7 @@ inline static void rrdr_lock_rrdset(RRDR *r) {
         return;
     }
 
-    pthread_rwlock_rdlock(&r->st->rwlock);
+    rrdset_rdlock(r->st);
     r->has_st_lock = 1;
 }
 
@@ -1355,7 +1394,7 @@ inline static void rrdr_unlock_rrdset(RRDR *r) {
     }
 
     if(likely(r->has_st_lock)) {
-        pthread_rwlock_unlock(&r->st->rwlock);
+        rrdset_unlock(r->st);
         r->has_st_lock = 0;
     }
 }
@@ -1394,7 +1433,7 @@ static RRDR *rrdr_create(RRDSET *st, long n)
     rrdr_lock_rrdset(r);
 
     RRDDIM *rd;
-    for(rd = st->dimensions ; rd ; rd = rd->next) r->d++;
+    rrddim_foreach_read(rd, st) r->d++;
 
     r->n = n;
 
@@ -1597,6 +1636,7 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
     // initialize them
     RRDDIM *rd;
     long c;
+    rrdset_check_rdlock(st);
     for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
         last_values[c] = 0;
         group_values[c] = (group_method == GROUP_MAX || group_method == GROUP_MIN)?NAN:0;
@@ -1992,7 +2032,7 @@ int rrd2format(RRDSET *st, BUFFER *wb, BUFFER *dimensions, uint32_t format, long
 time_t rrd_stats_json(int type, RRDSET *st, BUFFER *wb, long points, long group, int group_method, time_t after, time_t before, int only_non_zero)
 {
     int c;
-    pthread_rwlock_rdlock(&st->rwlock);
+    rrdset_rdlock(st);
 
 
     // -------------------------------------------------------------------------
@@ -2034,9 +2074,9 @@ time_t rrd_stats_json(int type, RRDSET *st, BUFFER *wb, long points, long group,
 
     int dimensions = 0;
     RRDDIM *rd;
-    for( rd = st->dimensions ; rd ; rd = rd->next) dimensions++;
+    rrddim_foreach_read(rd, st) dimensions++;
     if(!dimensions) {
-        pthread_rwlock_unlock(&st->rwlock);
+        rrdset_unlock(st);
         buffer_strcat(wb, "No dimensions yet.");
         return 0;
     }
@@ -2309,6 +2349,6 @@ time_t rrd_stats_json(int type, RRDSET *st, BUFFER *wb, long points, long group,
 
     debug(D_RRD_STATS, "RRD_STATS_JSON: %s total %zu bytes", st->name, wb->len);
 
-    pthread_rwlock_unlock(&st->rwlock);
+    rrdset_unlock(st);
     return last_timestamp;
 }