From: Vsevolod Stakhov Date: Mon, 4 May 2009 14:55:12 +0000 (+0400) Subject: * Add counters for rspamd symbols X-Git-Tag: 0.2.7~159 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=05556b30f9f309abc532f26c86a2e8266c2e72c7;p=rspamd.git * Add counters for rspamd symbols * Fix shared hashes --- diff --git a/rspamc.pl.in b/rspamc.pl.in index 9976794d0..8a0c53bea 100755 --- a/rspamc.pl.in +++ b/rspamc.pl.in @@ -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; } diff --git a/src/controller.c b/src/controller.c index b9223ff50..f20b19ee7 100644 --- a/src/controller.c +++ b/src/controller.c @@ -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 [-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 diff --git a/src/expressions.c b/src/expressions.c index 215f63897..e86802a1f 100644 --- a/src/expressions.c +++ b/src/expressions.c @@ -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; diff --git a/src/hash.c b/src/hash.c index 20989474e..a8309ff36 100644 --- a/src/hash.c +++ b/src/hash.c @@ -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); + } /* diff --git a/src/main.c b/src/main.c index d919063af..2b56cd961 100644 --- a/src/main.c +++ b/src/main.c @@ -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); diff --git a/src/main.h b/src/main.h index f7ab2eda4..c1a057824 100644 --- a/src/main.h +++ b/src/main.h @@ -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 */ diff --git a/src/mem_pool.c b/src/mem_pool.c index 66d9ace19..df4c544f9 100644 --- a/src/mem_pool.c +++ b/src/mem_pool.c @@ -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) { diff --git a/src/mem_pool.h b/src/mem_pool.h index 6875a1850..275da17d4 100644 --- a/src/mem_pool.h +++ b/src/mem_pool.h @@ -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 diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index 12feee911..4eaca581e 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -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 diff --git a/src/util.c b/src/util.c index 19afe0611..7d636b843 100644 --- a/src/util.c +++ b/src/util.c @@ -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 */ diff --git a/src/util.h b/src/util.h index 501a78cc3..2727ef4a5 100644 --- a/src/util.h +++ b/src/util.h @@ -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 diff --git a/test/rspamd_test_suite.c b/test/rspamd_test_suite.c index b3bc6c893..0f4768e73 100644 --- a/test/rspamd_test_suite.c +++ b/test/rspamd_test_suite.c @@ -13,6 +13,8 @@ #include "../src/cfg_file.h" #include "tests.h" +rspamd_hash_t *counters = NULL; + int main (int argc, char **argv) { diff --git a/utils/expression_parser.c b/utils/expression_parser.c index fa0237f3a..4f37ec923 100644 --- a/utils/expression_parser.c +++ b/utils/expression_parser.c @@ -3,6 +3,8 @@ #include "../src/cfg_file.h" #include "../src/expressions.h" +rspamd_hash_t *counters = NULL; + int main (int argc, char **argv) { diff --git a/utils/url_extracter.c b/utils/url_extracter.c index 1b98fa67e..ac8e8be4e 100644 --- a/utils/url_extracter.c +++ b/utils/url_extracter.c @@ -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)