aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2009-05-04 18:55:12 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2009-05-04 18:55:12 +0400
commit05556b30f9f309abc532f26c86a2e8266c2e72c7 (patch)
tree70007f830b786030de17e38df04754907094bb81 /src
parente30ea48c912be20ddc9c327205d146e46d60535e (diff)
downloadrspamd-05556b30f9f309abc532f26c86a2e8266c2e72c7.tar.gz
rspamd-05556b30f9f309abc532f26c86a2e8266c2e72c7.zip
* Add counters for rspamd symbols
* Fix shared hashes
Diffstat (limited to 'src')
-rw-r--r--src/controller.c38
-rw-r--r--src/expressions.c2
-rw-r--r--src/hash.c14
-rw-r--r--src/main.c5
-rw-r--r--src/main.h6
-rw-r--r--src/mem_pool.c31
-rw-r--r--src/mem_pool.h2
-rw-r--r--src/plugins/regexp.c26
-rw-r--r--src/util.c28
-rw-r--r--src/util.h2
10 files changed, 140 insertions, 14 deletions
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);
@@ -143,6 +152,19 @@ check_auth (struct controller_command *cmd, struct controller_session *session)
}
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)
{
char out_buf[BUFSIZ], *arg, *err_str;
@@ -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
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