From: Vsevolod Stakhov Date: Fri, 18 Sep 2015 16:15:18 +0000 (+0100) Subject: Add writing to rrd from the controller. X-Git-Tag: 1.0.1~22 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=07ae99830ac1cdfc7f9a1c16c5dce62eb7d00cbe;p=rspamd.git Add writing to rrd from the controller. --- diff --git a/src/controller.c b/src/controller.c index 5109fdb8c..b521eaa0e 100644 --- a/src/controller.c +++ b/src/controller.c @@ -34,6 +34,7 @@ #include "blake2.h" #include "cryptobox.h" #include "ottery.h" +#include "libutil/rrd.h" /* 60 seconds for worker's IO */ #define DEFAULT_WORKER_IO_TIMEOUT 60000 @@ -102,6 +103,11 @@ #define RSPAMD_PBKDF_ID_V1 1 +const struct timeval rrd_update_time = { + .tv_sec = 1, + .tv_usec = 0 +}; + extern struct rspamd_main *rspamd_main; gpointer init_controller_worker (struct rspamd_config *cfg); void start_controller_worker (struct rspamd_worker *worker); @@ -162,6 +168,10 @@ struct rspamd_controller_worker_ctx { /* Local keypair */ gpointer key; + + struct event *rrd_event; + struct rspamd_rrd_file *rrd; + }; struct rspamd_controller_session { @@ -1883,6 +1893,52 @@ rspamd_controller_accept_socket (gint fd, short what, void *arg) rspamd_http_router_handle_socket (ctx->http, nfd, session); } +static void +rspamd_controller_rrd_update (gint fd, short what, void *arg) +{ + struct rspamd_controller_worker_ctx *ctx = arg; + struct rspamd_stat *stat; + GArray ar; + gdouble points[4]; + GError *err = NULL; + guint i, j; + gdouble val; + + g_assert (ctx->rrd != NULL); + stat = ctx->srv->stat; + + for (i = METRIC_ACTION_REJECT, j = 0; + i <= METRIC_ACTION_NOACTION && j < G_N_ELEMENTS (points); + i++) { + switch (i) { + case METRIC_ACTION_SOFT_REJECT: + break; + case METRIC_ACTION_REWRITE_SUBJECT: + val = stat->actions_stat[i]; + break; + case METRIC_ACTION_ADD_HEADER: + val += stat->actions_stat[i]; + points[j++] = val; + break; + default: + val = stat->actions_stat[i]; + points[j++] = val; + } + } + + ar.data = (gchar *)points; + ar.len = sizeof (points); + + if (!rspamd_rrd_add_record (ctx->rrd, &ar, rspamd_get_calendar_ticks (), + &err)) { + msg_err_ctx ("cannot update rrd file: %e", err); + g_error_free (err); + } + + /* Plan new event */ + evtimer_add (ctx->rrd_event, &rrd_update_time); +} + static void rspamd_controller_load_saved_stats (struct rspamd_controller_worker_ctx *ctx) { @@ -2196,6 +2252,18 @@ start_controller_worker (struct rspamd_worker *worker) rspamd_controller_load_saved_stats (ctx); + /* RRD collector */ + if (ctx->cfg->rrd_file) { + ctx->rrd = rspamd_rrd_file_default (ctx->cfg->rrd_file, NULL); + + if (ctx->rrd) { + ctx->rrd_event = g_slice_alloc (sizeof (*ctx->rrd)); + evtimer_set (ctx->rrd_event, rspamd_controller_rrd_update, ctx); + event_base_set (ctx->ev_base, ctx->rrd_event); + event_add (ctx->rrd_event, &rrd_update_time); + } + } + rspamd_controller_password_sane (ctx, ctx->password, "normal password"); rspamd_controller_password_sane (ctx, ctx->enable_password, "enable " "password"); @@ -2299,5 +2367,9 @@ start_controller_worker (struct rspamd_worker *worker) rspamd_log_close (rspamd_main->logger); rspamd_controller_store_saved_stats (ctx); + if (ctx->rrd) { + rspamd_rrd_close (ctx->rrd); + } + exit (EXIT_SUCCESS); } diff --git a/src/libutil/rrd.c b/src/libutil/rrd.c index 7364a8729..638f44abe 100644 --- a/src/libutil/rrd.c +++ b/src/libutil/rrd.c @@ -1208,3 +1208,77 @@ rspamd_rrd_close (struct rspamd_rrd_file * file) return 0; } + +struct rspamd_rrd_file * +rspamd_rrd_file_default (const gchar *path, + GError **err) +{ + struct rspamd_rrd_file *rrd; + struct rrd_ds_def ds[4]; + struct rrd_rra_def rra[4]; + GArray ar; + + g_assert (path != NULL); + + if (access (path, R_OK) != -1) { + /* We can open rrd file */ + rrd = rspamd_rrd_open (path, err); + + if (rrd == NULL) { + return NULL; + } + + /* XXX: check rrd file sanity */ + return rrd; + } + + /* Try to create new rrd file */ + + rrd = rspamd_rrd_create (path, 4, 4, 1, rspamd_get_calendar_ticks (), err); + + if (rrd == NULL) { + return NULL; + } + + /* Create DS and RRA */ + rrd_make_default_ds ("spam", rrd_dst_to_string (RRD_DST_COUNTER), 1, &ds[0]); + rrd_make_default_ds ("probable", rrd_dst_to_string (RRD_DST_COUNTER), 1, + &ds[1]); + rrd_make_default_ds ("greylist", rrd_dst_to_string (RRD_DST_COUNTER), 1, + &ds[2]); + rrd_make_default_ds ("ham", rrd_dst_to_string (RRD_DST_COUNTER), 1, &ds[3]); + ar.data = (gchar *)ds; + ar.len = sizeof (ds); + + if (!rspamd_rrd_add_ds (rrd, &ar, err)) { + rspamd_rrd_close (rrd); + return NULL; + } + + /* Once per minute for 1 day */ + rrd_make_default_rra (rrd_cf_to_string (RRD_CF_AVERAGE), + 60, 24 * 60, &rra[0]); + /* Once per 5 minutes for 1 week */ + rrd_make_default_rra (rrd_cf_to_string (RRD_CF_AVERAGE), + 5 * 60, 7 * 24 * 60 / 5, &rra[1]); + /* Once per hour for 1 month */ + rrd_make_default_rra (rrd_cf_to_string (RRD_CF_AVERAGE), + 60 * 60, 30 * 24 * 60 / 3600, &rra[2]); + /* Once per day for 1 year */ + rrd_make_default_rra (rrd_cf_to_string (RRD_CF_AVERAGE), + 60 * 60 * 24, 365 * 24 * 60 / (60 * 60 * 24), &rra[3]); + ar.data = (gchar *)rra; + ar.len = sizeof (rra); + + if (!rspamd_rrd_add_rra (rrd, &ar, err)) { + rspamd_rrd_close (rrd); + return NULL; + } + + if (!rspamd_rrd_finalize (rrd, err)) { + rspamd_rrd_close (rrd); + return NULL; + } + + return rrd; +} diff --git a/src/libutil/rrd.h b/src/libutil/rrd.h index e6231bab8..189ea479a 100644 --- a/src/libutil/rrd.h +++ b/src/libutil/rrd.h @@ -329,4 +329,10 @@ void rrd_make_default_ds (const gchar *name, const gchar *type, gulong pdp_step, struct rrd_ds_def *ds); + +/** + * Open or create the default rspamd rrd file + */ +struct rspamd_rrd_file *rspamd_rrd_file_default (const gchar *path, + GError **err); #endif /* RRD_H_ */