X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fredis.c;h=85a8354629240553f7e60a65ae0c5cb72446ae29;hb=9f6f901889d4c9f594b5ae1fd0f449fcdd2d8fe3;hp=12cf5840d16615450742eedaf4dc6515fb52ad12;hpb=acc9dfa25b7c0c2eedd28c3861f7ef7fc82945ed;p=collectd.git diff --git a/src/redis.c b/src/redis.c index 12cf5840..85a83546 100644 --- a/src/redis.c +++ b/src/redis.c @@ -24,12 +24,16 @@ #include "common.h" #include "plugin.h" #include "configfile.h" -#include "utils_avltree.h" #include #include +#ifndef HOST_NAME_MAX +# define HOST_NAME_MAX _POSIX_HOST_NAME_MAX +#endif + #define REDIS_DEF_HOST "localhost" +#define REDIS_DEF_PASSWD "" #define REDIS_DEF_PORT 6379 #define REDIS_DEF_TIMEOUT 2000 #define MAX_REDIS_NODE_NAME 64 @@ -45,39 +49,36 @@ * */ -static c_avl_tree_t *redis_tree = NULL; -static pthread_mutex_t redis_lock = PTHREAD_MUTEX_INITIALIZER; - -typedef struct redis_node_s { +struct redis_node_s; +typedef struct redis_node_s redis_node_t; +struct redis_node_s +{ char name[MAX_REDIS_NODE_NAME]; char host[HOST_NAME_MAX]; + char passwd[HOST_NAME_MAX]; int port; int timeout; -} redis_node_t; -static redis_node_t *redis_node_get (const char *name, redis_node_t *rn) /* {{{ */ -{ - if (c_avl_get (redis_tree, name, (void *) rn) == 0) - return (rn); - else - return (NULL); -} /* }}} */ + redis_node_t *next; +}; + +static redis_node_t *nodes_head = NULL; static int redis_node_add (const redis_node_t *rn) /* {{{ */ { - int status; - redis_node_t *rn_copy = NULL; + redis_node_t *rn_copy; redis_node_t *rn_ptr; - redis_node_t rn_get; - if (redis_tree == NULL) + /* Check for duplicates first */ + for (rn_ptr = nodes_head; rn_ptr != NULL; rn_ptr = rn_ptr->next) + if (strcmp (rn->name, rn_ptr->name) == 0) + break; + + if (rn_ptr != NULL) { - redis_tree = c_avl_create ((void *) strcmp); - if (redis_tree == NULL) - { - ERROR ("redis plugin: c_avl_create failed."); - return (-1); - } + ERROR ("redis plugin: A node with the name `%s' already exists.", + rn->name); + return (-1); } rn_copy = malloc (sizeof (*rn_copy)); @@ -88,35 +89,18 @@ static int redis_node_add (const redis_node_t *rn) /* {{{ */ } memcpy (rn_copy, rn, sizeof (*rn_copy)); - if (rn_copy->name[0] == 0) - { - /* in theory never fails */ - (void) strncpy(rn_copy->name, "default", sizeof (rn_copy->name)); - } + rn_copy->next = NULL; - DEBUG ("redis plugin: adding entry `%s' to the tree.", rn_copy->name); + DEBUG ("redis plugin: Adding node \"%s\".", rn->name); - pthread_mutex_lock (&redis_lock); - - rn_ptr = redis_node_get (rn_copy->name, &rn_get); - if (rn_ptr != NULL) - { - pthread_mutex_unlock (&redis_lock); - ERROR ("redis plugin: A node with the name `%s' already exists.", - rn_copy->name); - sfree (rn_copy); - return (-1); - } - - status = c_avl_insert (redis_tree, rn_copy->name, rn_copy); - pthread_mutex_unlock (&redis_lock); - - if (status != 0) + if (nodes_head == NULL) + nodes_head = rn_copy; + else { - ERROR ("redis plugin: c_avl_insert (%s) failed adding new node.", - rn_copy->name); - sfree (rn_copy); - return (status); + rn_ptr = nodes_head; + while (rn_ptr->next != NULL) + rn_ptr = rn_ptr->next; + rn_ptr->next = rn_copy; } return (0); @@ -154,6 +138,8 @@ static int redis_config_node (oconfig_item_t *ci) /* {{{ */ } else if (strcasecmp ("Timeout", option->key) == 0) status = cf_util_get_int (option, &rn.timeout); + else if (strcasecmp ("Password", option->key) == 0) + status = cf_util_get_string_buffer (option, rn.passwd, sizeof (rn.passwd)); else WARNING ("redis plugin: Option `%s' not allowed inside a `Node' " "block. I'll ignore this option.", option->key); @@ -183,7 +169,7 @@ static int redis_config (oconfig_item_t *ci) /* {{{ */ " configuration. It will be ignored.", option->key); } - if (redis_tree == NULL) + if (nodes_head == NULL) { ERROR ("redis plugin: No valid node configuration could be found."); return (ENOENT); @@ -218,14 +204,14 @@ static void redis_submit_g (char *plugin_instance, } /* }}} */ __attribute__ ((nonnull(2))) -static void redis_submit_c (char *plugin_instance, +static void redis_submit_d (char *plugin_instance, const char *type, const char *type_instance, - counter_t value) /* {{{ */ + derive_t value) /* {{{ */ { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - values[0].counter = value; + values[0].derive = value; vl.values = values; vl.values_len = 1; @@ -242,39 +228,56 @@ static void redis_submit_c (char *plugin_instance, plugin_dispatch_values (&vl); } /* }}} */ -static int redis_read (void) /* {{{ */ +static int redis_init (void) /* {{{ */ { - REDIS rh; - REDIS_INFO info; + redis_node_t rn = { "default", REDIS_DEF_HOST, REDIS_DEF_PASSWD, + REDIS_DEF_PORT, REDIS_DEF_TIMEOUT, /* next = */ NULL }; - char key[64]; - int status; - c_avl_iterator_t *iter; + if (nodes_head == NULL) + redis_node_add (&rn); + + return (0); +} /* }}} int redis_init */ + +static int redis_read (void) /* {{{ */ +{ redis_node_t *rn; - status = -1; - if ( (iter = c_avl_get_iterator (redis_tree)) == NULL ) + for (rn = nodes_head; rn != NULL; rn = rn->next) { - ERROR ("redis plugin: unable to iterate redis tree."); - return (-1); - } + REDIS rh; + REDIS_INFO info; + + int status; - while (c_avl_iterator_next (iter, (void *) &key, (void *) &rn) == 0) - { DEBUG ("redis plugin: querying info from node `%s' (%s:%d).", rn->name, rn->host, rn->port); - if ( (rh = credis_connect (rn->host, rn->port, rn->timeout)) == NULL ) + rh = credis_connect (rn->host, rn->port, rn->timeout); + if (rh == NULL) { ERROR ("redis plugin: unable to connect to node `%s' (%s:%d).", rn->name, rn->host, rn->port); - status = -1; - break; + continue; + } + + if (strlen (rn->passwd) > 0) + { + DEBUG ("redis plugin: authenticanting node `%s' passwd(%s).", rn->name, rn->passwd); + status = credis_auth(rh, rn->passwd); + if (status != 0) + { + WARNING ("redis plugin: unable to authenticate on node `%s'.", rn->name); + credis_close (rh); + continue; + } } - if ( (status = credis_info (rh, &info)) == -1 ) + memset (&info, 0, sizeof (info)); + status = credis_info (rh, &info); + if (status != 0) { WARNING ("redis plugin: unable to get info from node `%s'.", rn->name); credis_close (rh); - break; + continue; } /* typedef struct _cr_info { @@ -301,23 +304,14 @@ static int redis_read (void) /* {{{ */ info.total_connections_received, info.total_commands_processed, info.uptime_in_seconds); - redis_submit_g (rn->name, "connected_clients", NULL, info.connected_clients); - redis_submit_g (rn->name, "connected_slaves", NULL, info.connected_slaves); - redis_submit_g (rn->name, "used_memory", NULL, info.used_memory); - redis_submit_g (rn->name, "changes_since_last_save", NULL, info.changes_since_last_save); - redis_submit_g (rn->name, "bgsave_in_progress", NULL, info.bgsave_in_progress); - redis_submit_c (rn->name, "total_connections_received", NULL, info.total_connections_received); - redis_submit_c (rn->name, "total_commands_processed", NULL, info.total_commands_processed); - redis_submit_c (rn->name, "uptime_in_seconds", NULL, info.uptime_in_seconds); + redis_submit_g (rn->name, "current_connections", "clients", info.connected_clients); + redis_submit_g (rn->name, "current_connections", "slaves", info.connected_slaves); + redis_submit_g (rn->name, "memory", "used", info.used_memory); + redis_submit_g (rn->name, "volatile_changes", NULL, info.changes_since_last_save); + redis_submit_d (rn->name, "total_connections", NULL, info.total_connections_received); + redis_submit_d (rn->name, "total_operations", NULL, info.total_commands_processed); credis_close (rh); - status = 0; - } - - c_avl_iterator_destroy(iter); - if ( status != 0 ) - { - return (-1); } return 0; @@ -327,6 +321,7 @@ static int redis_read (void) /* {{{ */ void module_register (void) /* {{{ */ { plugin_register_complex_config ("redis", redis_config); + plugin_register_init ("redis", redis_init); plugin_register_read ("redis", redis_read); /* TODO: plugin_register_write: one redis list per value id with * X elements */