]> source.dussan.org Git - rspamd.git/commitdiff
* Add counters for rspamd symbols
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 4 May 2009 14:55:12 +0000 (18:55 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 4 May 2009 14:55:12 +0000 (18:55 +0400)
* Fix shared hashes

14 files changed:
rspamc.pl.in
src/controller.c
src/expressions.c
src/hash.c
src/main.c
src/main.h
src/mem_pool.c
src/mem_pool.h
src/plugins/regexp.c
src/util.c
src/util.h
test/rspamd_test_suite.c
utils/expression_parser.c
utils/url_extracter.c

index 9976794d0055baee687cd9bd97f17654d971cb6a..8a0c53bea521ca8754c451d5b5265c1366b80591 100755 (executable)
@@ -215,7 +215,7 @@ while (my $param = shift) {
         $cfg{'command'} = $1;
         $cfg{'control'} = 0;
     }
-    elsif ($param =~ /(STAT|LEARN|SHUTDOWN|RELOAD|UPTIME)/i) {
+    elsif ($param =~ /(STAT|LEARN|SHUTDOWN|RELOAD|UPTIME|COUNTERS)/i) {
         $cfg{'command'} = $1;
         $cfg{'control'} = 1;
     }
index b9223ff50abc01cae4cb2a3ef192c98fbaba930d..f20b19ee7dedb37431024e92bfc57b302f9b16bc 100644 (file)
@@ -48,6 +48,7 @@ enum command_type {
        COMMAND_UPTIME,
        COMMAND_LEARN,
        COMMAND_HELP,
+       COMMAND_COUNTERS,
 };
 
 struct controller_command {
@@ -65,6 +66,7 @@ static struct controller_command commands[] = {
        {"uptime", 0, COMMAND_UPTIME},
        {"learn", 1, COMMAND_LEARN},
        {"help", 0, COMMAND_HELP},
+       {"counters", 0, COMMAND_COUNTERS},
 };
 
 static GCompletion *comp;
@@ -72,6 +74,7 @@ static time_t start_time;
 
 static char greetingbuf[1024];
 static struct timeval io_tv;
+extern rspamd_hash_t *counters;
 
 static 
 void sig_handler (int signo)
@@ -108,13 +111,12 @@ completion_func (gpointer elem)
 }
 
 static void
-free_session (struct controller_session *session)
+free_session (struct controller_session *session, gboolean is_soft)
 {
        GList *part;
        struct mime_part *p;
        
        msg_debug ("free_session: freeing session %p", session);
-       rspamd_remove_dispatcher (session->dispatcher);
        
        while ((part = g_list_first (session->parts))) {
                session->parts = g_list_remove_link (session->parts, part);
@@ -122,6 +124,13 @@ free_session (struct controller_session *session)
                g_byte_array_free (p->content, FALSE);
                g_list_free_1 (part);
        }
+       if (is_soft) {
+               /* Plan dispatcher shutdown */
+               session->dispatcher->wanna_die = 1;
+       }
+       else {
+               rspamd_remove_dispatcher (session->dispatcher);
+       }
 
        memory_pool_delete (session->session_pool);
        g_free (session);
@@ -142,6 +151,19 @@ check_auth (struct controller_command *cmd, struct controller_session *session)
        return 1;
 }
 
+static void
+counter_write_callback (gpointer key, gpointer value, void *data)
+{
+       struct controller_session *session = data;
+       struct counter_data *cd = value;
+       char *name = key;
+       char out_buf[128];
+       int r;
+
+       r = snprintf (out_buf, sizeof (out_buf), "%s: %llu" CRLF, name, (unsigned long long int)cd->value);
+       rspamd_dispatcher_write (session->dispatcher, out_buf, r, TRUE);
+}
+
 static void
 process_command (struct controller_command *cmd, char **cmd_args, struct controller_session *session)
 {
@@ -348,7 +370,7 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                        }
                        break;
                case COMMAND_HELP:
-                               r = snprintf (out_buf, sizeof (out_buf), 
+                       r = snprintf (out_buf, sizeof (out_buf), 
                                                        "Rspamd CLI commands (* - privilleged command):" CRLF
                                                        "    help - this help message" CRLF
                                                        "(*) learn <statfile> <size> [-r recipient], [-f from] [-n] - learn message to specified statfile" CRLF
@@ -356,8 +378,12 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                                                        "(*) reload - reload rspamd" CRLF
                                                        "(*) shutdown - shutdown rspamd" CRLF
                                                        "    stat - show different rspamd stat" CRLF
+                                                       "    counters - show rspamd counters" CRLF
                                                        "    uptime - rspamd uptime" CRLF);
-                               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE);
+                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE);
+                       break;
+               case COMMAND_COUNTERS:
+                       rspamd_hash_foreach (counters, counter_write_callback, session);
                        break;
        }
 }
@@ -454,7 +480,7 @@ controller_write_socket (void *arg)
                msg_info ("closing control connection");
                /* Free buffers */
                close (session->sock);
-               free_session (session);
+               free_session (session, TRUE);
                return;
        }
        else if (session->state == STATE_REPLY) {
@@ -475,7 +501,7 @@ controller_err_socket (GError *err, void *arg)
                msg_info ("controller_err_socket: abnormally closing control connection, error: %s", err->message);
        }
        /* Free buffers */
-       free_session (session);
+       free_session (session, FALSE);
 }
 
 static void
index 215f63897429a2bc4279a6601d0d2a1c67b05114..e86802a1ff9a84cf9f354d1330172cc8ad464c31 100644 (file)
@@ -500,7 +500,7 @@ parse_regexp (memory_pool_t *pool, char *line, gboolean raw_mode)
 {
        char *begin, *end, *p, *src;
        struct rspamd_regexp *result, *check;
-       int regexp_flags = 0;
+       int regexp_flags = G_REGEX_OPTIMIZE | G_REGEX_NO_AUTO_CAPTURE;
        GError *err = NULL;
        
        src = line;
index 20989474e5c60cb0e58246f2b9b6152b910c9fd5..a8309ff36eb8ff99d5852fb7c22589b00ec68179 100644 (file)
@@ -114,8 +114,12 @@ rspamd_hash_resize (rspamd_hash_t *hash)
 
        new_size = g_spaced_primes_closest (hash->nnodes);
        new_size = CLAMP (new_size, HASH_TABLE_MIN_SIZE, HASH_TABLE_MAX_SIZE);
-
-       new_nodes = memory_pool_alloc (hash->pool, sizeof (struct rspamd_hash_node *) * new_size);
+       
+       if (hash->shared) {
+               new_nodes = memory_pool_alloc_shared (hash->pool, sizeof (struct rspamd_hash_node *) * new_size);
+       } else {
+               new_nodes = memory_pool_alloc (hash->pool, sizeof (struct rspamd_hash_node *) * new_size);
+       }
 
        if (hash->shared) {
                memory_pool_wlock_rwlock (hash->lock);
@@ -184,7 +188,7 @@ rspamd_hash_new_shared (memory_pool_t *pool, GHashFunc hash_func, GEqualFunc key
        hash->nnodes             = 0;
        hash->hash_func          = hash_func ? hash_func : g_direct_hash;
        hash->key_equal_func     = key_equal_func;
-       hash->nodes              = memory_pool_alloc0 (pool, sizeof (struct rspamd_hash_node*) * hash->size);
+       hash->nodes              = memory_pool_alloc0_shared (pool, sizeof (struct rspamd_hash_node*) * hash->size);
        hash->shared             = 1;
        /* Get mutex from pool for locking on insert/remove operations */
        hash->lock               = memory_pool_get_rwlock (pool);
@@ -227,13 +231,13 @@ rspamd_hash_insert (rspamd_hash_t *hash, gpointer key, gpointer value)
                
                *node_ptr = node;
                hash->nnodes ++;
-               rspamd_hash_maybe_resize (hash);
-
     }
        if (hash->shared) {
                memory_pool_wunlock_rwlock (hash->lock);
        }
 
+       rspamd_hash_maybe_resize (hash);
+
 }
 
 /* 
index d919063af29494c908c09f547d63500b9b856085..2b56cd96123b5f450b8780e74c47a88c02c4ca40 100644 (file)
@@ -48,6 +48,8 @@
 
 struct config_file *cfg;
 
+rspamd_hash_t *counters;
+
 static void sig_handler (int );
 static struct rspamd_worker * fork_worker (struct rspamd_main *, int, enum process_type);
        
@@ -571,6 +573,9 @@ main (int argc, char **argv, char **env)
 
        /* Init statfile pool */
        rspamd->statfile_pool = statfile_pool_new (cfg->max_statfile_size);
+
+       /* Init counters */
+       counters = rspamd_hash_new_shared (rspamd->server_pool, g_str_hash, g_str_equal);
        
        for (i = 0; i < cfg->workers_number; i++) {
                fork_worker (rspamd, listen_sock, TYPE_WORKER);
index f7ab2eda4bda140f15617f8f67a5bf8eea8abae5..c1a057824d1d0488eb26a8f6d5b07f68418ddb45 100644 (file)
@@ -15,6 +15,7 @@
 #include "protocol.h"
 #include "filter.h"
 #include "buffer.h"
+#include "hash.h"
 
 /* Default values */
 #define FIXED_CONFIG_FILE CMAKE_PREFIX "/etc/rspamd.conf"
@@ -107,6 +108,11 @@ struct rspamd_main {
        TAILQ_HEAD (workq, rspamd_worker) workers;                                      /**< linked list of workers                                                     */
 };
 
+struct counter_data {
+       uint64_t value;
+       int number;
+};
+
 /**
  * Save point object for delayed filters processing
  */
index 66d9ace19a7936645eb423aacac8208d391731ba..df4c544f93d53231cfa7ab424018e9b236d148ed 100644 (file)
@@ -200,6 +200,16 @@ memory_pool_alloc0 (memory_pool_t *pool, memory_pool_ssize_t size)
        return pointer;
 }
 
+void *
+memory_pool_alloc0_shared (memory_pool_t *pool, memory_pool_ssize_t size)
+{
+       void *pointer = memory_pool_alloc_shared (pool, size);
+       if (pointer) {
+               bzero (pointer, size);
+       }
+       return pointer;
+}
+
 char *
 memory_pool_strdup (memory_pool_t *pool, const char *src)
 {
@@ -212,10 +222,29 @@ memory_pool_strdup (memory_pool_t *pool, const char *src)
 
        len = strlen (src);
        newstr = memory_pool_alloc (pool, len + 1);
-       memcpy (newstr, src, len + 1);
+       memcpy (newstr, src, len);
+       newstr[len] = '\0';
+       return newstr;
+}
+
+char *
+memory_pool_strdup_shared (memory_pool_t *pool, const char *src)
+{
+       memory_pool_ssize_t len;
+       char *newstr;
+
+       if (src == NULL) {
+               return NULL;
+       }
+
+       len = strlen (src);
+       newstr = memory_pool_alloc_shared (pool, len + 1);
+       memcpy (newstr, src, len);
+       newstr[len] = '\0';
        return newstr;
 }
 
+
 void *
 memory_pool_alloc_shared (memory_pool_t *pool, memory_pool_ssize_t size)
 {
index 6875a1850fb15a6b68c81e29604e421568ceefa9..275da17d4b942e24903adb56c230a2c942c28b27 100644 (file)
@@ -122,6 +122,8 @@ char* memory_pool_strdup (memory_pool_t* pool, const char *src);
  * @param size bytes to allocate
  */
 void* memory_pool_alloc_shared (memory_pool_t *pool, memory_pool_ssize_t size);
+void* memory_pool_alloc0_shared (memory_pool_t *pool, memory_pool_ssize_t size);
+char* memory_pool_strdup_shared (memory_pool_t* pool, const char *src);
 
 /**
  * Lock chunk of shared memory in which pointer is placed
index 12feee9117f50da82b90fd239774945ffaa55114..4eaca581e2e974147167e9d355e78c3ddf03c624 100644 (file)
@@ -34,6 +34,7 @@
 #include "../message.h"
 #include "../modules.h"
 #include "../cfg_file.h"
+#include "../util.h"
 #include "../expressions.h"
 
 #define DEFAULT_STATFILE_PREFIX "./"
@@ -41,6 +42,7 @@
 struct regexp_module_item {
        struct expression *expr;
        char *symbol;
+    long int avg_time;
 };
 
 struct autolearn_data {
@@ -501,7 +503,7 @@ process_regexp_expression (struct expression *expr, struct worker_task *task)
        else {
                msg_warn ("process_regexp_expression: regexp expression seems to be invalid: empty stack at the end of expression");
        }
-
+       
        g_queue_free (stack);
 
        return FALSE;
@@ -510,9 +512,31 @@ process_regexp_expression (struct expression *expr, struct worker_task *task)
 static void
 process_regexp_item (struct regexp_module_item *item, struct worker_task *task)
 {
+    struct timespec ts1, ts2;
+       uint64_t diff;
+
+#ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
+       clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts1);
+#elif defined(HAVE_CLOCK_VIRTUAL)
+       clock_gettime (CLOCK_VIRTUAL, &ts1);
+#else
+       clock_gettime (CLOCK_REALTIME, &ts1);
+#endif
+
        if (process_regexp_expression (item->expr, task)) {
                insert_result (task, regexp_module_ctx->metric, item->symbol, 1, NULL);
        }
+
+#ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
+       clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts2);
+#elif defined(HAVE_CLOCK_VIRTUAL)
+       clock_gettime (CLOCK_VIRTUAL, &ts2);
+#else
+       clock_gettime (CLOCK_REALTIME, &ts2);
+#endif
+
+       diff = (ts2.tv_sec - ts1.tv_sec) * 1000000 + (ts2.tv_nsec - ts1.tv_nsec) / 1000;
+       set_counter (item->symbol, diff);
 }
 
 static int
index 19afe0611fa4fffb39437fa932625c82074005c4..7d636b84315b293e293421c98f5d0f182045602f 100644 (file)
@@ -29,6 +29,7 @@
 #include "main.h"
 
 sig_atomic_t do_reopen_log = 0;
+extern rspamd_hash_t *counters;
 
 int
 make_socket_nonblocking (int fd)
@@ -811,6 +812,33 @@ calculate_check_time (struct timespec *begin, int resolution)
        return (const char *)res;
 }
 
+void 
+set_counter (const char *name, long int value)
+{
+       struct counter_data *cd;
+       double alpha;
+       char *key;
+
+       cd = rspamd_hash_lookup (counters, (gpointer)name);
+
+       if (cd == NULL) {
+               cd = memory_pool_alloc_shared (counters->pool, sizeof (struct counter_data));
+               cd->value = value;
+               cd->number = 1;
+               key = memory_pool_strdup_shared (counters->pool, name);
+               rspamd_hash_insert (counters, (gpointer)key, (gpointer)cd);
+       }
+       else {
+               /* Calculate new value */
+               memory_pool_wlock_rwlock (counters->lock);
+
+               alpha = 2. / (++cd->number + 1);
+               cd->value = cd->value * (1. - alpha) + value * alpha;
+
+               memory_pool_wunlock_rwlock (counters->lock);
+       }
+}
+
 /*
  * vi:ts=4
  */
index 501a78cc3853b0eaf04c2c8590969d699528e7d4..2727ef4a5b235c6f02bf2d019bce8de2e8d09d14 100644 (file)
@@ -57,4 +57,6 @@ void file_log_function (const gchar *log_domain, GLogLevelFlags log_level, const
 char* resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *from);
 const char* calculate_check_time (struct timespec *begin, int resolution);
 
+void set_counter (const char *name, long int value);
+
 #endif
index b3bc6c89392fba158ba5d0e79a589fdb85186673..0f4768e731fa8262c65b9164b23a45bc44472794 100644 (file)
@@ -13,6 +13,8 @@
 #include "../src/cfg_file.h"
 #include "tests.h"
 
+rspamd_hash_t *counters = NULL;
+
 int
 main (int argc, char **argv)
 {
index fa0237f3a3d8076a00a19093cdbbcf0167d355a3..4f37ec9239f01eb465414df6327bd209bfb63a4d 100644 (file)
@@ -3,6 +3,8 @@
 #include "../src/cfg_file.h"
 #include "../src/expressions.h"
 
+rspamd_hash_t *counters = NULL;
+
 int 
 main (int argc, char **argv)
 {
index 1b98fa67e46d8463d184fae27481bb0c4156bbff..ac8e8be4e956b84c5d9094678b3cd31241af0afb 100644 (file)
@@ -26,6 +26,7 @@
 #include "../src/url.h"
 #include "../src/message.h"
 
+rspamd_hash_t *counters = NULL;
 #ifdef GMIME24
 static void
 mime_foreach_callback (GMimeObject *parent, GMimeObject *part, gpointer user_data)