X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fpinba.c;h=9f0a80023324d55c00871c2299a22aa484978f74;hp=46a2ca33f23fea59d2cdff4a47248859c3da12e9;hb=633c3966f770e4d46651a2fe219a18d8a9907a9f;hpb=774b407e1ecc65d8b1d3922ea50fb5290ad4a5ef diff --git a/src/pinba.c b/src/pinba.c index 46a2ca33..9f0a8002 100644 --- a/src/pinba.c +++ b/src/pinba.c @@ -20,7 +20,7 @@ * Authors: * Antony Dovgal * Phoenix Kayo - * Florian Forster + * Florian Forster **/ #include "collectd.h" @@ -35,6 +35,11 @@ #include "pinba.pb-c.h" +/* AIX doesn't have MSG_DONTWAIT */ +#ifndef MSG_DONTWAIT +# define MSG_DONTWAIT MSG_NONBLOCK +#endif + /* * Defines */ @@ -43,11 +48,11 @@ #endif #ifndef PINBA_DEFAULT_NODE -# define PINBA_DEFAULT_NODE "127.0.0.1" /* FIXME */ +# define PINBA_DEFAULT_NODE "::0" #endif #ifndef PINBA_DEFAULT_SERVICE -# define PINBA_DEFAULT_SERVICE "12345" /* FIXME */ +# define PINBA_DEFAULT_SERVICE "30002" #endif #ifndef PINBA_MAX_SOCKETS @@ -57,26 +62,14 @@ /* * Private data structures */ -typedef struct _pinba_statres_ pinba_statres_t; -struct _pinba_statres_ { - const char *name; - double req_per_sec; - double req_time; - double ru_utime; - double ru_stime; - double doc_size; - double mem_peak; -}; - -struct pinba_socket_s { +/* {{{ */ +struct pinba_socket_s +{ struct pollfd fd[PINBA_MAX_SOCKETS]; nfds_t fd_num; }; typedef struct pinba_socket_s pinba_socket_t; -typedef double pinba_time_t; -typedef uint32_t pinba_size_t; - /* Fixed point counter value. n is the decimal part multiplied by 10^9. */ struct float_counter_s { @@ -87,7 +80,7 @@ typedef struct float_counter_s float_counter_t; struct pinba_statnode_s { - /* collector name */ + /* collector name, used as plugin instance */ char *name; /* query data */ @@ -105,10 +98,12 @@ struct pinba_statnode_s gauge_t mem_peak; }; typedef struct pinba_statnode_s pinba_statnode_t; +/* }}} */ /* * Module global variables */ +/* {{{ */ static pinba_statnode_t *stat_nodes = NULL; static unsigned int stat_nodes_num = 0; static pthread_mutex_t stat_nodes_lock; @@ -119,6 +114,7 @@ static char *conf_service = NULL; static _Bool collector_thread_running = 0; static _Bool collector_thread_do_shutdown = 0; static pthread_t collector_thread_id; +/* }}} */ /* * Functions @@ -144,12 +140,15 @@ static void float_counter_add (float_counter_t *fc, float val) /* {{{ */ } } /* }}} void float_counter_add */ -static derive_t float_counter_get (const float_counter_t *fc) /* {{{ */ +static derive_t float_counter_get (const float_counter_t *fc, /* {{{ */ + uint64_t factor) { - if (fc->n >= 500000000) - return ((derive_t) (fc->i + 1)); - else - return ((derive_t) fc->i); + derive_t ret; + + ret = (derive_t) (fc->i * factor); + ret += (derive_t) (fc->n / (1000000000 / factor)); + + return (ret); } /* }}} derive_t float_counter_get */ static void strset (char **str, const char *new) /* {{{ */ @@ -195,10 +194,10 @@ static void service_statnode_add(const char *name, /* {{{ */ node->mem_peak = NAN; /* fill query data */ - strset(&node->name, name); - strset(&node->host, host); - strset(&node->server, server); - strset(&node->script, script); + strset (&node->name, name); + strset (&node->host, host); + strset (&node->server, server); + strset (&node->script, script); /* increment counter */ stat_nodes_num++; @@ -260,11 +259,16 @@ static void service_process_request (Pinba__Request *request) /* {{{ */ for (i = 0; i < stat_nodes_num; i++) { - if(stat_nodes[i].host && strcmp(request->hostname, stat_nodes[i].host)) + if ((stat_nodes[i].host != NULL) + && (strcmp (request->hostname, stat_nodes[i].host) != 0)) continue; - if(stat_nodes[i].server && strcmp(request->server_name, stat_nodes[i].server)) + + if ((stat_nodes[i].server != NULL) + && (strcmp (request->server_name, stat_nodes[i].server) != 0)) continue; - if(stat_nodes[i].script && strcmp(request->script_name, stat_nodes[i].script)) + + if ((stat_nodes[i].script != NULL) + && (strcmp (request->script_name, stat_nodes[i].script) != 0)) continue; service_statnode_process(&stat_nodes[i], request); @@ -378,7 +382,7 @@ static pinba_socket_t *pinba_socket_open (const char *node, /* {{{ */ assert (ai_list != NULL); s = malloc (sizeof (*s)); - if (s != NULL) + if (s == NULL) { freeaddrinfo (ai_list); ERROR ("pinba plugin: malloc failed."); @@ -559,102 +563,94 @@ static void *collector_thread (void *arg) /* {{{ */ /* * Plugin declaration section */ - -static int config_set (char **var, const char *value) /* {{{ */ +static int pinba_config_view (const oconfig_item_t *ci) /* {{{ */ { - /* code from nginx plugin for collectd */ - if (*var != NULL) { - free (*var); - *var = NULL; + char *name = NULL; + char *host = NULL; + char *server = NULL; + char *script = NULL; + int status; + int i; + + status = cf_util_get_string (ci, &name); + if (status != 0) + return (status); + + for (i = 0; i < ci->children_num; i++) + { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp ("Host", child->key) == 0) + status = cf_util_get_string (child, &host); + else if (strcasecmp ("Server", child->key) == 0) + status = cf_util_get_string (child, &server); + else if (strcasecmp ("Script", child->key) == 0) + status = cf_util_get_string (child, &script); + else + { + WARNING ("pinba plugin: Unknown config option: %s", child->key); + status = -1; + } + + if (status != 0) + break; } - - if ((*var = strdup (value)) == NULL) return (1); - else return (0); -} /* }}} int config_set */ + + if (status == 0) + service_statnode_add (name, host, server, script); + + sfree (name); + sfree (host); + sfree (server); + sfree (script); + + return (status); +} /* }}} int pinba_config_view */ static int plugin_config (oconfig_item_t *ci) /* {{{ */ { - unsigned int i, o; + int i; + /* The lock should not be necessary in the config callback, but let's be + * sure.. */ pthread_mutex_lock (&stat_nodes_lock); - /* FIXME XXX: Remove all those return statements that don't free the lock. */ - if (stat_nodes == NULL) + for (i = 0; i < ci->children_num; i++) { - /* Collect the "total" data by default. */ - service_statnode_add ("total", - /* host = */ NULL, - /* server = */ NULL, - /* script = */ NULL); - } - - for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Address", child->key) == 0) { - if ((child->values_num != 1) || (child->values[0].type != OCONFIG_TYPE_STRING)){ - WARNING ("pinba plugin: `Address' needs exactly one string argument."); - return (-1); - } - config_set(&conf_node, child->values[0].value.string); - } else if (strcasecmp ("Port", child->key) == 0) { - if ((child->values_num != 1) || (child->values[0].type != OCONFIG_TYPE_STRING)){ - WARNING ("pinba plugin: `Port' needs exactly one string argument."); - return (-1); - } - config_set(&conf_service, child->values[0].value.string); - } else if (strcasecmp ("View", child->key) == 0) { - const char *name=NULL, *host=NULL, *server=NULL, *script=NULL; - if ((child->values_num != 1) || (child->values[0].type != OCONFIG_TYPE_STRING) || strlen(child->values[0].value.string)==0){ - WARNING ("pinba plugin: `View' needs exactly one non-empty string argument."); - return (-1); - } - name = child->values[0].value.string; - for(o=0; ochildren_num; o++){ - oconfig_item_t *node = child->children + o; - if (strcasecmp ("Host", node->key) == 0) { - if ((node->values_num != 1) || (node->values[0].type != OCONFIG_TYPE_STRING) || strlen(node->values[0].value.string)==0){ - WARNING ("pinba plugin: `View->Host' needs exactly one non-empty string argument."); - return (-1); - } - host = node->values[0].value.string; - } else if (strcasecmp ("Server", node->key) == 0) { - if ((node->values_num != 1) || (node->values[0].type != OCONFIG_TYPE_STRING) || strlen(node->values[0].value.string)==0){ - WARNING ("pinba plugin: `View->Server' needs exactly one non-empty string argument."); - return (-1); - } - server = node->values[0].value.string; - } else if (strcasecmp ("Script", node->key) == 0) { - if ((node->values_num != 1) || (node->values[0].type != OCONFIG_TYPE_STRING) || strlen(node->values[0].value.string)==0){ - WARNING ("pinba plugin: `View->Script' needs exactly one non-empty string argument."); - return (-1); - } - script = node->values[0].value.string; - } else { - WARNING ("pinba plugin: In `' context allowed only `Host', `Server' and `Script' options but not the `%s'.", node->key); - return (-1); - } - } - /* add new statnode */ - service_statnode_add(name, host, server, script); - } else { - WARNING ("pinba plugin: In `' context allowed only `Address', `Port' and `Observe' options but not the `%s'.", child->key); - return (-1); - } + + if (strcasecmp ("Address", child->key) == 0) + cf_util_get_string (child, &conf_node); + else if (strcasecmp ("Port", child->key) == 0) + cf_util_get_service (child, &conf_service); + else if (strcasecmp ("View", child->key) == 0) + pinba_config_view (child); + else + WARNING ("pinba plugin: Unknown config option: %s", child->key); } - + pthread_mutex_unlock(&stat_nodes_lock); return (0); -} /* int pinba_config */ +} /* }}} int pinba_config */ static int plugin_init (void) /* {{{ */ { int status; + if (stat_nodes == NULL) + { + /* Collect the "total" data by default. */ + service_statnode_add ("total", + /* host = */ NULL, + /* server = */ NULL, + /* script = */ NULL); + } + if (collector_thread_running) return (0); - status = pthread_create (&collector_thread_id, + status = plugin_thread_create (&collector_thread_id, /* attrs = */ NULL, collector_thread, /* args = */ NULL); @@ -706,19 +702,23 @@ static int plugin_submit (const pinba_statnode_t *res) /* {{{ */ sstrncpy (vl.plugin_instance, res->name, sizeof (vl.plugin_instance)); value.derive = res->req_count; - sstrncpy (vl.type, "requests", sizeof (vl.type)); + sstrncpy (vl.type, "total_requests", sizeof (vl.type)); + plugin_dispatch_values (&vl); + + value.derive = float_counter_get (&res->req_time, /* factor = */ 1000); + sstrncpy (vl.type, "total_time_in_ms", sizeof (vl.type)); plugin_dispatch_values (&vl); - value.derive = float_counter_get (&res->req_time); - sstrncpy (vl.type, "total_time", sizeof (vl.type)); + value.derive = res->doc_size; + sstrncpy (vl.type, "total_bytes", sizeof (vl.type)); plugin_dispatch_values (&vl); - value.derive = float_counter_get (&res->ru_utime); + value.derive = float_counter_get (&res->ru_utime, /* factor = */ 100); sstrncpy (vl.type, "cpu", sizeof (vl.type)); sstrncpy (vl.type_instance, "user", sizeof (vl.type_instance)); plugin_dispatch_values (&vl); - value.derive = float_counter_get (&res->ru_stime); + value.derive = float_counter_get (&res->ru_stime, /* factor = */ 100); sstrncpy (vl.type, "cpu", sizeof (vl.type)); sstrncpy (vl.type_instance, "system", sizeof (vl.type_instance)); plugin_dispatch_values (&vl);