]> source.dussan.org Git - rspamd.git/commitdiff
Add writing to rrd from the controller.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 18 Sep 2015 16:15:18 +0000 (17:15 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 18 Sep 2015 16:15:18 +0000 (17:15 +0100)
src/controller.c
src/libutil/rrd.c
src/libutil/rrd.h

index 5109fdb8c404f148069c4b24fed34872c38d13a1..b521eaa0ed2ddb2c90ce408c02c459ce18a05dd4 100644 (file)
@@ -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
 
 #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);
 }
index 7364a8729731b0ac441af2a33a65659a058f1a4c..638f44abee9ab417d2d55469259e7cf9fd8c3821 100644 (file)
@@ -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;
+}
index e6231bab8c2d5fa9a9c9374257bf86b944dc8254..189ea479a8618d422a7c0282dc305fea26de2942 100644 (file)
@@ -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_ */