summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorStelios Fragkakis <52996999+stelfrag@users.noreply.github.com>2023-11-08 16:15:54 +0200
committerGitHub <noreply@github.com>2023-11-08 16:15:54 +0200
commit4c867cb3a61c6c2bcd32f82267b0e01327eba752 (patch)
treef8989170721ae8dee9ddcc6d18100a3a1bb9e88c /web
parentfa86868728a1cbb2b1454951fa7f1f66bf62b8f3 (diff)
Switch charts / chart to use buffer json functions (#16359)
Switch charts / chart to use buffer json
Diffstat (limited to 'web')
-rw-r--r--web/api/formatters/charts2json.c99
-rw-r--r--web/api/formatters/charts2json.h2
-rw-r--r--web/api/formatters/json_wrapper.c6
-rw-r--r--web/api/formatters/rrd2json.c7
-rw-r--r--web/api/formatters/rrdset2json.c192
-rw-r--r--web/api/formatters/rrdset2json.h2
-rw-r--r--web/api/web_api_v1.c2
7 files changed, 115 insertions, 195 deletions
diff --git a/web/api/formatters/charts2json.c b/web/api/formatters/charts2json.c
index 61086ab635..cab4debaec 100644
--- a/web/api/formatters/charts2json.c
+++ b/web/api/formatters/charts2json.c
@@ -36,9 +36,9 @@ const char* get_release_channel() {
return (use_stable)?"stable":"nightly";
}
-void charts2json(RRDHOST *host, BUFFER *wb, int skip_volatile) {
+void charts2json(RRDHOST *host, BUFFER *wb) {
static char *custom_dashboard_info_js_filename = NULL;
- size_t c, dimensions = 0, memory = 0, alarms = 0;
+ size_t c = 0, dimensions = 0, memory = 0, alarms = 0;
RRDSET *st;
time_t now = now_realtime_sec();
@@ -46,42 +46,31 @@ void charts2json(RRDHOST *host, BUFFER *wb, int skip_volatile) {
if(unlikely(!custom_dashboard_info_js_filename))
custom_dashboard_info_js_filename = config_get(CONFIG_SECTION_WEB, "custom dashboard_info.js", "");
- buffer_sprintf(wb, "{\n"
- "\t\"hostname\": \"%s\""
- ",\n\t\"version\": \"%s\""
- ",\n\t\"release_channel\": \"%s\""
- ",\n\t\"os\": \"%s\""
- ",\n\t\"timezone\": \"%s\""
- ",\n\t\"update_every\": %d"
- ",\n\t\"history\": %d"
- ",\n\t\"memory_mode\": \"%s\""
- ",\n\t\"custom_info\": \"%s\""
- ",\n\t\"charts\": {"
- , rrdhost_hostname(host)
- , rrdhost_program_version(host)
- , get_release_channel()
- , rrdhost_os(host)
- , rrdhost_timezone(host)
- , host->rrd_update_every
- , host->rrd_history_entries
- , rrd_memory_mode_name(host->rrd_memory_mode)
- , custom_dashboard_info_js_filename
- );
+ buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_DEFAULT);
- c = 0;
+ buffer_json_member_add_string(wb, "hostname", rrdhost_hostname(host));
+ buffer_json_member_add_string(wb, "version", rrdhost_program_version(host));
+ buffer_json_member_add_string(wb, "release_channel", get_release_channel());
+ buffer_json_member_add_string(wb, "os", rrdhost_os(host));
+ buffer_json_member_add_string(wb, "timezone", rrdhost_timezone(host));
+ buffer_json_member_add_int64(wb, "update_every", host->rrd_update_every);
+ buffer_json_member_add_int64(wb, "history", host->rrd_history_entries);
+ buffer_json_member_add_string(wb, "memory_mode", rrd_memory_mode_name(host->rrd_memory_mode));
+ buffer_json_member_add_string(wb, "custom_info", custom_dashboard_info_js_filename);
+
+ buffer_json_member_add_object(wb, "charts");
rrdset_foreach_read(st, host) {
if (rrdset_is_available_for_viewers(st)) {
- if(c) buffer_strcat(wb, ",");
- buffer_strcat(wb, "\n\t\t\"");
- buffer_strcat(wb, rrdset_id(st));
- buffer_strcat(wb, "\": ");
- rrdset2json(st, wb, &dimensions, &memory, skip_volatile);
- c++;
+ buffer_json_member_add_object(wb, rrdset_id(st));
+ rrdset2json(st, wb, &dimensions, &memory);
+ buffer_json_object_close(wb);
st->last_accessed_time_s = now;
+ c++;
}
}
rrdset_foreach_done(st);
+ buffer_json_object_close(wb);
RRDCALC *rc;
foreach_rrdcalc_in_rrdhost_read(host, rc) {
@@ -90,50 +79,26 @@ void charts2json(RRDHOST *host, BUFFER *wb, int skip_volatile) {
}
foreach_rrdcalc_in_rrdhost_done(rc);
- 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\t\"hosts_count\": %zu"
- ",\n\t\"hosts\": ["
- , c
- , dimensions
- , alarms
- , memory
- , rrdhost_hosts_available()
- );
+ buffer_json_member_add_int64(wb, "charts_count", (int64_t) c);
+ buffer_json_member_add_int64(wb, "dimensions_count", (int64_t) dimensions);
+ buffer_json_member_add_int64(wb, "alarms_count", (int64_t)alarms);
+ buffer_json_member_add_int64(wb, "rrd_memory_bytes", (int64_t)memory);
+ buffer_json_member_add_int64(wb, "hosts_count", (int64_t) rrdhost_hosts_available());
- if(unlikely(rrdhost_hosts_available() > 1)) {
+ buffer_json_member_add_array(wb, "hosts");
+ {
rrd_rdlock();
-
- size_t found = 0;
RRDHOST *h;
rrdhost_foreach_read(h) {
- if(!rrdhost_should_be_removed(h, host, now) && !rrdhost_flag_check(h, RRDHOST_FLAG_ARCHIVED)) {
- buffer_sprintf(wb
- , "%s\n\t\t{"
- "\n\t\t\t\"hostname\": \"%s\""
- "\n\t\t}"
- , (found > 0) ? "," : ""
- , rrdhost_hostname(h)
- );
-
- found++;
+ if(!rrdhost_should_be_removed(h, host, now) /*&& !rrdhost_flag_check(h, RRDHOST_FLAG_ARCHIVED) */) {
+ buffer_json_add_array_item_object(wb);
+ buffer_json_member_add_string(wb, "hostname", rrdhost_hostname(h));
+ buffer_json_object_close(wb);
}
}
-
rrd_unlock();
}
- else {
- buffer_sprintf(wb
- , "\n\t\t{"
- "\n\t\t\t\"hostname\": \"%s\""
- "\n\t\t}"
- , rrdhost_hostname(host)
- );
- }
+ buffer_json_array_close(wb);
- buffer_sprintf(wb, "\n\t]\n}\n");
+ buffer_json_finalize(wb);
}
diff --git a/web/api/formatters/charts2json.h b/web/api/formatters/charts2json.h
index 4ef6bc2c80..7b07af5a0c 100644
--- a/web/api/formatters/charts2json.h
+++ b/web/api/formatters/charts2json.h
@@ -5,7 +5,7 @@
#include "rrd2json.h"
-void charts2json(RRDHOST *host, BUFFER *wb, int skip_volatile);
+void charts2json(RRDHOST *host, BUFFER *wb);
const char* get_release_channel();
#endif //NETDATA_API_FORMATTER_CHARTS2JSON_H
diff --git a/web/api/formatters/json_wrapper.c b/web/api/formatters/json_wrapper.c
index baa39e2280..708a0f1f1c 100644
--- a/web/api/formatters/json_wrapper.c
+++ b/web/api/formatters/json_wrapper.c
@@ -874,7 +874,8 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb) {
sq[0] = '"';
}
- buffer_json_initialize(wb, kq, sq, 0, true, (options & RRDR_OPTION_MINIFY) ? BUFFER_JSON_OPTIONS_MINIFY : BUFFER_JSON_OPTIONS_DEFAULT);
+ buffer_json_initialize(
+ wb, kq, sq, 0, true, (options & RRDR_OPTION_MINIFY) ? BUFFER_JSON_OPTIONS_MINIFY : BUFFER_JSON_OPTIONS_DEFAULT);
buffer_json_member_add_uint64(wb, "api", 1);
buffer_json_member_add_string(wb, "id", qt->id);
@@ -1289,7 +1290,8 @@ void rrdr_json_wrapper_begin2(RRDR *r, BUFFER *wb) {
sq[0] = '\'';
}
- buffer_json_initialize(wb, kq, sq, 0, true, (options & RRDR_OPTION_MINIFY) ? BUFFER_JSON_OPTIONS_MINIFY : BUFFER_JSON_OPTIONS_DEFAULT);
+ buffer_json_initialize(
+ wb, kq, sq, 0, true, (options & RRDR_OPTION_MINIFY) ? BUFFER_JSON_OPTIONS_MINIFY : BUFFER_JSON_OPTIONS_DEFAULT);
buffer_json_member_add_uint64(wb, "api", 2);
if(options & RRDR_OPTION_DEBUG) {
diff --git a/web/api/formatters/rrd2json.c b/web/api/formatters/rrd2json.c
index 52ab31f1b0..81c9ad5c78 100644
--- a/web/api/formatters/rrd2json.c
+++ b/web/api/formatters/rrd2json.c
@@ -3,8 +3,11 @@
#include "web/api/web_api_v1.h"
#include "database/storage_engine.h"
-void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb) {
- rrdset2json(st, wb, NULL, NULL, 0);
+void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb)
+{
+ buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_DEFAULT);
+ rrdset2json(st, wb, NULL, NULL);
+ buffer_json_finalize(wb);
}
const char *rrdr_format_to_string(DATASOURCE_FORMAT format) {
diff --git a/web/api/formatters/rrdset2json.c b/web/api/formatters/rrdset2json.c
index 04250dd68b..5814cf2bce 100644
--- a/web/api/formatters/rrdset2json.c
+++ b/web/api/formatters/rrdset2json.c
@@ -2,154 +2,104 @@
#include "rrdset2json.h"
-void chart_labels2json(RRDSET *st, BUFFER *wb, size_t indentation)
+static int process_label_callback(const char *name, const char *value, RRDLABEL_SRC ls, void *data) {
+ BUFFER *wb = data;
+ buffer_json_member_add_string_or_empty(wb, name, value);
+ return 1;
+}
+
+void chart_labels2json(RRDSET *st, BUFFER *wb)
{
if(unlikely(!st->rrdlabels))
return;
- char tabs[11];
-
- if (indentation > 10)
- indentation = 10;
-
- tabs[0] = '\0';
- while (indentation) {
- strcat(tabs, "\t\t");
- indentation--;
- }
-
- rrdlabels_to_buffer(st->rrdlabels, wb, tabs, ":", "\"", ",\n", NULL, NULL, NULL, NULL);
- buffer_strcat(wb, "\n");
+ rrdlabels_walkthrough_read(st->rrdlabels, process_label_callback, wb);
}
// generate JSON for the /api/v1/chart API call
-
-void rrdset2json(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memory_used, int skip_volatile) {
+void rrdset2json(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memory_used)
+{
time_t first_entry_t = rrdset_first_entry_s(st);
time_t last_entry_t = rrdset_last_entry_s(st);
- buffer_sprintf(
- wb,
- "\t\t{\n"
- "\t\t\t\"id\": \"%s\",\n"
- "\t\t\t\"name\": \"%s\",\n"
- "\t\t\t\"type\": \"%s\",\n"
- "\t\t\t\"family\": \"%s\",\n"
- "\t\t\t\"context\": \"%s\",\n"
- "\t\t\t\"title\": \"%s (%s)\",\n"
- "\t\t\t\"priority\": %d,\n"
- "\t\t\t\"plugin\": \"%s\",\n"
- "\t\t\t\"module\": \"%s\",\n"
- "\t\t\t\"units\": \"%s\",\n"
- "\t\t\t\"data_url\": \"/api/v1/data?chart=%s\",\n"
- "\t\t\t\"chart_type\": \"%s\",\n",
- rrdset_id(st),
- rrdset_name(st),
- rrdset_parts_type(st),
- rrdset_family(st),
- rrdset_context(st),
- rrdset_title(st),
- rrdset_name(st),
- st->priority,
- rrdset_plugin_name(st),
- rrdset_module_name(st),
- rrdset_units(st),
- rrdset_name(st),
- rrdset_type_name(st->chart_type));
-
- if (likely(!skip_volatile))
- buffer_sprintf(
- wb,
- "\t\t\t\"duration\": %"PRId64",\n",
- (int64_t)(last_entry_t - first_entry_t + st->update_every) //st->entries * st->update_every
- );
-
- buffer_sprintf(
- wb,
- "\t\t\t\"first_entry\": %"PRId64",\n",
- (int64_t)first_entry_t //rrdset_first_entry_t(st)
- );
-
- if (likely(!skip_volatile))
- buffer_sprintf(
- wb,
- "\t\t\t\"last_entry\": %"PRId64",\n",
- (int64_t)last_entry_t //rrdset_last_entry_t(st)
- );
-
- buffer_sprintf(
- wb,
- "\t\t\t\"update_every\": %d,\n"
- "\t\t\t\"dimensions\": {\n",
- st->update_every);
+ buffer_json_member_add_string(wb, "id", rrdset_id(st));
+ buffer_json_member_add_string(wb, "name", rrdset_name(st));
+ buffer_json_member_add_string(wb, "type", rrdset_parts_type(st));
+ buffer_json_member_add_string(wb, "family", rrdset_family(st));
+ buffer_json_member_add_string(wb, "context", rrdset_context(st));
+ buffer_json_member_add_string(wb, "title", rrdset_title(st));
+ buffer_json_member_add_int64(wb, "priority", st->priority);
+ buffer_json_member_add_string(wb, "plugin", rrdset_plugin_name(st));
+ buffer_json_member_add_string(wb, "module", rrdset_module_name(st));
+ buffer_json_member_add_string(wb, "units", rrdset_units(st));
+
+ char data_url[RRD_ID_LENGTH_MAX + 16];
+ snprintfz(data_url, RRD_ID_LENGTH_MAX + 15, "/api/v1/chart=%s", rrdset_name(st));
+ buffer_json_member_add_string(wb, "data_url", data_url);
+
+ buffer_json_member_add_string(wb, "chart_type", rrdset_type_name(st->chart_type));
+ buffer_json_member_add_int64(wb, "duration", (int64_t)(last_entry_t - first_entry_t + st->update_every));
+ buffer_json_member_add_int64(wb, "first_entry", (int64_t)first_entry_t);
+ buffer_json_member_add_int64(wb, "last_entry", (int64_t)last_entry_t);
+ buffer_json_member_add_int64(wb, "update_every", (int64_t)st->update_every);
unsigned long memory = sizeof(RRDSET);
size_t dimensions = 0;
- RRDDIM *rd;
- rrddim_foreach_read(rd, st) {
- if(rrddim_option_check(rd, RRDDIM_OPTION_HIDDEN) || rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE)) continue;
-
- memory += rrddim_size() + rd->db.memsize;
-
- if (dimensions)
- buffer_strcat(wb, ",\n\t\t\t\t\"");
- else
- buffer_strcat(wb, "\t\t\t\t\"");
- buffer_json_strcat(wb, rrddim_id(rd));
- buffer_strcat(wb, "\": { \"name\": \"");
- buffer_json_strcat(wb, rrddim_name(rd));
- buffer_strcat(wb, "\" }");
-
- dimensions++;
+ buffer_json_member_add_object(wb, "dimensions");
+ {
+ RRDDIM *rd;
+ rrddim_foreach_read(rd, st)
+ {
+ if (rrddim_option_check(rd, RRDDIM_OPTION_HIDDEN) || rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE))
+ continue;
+
+ memory += rrddim_size() + rd->db.memsize;
+
+ buffer_json_member_add_object(wb, rrddim_id(rd));
+ buffer_json_member_add_string(wb, "name", rrddim_name(rd));
+ buffer_json_object_close(wb);
+
+ dimensions++;
+ }
+ rrddim_foreach_done(rd);
}
- rrddim_foreach_done(rd);
+ buffer_json_object_close(wb);
if(dimensions_count) *dimensions_count += dimensions;
if(memory_used) *memory_used += memory;
- buffer_sprintf(wb, "\n\t\t\t},\n\t\t\t\"chart_variables\": ");
+ buffer_json_member_add_object(wb, "chart_variables");
health_api_v1_chart_custom_variables2json(st, wb);
+ buffer_json_object_close(wb);
- buffer_strcat(wb, ",\n\t\t\t\"green\": ");
- buffer_print_netdata_double(wb, st->green);
- buffer_strcat(wb, ",\n\t\t\t\"red\": ");
- buffer_print_netdata_double(wb, st->red);
+ buffer_json_member_add_double(wb, "green", st->green);
+ buffer_json_member_add_double(wb, "red", st->red);
- if (likely(!skip_volatile)) {
- buffer_strcat(wb, ",\n\t\t\t\"alarms\": {\n");
- size_t alarms = 0;
+ {
+ buffer_json_member_add_object(wb, "alarms");
RRDCALC *rc;
rw_spinlock_read_lock(&st->alerts.spinlock);
- DOUBLE_LINKED_LIST_FOREACH_FORWARD(st->alerts.base, rc, prev, next) {
- buffer_sprintf(
- wb,
- "%s"
- "\t\t\t\t\"%s\": {\n"
- "\t\t\t\t\t\"id\": %u,\n"
- "\t\t\t\t\t\"status\": \"%s\",\n"
- "\t\t\t\t\t\"units\": \"%s\",\n"
- "\t\t\t\t\t\"update_every\": %d\n"
- "\t\t\t\t}",
- (alarms) ? ",\n" : "", rrdcalc_name(rc), rc->id, rrdcalc_status2string(rc->status), rrdcalc_units(rc),
- rc->update_every);
-
- alarms++;
+ DOUBLE_LINKED_LIST_FOREACH_FORWARD(st->alerts.base, rc, prev, next)
+ {
+ {
+ buffer_json_member_add_object(wb, rrdcalc_name(rc));
+ buffer_json_member_add_string_or_empty(wb, "id", rrdcalc_name(rc));
+ buffer_json_member_add_string_or_empty(wb, "status", rrdcalc_status2string(rc->status));
+ buffer_json_member_add_string_or_empty(wb, "units", rrdcalc_units(rc));
+ buffer_json_member_add_int64(wb, "duration", (int64_t)rc->update_every);
+ buffer_json_object_close(wb);
+ }
}
rw_spinlock_read_unlock(&st->alerts.spinlock);
- buffer_sprintf(wb,
- "\n\t\t\t}"
- );
+ buffer_json_object_close(wb);
}
- buffer_strcat(wb, ",\n\t\t\t\"chart_labels\": {\n");
- chart_labels2json(st, wb, 2);
- buffer_strcat(wb, "\t\t\t}");
- buffer_strcat(wb, ",\n\t\t\t\"functions\": {\n");
- chart_functions2json(st, wb, 4, "\"", "\"");
- buffer_strcat(wb, "\t\t\t}");
+ buffer_json_member_add_object(wb, "chart_labels");
+ chart_labels2json(st, wb);
+ buffer_json_object_close(wb);
- buffer_sprintf(wb,
- "\n\t\t}"
- );
+ buffer_json_member_add_object(wb, "functions");
+ chart_functions2json(st, wb);
+ buffer_json_object_close(wb);
}
diff --git a/web/api/formatters/rrdset2json.h b/web/api/formatters/rrdset2json.h
index b2908e225e..8b325c65dd 100644
--- a/web/api/formatters/rrdset2json.h
+++ b/web/api/formatters/rrdset2json.h
@@ -5,6 +5,6 @@
#include "rrd2json.h"
-void rrdset2json(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memory_used, int skip_volatile);
+void rrdset2json(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memory_used);
#endif //NETDATA_API_FORMATTER_RRDSET2JSON_H
diff --git a/web/api/web_api_v1.c b/web/api/web_api_v1.c
index 60fee6684b..ec0a0b6d61 100644
--- a/web/api/web_api_v1.c
+++ b/web/api/web_api_v1.c
@@ -644,7 +644,7 @@ inline int web_client_api_request_v1_charts(RRDHOST *host, struct web_client *w,
buffer_flush(w->response.data);
w->response.data->content_type = CT_APPLICATION_JSON;
- charts2json(host, w->response.data, 0);
+ charts2json(host, w->response.data);
return HTTP_RESP_OK;
}