summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-07-02 13:08:42 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-07-02 13:08:42 +0100
commit47d2721f8b7a7f2c40a0cea3c3b1040450546d69 (patch)
tree2702ca920977e15ae022e2d540b8a5053da655f5
parent1e9599d405984d5654d5f0752b63d9f4eec19652 (diff)
downloadrspamd-47d2721f8b7a7f2c40a0cea3c3b1040450546d69.tar.gz
rspamd-47d2721f8b7a7f2c40a0cea3c3b1040450546d69.zip
[Feature] Interpolate points sent to webui
-rw-r--r--src/controller.c86
1 files changed, 63 insertions, 23 deletions
diff --git a/src/controller.c b/src/controller.c
index 78c168460..486957375 100644
--- a/src/controller.c
+++ b/src/controller.c
@@ -1022,6 +1022,45 @@ rspamd_controller_handle_pie_chart (
return 0;
}
+void
+rspamd_controller_graph_point (gulong t, gulong step,
+ struct rspamd_rrd_query_result* rrd_result,
+ gdouble *acc,
+ ucl_object_t **elt)
+{
+ guint nan_cnt;
+ gdouble sum = 0.0, yval;
+ ucl_object_t* data_elt;
+ guint i, j;
+
+ for (i = 0; i < rrd_result->ds_count; i++) {
+ sum = 0.0;
+ nan_cnt = 0;
+ data_elt = ucl_object_typed_new (UCL_OBJECT);
+ ucl_object_insert_key (data_elt, ucl_object_fromint (t), "x", 1, false);
+
+ for (j = 0; j < step; j++) {
+ yval = acc[i + j * rrd_result->ds_count];
+ if (isnan(yval)) {
+ nan_cnt++;
+ }
+ else {
+ sum += yval;
+ }
+ }
+ if (nan_cnt == step) {
+ ucl_object_insert_key (data_elt, ucl_object_typed_new (UCL_NULL),
+ "y", 1, false);
+ }
+ else {
+ ucl_object_insert_key (data_elt,
+ ucl_object_fromdouble (sum / (gdouble) step), "y", 1,
+ false);
+ }
+ ucl_array_append (elt[i], data_elt);
+ }
+}
+
/*
* Graph command handler:
* request: /graph?type=<hourly|daily|weekly|monthly>
@@ -1042,9 +1081,9 @@ rspamd_controller_handle_graph (
struct rspamd_controller_worker_ctx *ctx;
rspamd_ftok_t srch, *value;
struct rspamd_rrd_query_result *rrd_result;
- gulong i, j, start_row, cnt, t, ts;
- gdouble yval, last = 0;
- ucl_object_t *res, *elt[4], *data_elt;
+ gulong i, j, k, start_row, cnt, t, ts, step;
+ gdouble *acc;
+ ucl_object_t *res, *elt[4];
enum {
rra_hourly = 0,
rra_daily,
@@ -1052,6 +1091,8 @@ rspamd_controller_handle_graph (
rra_monthly,
rra_invalid
} rra_num = rra_invalid;
+ /* How many points are we going to send to display */
+ static const guint desired_points = 500;
ctx = session->ctx;
@@ -1125,43 +1166,42 @@ rspamd_controller_handle_graph (
start_row = rrd_result->cur_row == rrd_result->rra_rows - 1 ?
0 : rrd_result->cur_row;
+ /* Create window */
+ step = (rrd_result->rra_rows / desired_points + 0.5);
+ acc = g_malloc0 (sizeof (double) * rrd_result->ds_count * step);
+
for (i = start_row, cnt = 0; cnt < rrd_result->rra_rows; cnt ++) {
for (j = 0; j < rrd_result->ds_count; j++) {
-
- data_elt = ucl_object_typed_new (UCL_OBJECT);
- t = ts * rrd_result->pdp_per_cdp;
- ucl_object_insert_key (data_elt,
- ucl_object_fromint (t),
- "x", 1,
- false);
- yval = rrd_result->data[i * rrd_result->ds_count + j];
-
- if (!isnan (yval)) {
- ucl_object_insert_key (data_elt,
- ucl_object_fromdouble (yval),
- "y", 1,
- false);
- last = yval;
+ if (k < step) {
+ /* Just update window */
+ acc[k * rrd_result->ds_count + j] =
+ rrd_result->data[i * rrd_result->ds_count + j];
+ k ++;
}
else {
- ucl_object_insert_key (data_elt,
- ucl_object_fromdouble (last),
- "y", 1,
- false);
+ t = ts * rrd_result->pdp_per_cdp;
+
+ /* Need a fresh point */
+ rspamd_controller_graph_point (t, step, rrd_result, acc, elt);
+ k = 0;
}
- ucl_array_append (elt[j], data_elt);
}
i = start_row == 0 ? i + 1 : (i + 1) % start_row;
ts ++;
}
+ if (k > 0) {
+ rspamd_controller_graph_point (t, k, rrd_result, acc, elt);
+ }
+
for (i = 0; i < rrd_result->ds_count; i++) {
ucl_array_append (res, elt[i]);
}
rspamd_controller_send_ucl (conn_ent, res);
ucl_object_unref (res);
+ g_free (acc);
return 0;
}