summaryrefslogtreecommitdiffstats
path: root/web/api
diff options
context:
space:
mode:
Diffstat (limited to 'web/api')
-rw-r--r--web/api/badges/README.md8
-rw-r--r--web/api/badges/web_buffer_svg.c102
-rw-r--r--web/api/badges/web_buffer_svg.h2
-rw-r--r--web/api/exporters/shell/allmetrics_shell.c2
-rw-r--r--web/api/formatters/json/README.md2
-rw-r--r--web/api/queries/query.c87
6 files changed, 118 insertions, 85 deletions
diff --git a/web/api/badges/README.md b/web/api/badges/README.md
index 75c30abff..f199c5802 100644
--- a/web/api/badges/README.md
+++ b/web/api/badges/README.md
@@ -214,6 +214,14 @@ These are options dedicated to badges:
<img src="https://registry.my-netdata.io/api/v1/badge.svg?chart=system.cpu&after=-60&scale=175"></img> `scale=175`<br/>
<img src="https://registry.my-netdata.io/api/v1/badge.svg?chart=system.cpu&after=-60&scale=200"></img> `scale=200`
+- `fixed_width_lbl=NUMBER` and `fixed_width_val=NUMBER`
+
+ This parameter overrides auto-sizing of badges and displays them at fixed widths. `fixed_width_lbl` determines the size of the label's left side (label/name). `fixed_width_val` determines the size of the the label's right side (value). You must set both parameters together, or they will be ignored.
+
+ You should set the label/value widths wide enough to provide space for all the possible values/contents of the badge you're requesting. In case the text cannot fit the space given it will be clipped.
+
+ The `scale` parameter still applies on the values you give to `fixed_width_lbl` and `fixed_width_val`.
+
- `refresh=auto` or `refresh=SECONDS`
This option enables auto-refreshing of images. Netdata will send the HTTP header `Refresh: SECONDS` to the web browser, thus requesting automatic refresh of the images at regular intervals.
diff --git a/web/api/badges/web_buffer_svg.c b/web/api/badges/web_buffer_svg.c
index 143fc0f3c..ea07c894d 100644
--- a/web/api/badges/web_buffer_svg.c
+++ b/web/api/badges/web_buffer_svg.c
@@ -688,7 +688,7 @@ static inline void calc_colorz(const char *color, char *final, size_t len, calcu
// colors
#define COLOR_STRING_SIZE 100
-void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, int scale, uint32_t options) {
+void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, int scale, uint32_t options, int fixed_width_lbl, int fixed_width_val) {
char value_color_buffer[COLOR_STRING_SIZE + 1]
, value_string[VALUE_STRING_SIZE + 1]
, label_escaped[LABEL_STRING_SIZE + 1]
@@ -696,7 +696,8 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
, label_color_escaped[COLOR_STRING_SIZE + 1]
, value_color_escaped[COLOR_STRING_SIZE + 1];
- double label_width, value_width, total_width, height = 20.0, font_size = 11.0, text_offset = 5.8, round_corner = 3.0;
+ double label_width = (double)fixed_width_lbl, value_width = (double)fixed_width_val, total_width;
+ double height = 20.0, font_size = 11.0, text_offset = 5.8, round_corner = 3.0;
if(scale < 100) scale = 100;
@@ -709,8 +710,10 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
calc_colorz(value_color, value_color_buffer, COLOR_STRING_SIZE, value);
format_value_and_unit(value_string, VALUE_STRING_SIZE, (options & RRDR_OPTION_DISPLAY_ABS)?calculated_number_fabs(value):value, units, precision);
- label_width = verdana11_width(label, font_size) + (BADGE_HORIZONTAL_PADDING * 2);
- value_width = verdana11_width(value_string, font_size) + (BADGE_HORIZONTAL_PADDING * 2);
+ if(fixed_width_lbl <= 0 || fixed_width_val <= 0) {
+ label_width = verdana11_width(label, font_size) + (BADGE_HORIZONTAL_PADDING * 2);
+ value_width = verdana11_width(value_string, font_size) + (BADGE_HORIZONTAL_PADDING * 2);
+ }
total_width = label_width + value_width;
escape_xmlz(label_escaped, label, LABEL_STRING_SIZE);
@@ -740,16 +743,49 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
"<rect class=\"bdge-ttl-width\" width=\"%0.2f\" height=\"%0.2f\" rx=\"%0.2f\" fill=\"#fff\"/>"
"</mask>"
"<g mask=\"url(#round)\">"
- "<rect class=\"bdge-rect-lbl\" width=\"%0.2f\" height=\"%0.2f\" fill=\"%s\"/>"
- "<rect class=\"bdge-rect-val\" x=\"%0.2f\" width=\"%0.2f\" height=\"%0.2f\" fill=\"%s\"/>"
+ "<rect class=\"bdge-rect-lbl\" width=\"%0.2f\" height=\"%0.2f\" fill=\"%s\"/>",
+ total_width, height,
+ total_width, height, round_corner,
+ label_width, height, label_color_escaped); //<rect class="bdge-rect-lbl"
+
+ if(fixed_width_lbl > 0 && fixed_width_val > 0) {
+ buffer_sprintf(wb,
+ "<clipPath id=\"lbl-rect\">"
+ "<rect class=\"bdge-rect-lbl\" width=\"%0.2f\" height=\"%0.2f\"/>"
+ "</clipPath>",
+ label_width, height); //<clipPath id="lbl-rect"> <rect class="bdge-rect-lbl"
+ }
+
+ buffer_sprintf(wb,
+ "<rect class=\"bdge-rect-val\" x=\"%0.2f\" width=\"%0.2f\" height=\"%0.2f\" fill=\"%s\"/>",
+ label_width, value_width, height, value_color_escaped);
+
+ if(fixed_width_lbl > 0 && fixed_width_val > 0) {
+ buffer_sprintf(wb,
+ "<clipPath id=\"val-rect\">"
+ "<rect class=\"bdge-rect-val\" x=\"%0.2f\" width=\"%0.2f\" height=\"%0.2f\"/>"
+ "</clipPath>",
+ label_width, value_width, height);
+ }
+
+ buffer_sprintf(wb,
"<rect class=\"bdge-ttl-width\" width=\"%0.2f\" height=\"%0.2f\" fill=\"url(#smooth)\"/>"
"</g>"
"<g fill=\"#fff\" text-anchor=\"middle\" font-family=\"DejaVu Sans,Verdana,Geneva,sans-serif\" font-size=\"%0.2f\">"
- "<text class=\"bdge-lbl-lbl\" x=\"%0.2f\" y=\"%0.0f\" fill=\"#010101\" fill-opacity=\".3\">%s</text>"
- "<text class=\"bdge-lbl-lbl\" x=\"%0.2f\" y=\"%0.0f\">%s</text>"
- "<text class=\"bdge-lbl-val\" x=\"%0.2f\" y=\"%0.0f\" fill=\"#010101\" fill-opacity=\".3\">%s</text>"
- "<text class=\"bdge-lbl-val\" x=\"%0.2f\" y=\"%0.0f\">%s</text>"
- "</g>"
+ "<text class=\"bdge-lbl-lbl\" x=\"%0.2f\" y=\"%0.0f\" fill=\"#010101\" fill-opacity=\".3\" clip-path=\"url(#lbl-rect)\">%s</text>"
+ "<text class=\"bdge-lbl-lbl\" x=\"%0.2f\" y=\"%0.0f\" clip-path=\"url(#lbl-rect)\">%s</text>"
+ "<text class=\"bdge-lbl-val\" x=\"%0.2f\" y=\"%0.0f\" fill=\"#010101\" fill-opacity=\".3\" clip-path=\"url(#val-rect)\">%s</text>"
+ "<text class=\"bdge-lbl-val\" x=\"%0.2f\" y=\"%0.0f\" clip-path=\"url(#val-rect)\">%s</text>"
+ "</g>",
+ total_width, height,
+ font_size,
+ label_width / 2, ceil(height - text_offset), label_escaped,
+ label_width / 2, ceil(height - text_offset - 1.0), label_escaped,
+ label_width + value_width / 2 -1, ceil(height - text_offset), value_escaped,
+ label_width + value_width / 2 -1, ceil(height - text_offset - 1.0), value_escaped);
+
+ if(fixed_width_lbl <= 0 || fixed_width_val <= 0){
+ buffer_sprintf(wb,
"<script type=\"text/javascript\">"
"var bdg_horiz_padding = %d;"
"function netdata_bdge_each(list, attr, value){"
@@ -773,19 +809,10 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
"var width_update_elems = this_svg.getElementsByClassName(\"bdge-ttl-width\");"
"netdata_bdge_each(width_update_elems, \"width\", width_total);"
"this_svg.setAttribute(\"width\", width_total);"
- "</script>"
- "</svg>",
- total_width, height,
- total_width, height, round_corner,
- label_width, height, label_color_escaped,
- label_width, value_width, height, value_color_escaped,
- total_width, height,
- font_size,
- label_width / 2, ceil(height - text_offset), label_escaped,
- label_width / 2, ceil(height - text_offset - 1.0), label_escaped,
- label_width + value_width / 2 -1, ceil(height - text_offset), value_escaped,
- label_width + value_width / 2 -1, ceil(height - text_offset - 1.0), value_escaped,
- BADGE_HORIZONTAL_PADDING );
+ "</script>",
+ BADGE_HORIZONTAL_PADDING);
+ }
+ buffer_sprintf(wb, "</svg>");
}
int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *url) {
@@ -807,7 +834,9 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
, *refresh_str = NULL
, *precision_str = NULL
, *scale_str = NULL
- , *alarm = NULL;
+ , *alarm = NULL
+ , *fixed_width_lbl_str = NULL
+ , *fixed_width_val_str = NULL;
int group = RRDR_GROUPING_AVERAGE;
uint32_t options = 0x00000000;
@@ -851,9 +880,20 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
else if(!strcmp(name, "refresh")) refresh_str = value;
else if(!strcmp(name, "precision")) precision_str = value;
else if(!strcmp(name, "scale")) scale_str = value;
+ else if(!strcmp(name, "fixed_width_lbl")) fixed_width_lbl_str = value;
+ else if(!strcmp(name, "fixed_width_val")) fixed_width_val_str = value;
else if(!strcmp(name, "alarm")) alarm = value;
}
+ int fixed_width_lbl = -1;
+ int fixed_width_val = -1;
+
+ if(fixed_width_lbl_str && *fixed_width_lbl_str
+ && fixed_width_val_str && *fixed_width_val_str) {
+ fixed_width_lbl = str2i(fixed_width_lbl_str);
+ fixed_width_val = str2i(fixed_width_val_str);
+ }
+
if(!chart || !*chart) {
buffer_no_cacheable(w->response.data);
buffer_sprintf(w->response.data, "No chart id is given at the request.");
@@ -866,7 +906,7 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
if(!st) st = rrdset_find_byname(host, chart);
if(!st) {
buffer_no_cacheable(w->response.data);
- buffer_svg(w->response.data, "chart not found", NAN, "", NULL, NULL, -1, scale, 0);
+ buffer_svg(w->response.data, "chart not found", NAN, "", NULL, NULL, -1, scale, 0, -1, -1);
ret = HTTP_RESP_OK;
goto cleanup;
}
@@ -877,7 +917,7 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
rc = rrdcalc_find(st, alarm);
if (!rc) {
buffer_no_cacheable(w->response.data);
- buffer_svg(w->response.data, "alarm not found", NAN, "", NULL, NULL, -1, scale, 0);
+ buffer_svg(w->response.data, "alarm not found", NAN, "", NULL, NULL, -1, scale, 0, -1, -1);
ret = HTTP_RESP_OK;
goto cleanup;
}
@@ -995,7 +1035,9 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
value_color,
precision,
scale,
- options
+ options,
+ fixed_width_lbl,
+ fixed_width_val
);
ret = HTTP_RESP_OK;
}
@@ -1032,7 +1074,9 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
value_color,
precision,
scale,
- options
+ options,
+ fixed_width_lbl,
+ fixed_width_val
);
}
diff --git a/web/api/badges/web_buffer_svg.h b/web/api/badges/web_buffer_svg.h
index f75677bf9..f0558c078 100644
--- a/web/api/badges/web_buffer_svg.h
+++ b/web/api/badges/web_buffer_svg.h
@@ -6,7 +6,7 @@
#include "libnetdata/libnetdata.h"
#include "web/server/web_client.h"
-extern void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, int scale, uint32_t options);
+extern void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, int scale, uint32_t options, int fixed_width_lbl, int fixed_width_val);
extern char *format_value_and_unit(char *value_string, size_t value_string_len, calculated_number value, const char *units, int precision);
extern int web_client_api_request_v1_badge(struct rrdhost *host, struct web_client *w, char *url);
diff --git a/web/api/exporters/shell/allmetrics_shell.c b/web/api/exporters/shell/allmetrics_shell.c
index 9a18b92dc..90c63d443 100644
--- a/web/api/exporters/shell/allmetrics_shell.c
+++ b/web/api/exporters/shell/allmetrics_shell.c
@@ -108,6 +108,7 @@ void rrd_stats_api_v1_charts_allmetrics_json(RRDHOST *host, BUFFER *wb) {
buffer_sprintf(wb, "%s\n"
"\t\"%s\": {\n"
"\t\t\"name\":\"%s\",\n"
+ "\t\t\"family\":\"%s\",\n"
"\t\t\"context\":\"%s\",\n"
"\t\t\"units\":\"%s\",\n"
"\t\t\"last_updated\": %ld,\n"
@@ -115,6 +116,7 @@ void rrd_stats_api_v1_charts_allmetrics_json(RRDHOST *host, BUFFER *wb) {
, chart_counter?",":""
, st->id
, st->name
+ , st->family
, st->context
, st->units
, rrdset_last_entry_t(st)
diff --git a/web/api/formatters/json/README.md b/web/api/formatters/json/README.md
index 8a0e37bfc..2bd37bc7d 100644
--- a/web/api/formatters/json/README.md
+++ b/web/api/formatters/json/README.md
@@ -103,7 +103,7 @@ callback({
> Using `format=datatable` and `options=`
```bash
-$ curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=nginx_local.connections&after=-3600&points=6&group=average&formdatatable&options='
+curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=nginx_local.connections&after=-3600&points=6&group=average&formdatatable&options='
{
"cols":
[
diff --git a/web/api/queries/query.c b/web/api/queries/query.c
index af3bcfe38..6f186d3ac 100644
--- a/web/api/queries/query.c
+++ b/web/api/queries/query.c
@@ -731,6 +731,7 @@ static void rrd2rrdr_log_request_response_metdata(RRDR *r
static int rrdr_convert_before_after_to_absolute(
long long *after_requestedp
, long long *before_requestedp
+ , int update_every
, time_t first_entry_t
, time_t last_entry_t
) {
@@ -749,6 +750,12 @@ static int rrdr_convert_before_after_to_absolute(
// allow relative for before (smaller than API_RELATIVE_TIME_MAX)
if(abs(before_requested) <= API_RELATIVE_TIME_MAX) {
+ if(abs(before_requested) % update_every) {
+ // make sure it is multiple of st->update_every
+ if(before_requested < 0) before_requested = before_requested - update_every -
+ before_requested % update_every;
+ else before_requested = before_requested + update_every - before_requested % update_every;
+ }
if(before_requested > 0) before_requested = first_entry_t + before_requested;
else before_requested = last_entry_t + before_requested; //last_entry_t is not really now_t
//TODO: fix before_requested to be relative to now_t
@@ -757,6 +764,12 @@ static int rrdr_convert_before_after_to_absolute(
// allow relative for after (smaller than API_RELATIVE_TIME_MAX)
if(abs(after_requested) <= API_RELATIVE_TIME_MAX) {
+ if(after_requested == 0) after_requested = -update_every;
+ if(abs(after_requested) % update_every) {
+ // make sure it is multiple of st->update_every
+ if(after_requested < 0) after_requested = after_requested - update_every - after_requested % update_every;
+ else after_requested = after_requested + update_every - after_requested % update_every;
+ }
after_requested = before_requested + after_requested;
absolute_period_requested = 0;
}
@@ -800,28 +813,6 @@ static RRDR *rrd2rrdr_fixedstep(
) {
int aligned = !(options & RRDR_OPTION_NOT_ALIGNED);
- if(!absolute_period_requested) {
- if(before_requested % update_every) {
- // make sure it is multiple of update_every
- if(before_requested > 0)
- before_requested = before_requested - update_every + before_requested % update_every;
- #ifdef NETDATA_INTERNAL_CHECKS
- else
- error("INTERNAL ERROR: rrd2rrdr() on %s, negative or zero before_requested", st->name);
- #endif
- }
- if(after_requested % update_every) {
- // make sure it is multiple of update_every
- if(after_requested < 0)
- after_requested = after_requested - update_every + after_requested % update_every;
- #ifdef NETDATA_INTERNAL_CHECKS
- else
- error("INTERNAL ERROR: rrd2rrdr() on %s, negative or zero after_requested", st->name);
- #endif
- }
- if(after_requested == before_requested) after_requested -= update_every;
- }
-
// the duration of the chart
time_t duration = before_requested - after_requested;
long available_points = duration / update_every;
@@ -1190,28 +1181,6 @@ static RRDR *rrd2rrdr_variablestep(
) {
int aligned = !(options & RRDR_OPTION_NOT_ALIGNED);
- if(!absolute_period_requested) {
- if(before_requested % update_every) {
- // make sure it is multiple of update_every
- if(before_requested > 0)
- before_requested = before_requested - before_requested % update_every;
- #ifdef NETDATA_INTERNAL_CHECKS
- else
- error("INTERNAL ERROR: rrd2rrdr() on %s, negative or zero before_requested", st->name);
- #endif
- }
- if(after_requested % update_every) {
- // make sure it is multiple of update_every
- if(after_requested < 0)
- after_requested = after_requested - after_requested % update_every;
- #ifdef NETDATA_INTERNAL_CHECKS
- else
- error("INTERNAL ERROR: rrd2rrdr() on %s, negative or zero after_requested", st->name);
- #endif
- }
- if(after_requested == before_requested) after_requested -= update_every;
- }
-
// the duration of the chart
time_t duration = before_requested - after_requested;
long available_points = duration / update_every;
@@ -1585,9 +1554,10 @@ RRDR *rrd2rrdr(
time_t first_entry_t = rrdset_first_entry_t(st);
time_t last_entry_t = rrdset_last_entry_t(st);
+ rrd_update_every = st->update_every;
absolute_period_requested = rrdr_convert_before_after_to_absolute(&after_requested, &before_requested,
- first_entry_t, last_entry_t);
-
+ rrd_update_every, first_entry_t,
+ last_entry_t);
#ifdef ENABLE_DBENGINE
if ((st->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)) {
struct rrdeng_region_info *region_info_array;
@@ -1597,24 +1567,33 @@ RRDR *rrd2rrdr(
regions = rrdeng_variable_step_boundaries(st, after_requested, before_requested,
&region_info_array, &max_interval);
if (1 == regions) {
- if (region_info_array)
- rrd_update_every = region_info_array[0].update_every;
- else
- rrd_update_every = st->update_every;
- if (region_info_array)
- freez(region_info_array);
+ if (region_info_array) {
+ if (rrd_update_every != region_info_array[0].update_every) {
+ rrd_update_every = region_info_array[0].update_every;
+ /* recalculate query alignment */
+ absolute_period_requested =
+ rrdr_convert_before_after_to_absolute(&after_requested, &before_requested, rrd_update_every,
+ first_entry_t, last_entry_t);
+ }
+ freez(region_info_array);
+ }
return rrd2rrdr_fixedstep(st, points_requested, after_requested, before_requested, group_method,
resampling_time_requested, options, dimensions, rrd_update_every,
first_entry_t, last_entry_t, absolute_period_requested);
} else {
- rrd_update_every = (uint16_t)max_interval;
+ if (rrd_update_every != (uint16_t)max_interval) {
+ rrd_update_every = (uint16_t) max_interval;
+ /* recalculate query alignment */
+ absolute_period_requested = rrdr_convert_before_after_to_absolute(&after_requested, &before_requested,
+ rrd_update_every, first_entry_t,
+ last_entry_t);
+ }
return rrd2rrdr_variablestep(st, points_requested, after_requested, before_requested, group_method,
resampling_time_requested, options, dimensions, rrd_update_every,
first_entry_t, last_entry_t, absolute_period_requested, region_info_array);
}
}
#endif
- rrd_update_every = st->update_every;
return rrd2rrdr_fixedstep(st, points_requested, after_requested, before_requested, group_method,
resampling_time_requested, options, dimensions,
rrd_update_every, first_entry_t, last_entry_t, absolute_period_requested);