X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fmemcached.c;h=06cd536beba67e4df34bdfd8260b232be6cbbc23;hb=0d65c92e5de2a6459dbeb002143fdeca9b3d6f41;hp=0e343316ecab23582be8084aae002bc8be2683bf;hpb=5c173359debb2664fad38f9b494d303bfc93496e;p=collectd.git diff --git a/src/memcached.c b/src/memcached.c index 0e343316..06cd536b 100644 --- a/src/memcached.c +++ b/src/memcached.c @@ -31,6 +31,7 @@ # include # include # include +# include # include # include @@ -41,11 +42,13 @@ static const char *config_keys[] = { + "Socket", "Host", "Port" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static char *memcached_socket = NULL; static char *memcached_host = NULL; static char memcached_port[16]; @@ -54,66 +57,92 @@ static int memcached_query_daemon (char *buffer, int buffer_size) /* {{{ */ int fd; ssize_t status; int buffer_fill; + int i = 0; - const char *host; - const char *port; + if (memcached_socket != NULL) { - struct addrinfo ai_hints; - struct addrinfo *ai_list, *ai_ptr; - int ai_return, i = 0; + struct sockaddr_un serv_addr; - memset (&ai_hints, '\0', sizeof (ai_hints)); - ai_hints.ai_flags = 0; -#ifdef AI_ADDRCONFIG -/* ai_hints.ai_flags |= AI_ADDRCONFIG; */ -#endif - ai_hints.ai_family = AF_INET; - ai_hints.ai_socktype = SOCK_STREAM; - ai_hints.ai_protocol = 0; + memset(&serv_addr, '\0', sizeof (serv_addr)); + serv_addr.sun_family = AF_UNIX; + strncpy(serv_addr.sun_path, memcached_socket, sizeof (serv_addr.sun_path)); - host = memcached_host; - if (host == NULL) { - host = MEMCACHED_DEF_HOST; - } + /* create our socket descriptor */ + if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) { + char errbuf[1024]; + ERROR ("memcached: unix socket: %s", sstrerror (errno, errbuf, sizeof (errbuf))); + return -1; + } - port = memcached_port; - if (strlen (port) == 0) { - port = MEMCACHED_DEF_PORT; - } + /* connect to the memcached daemon */ + if (connect (fd, (struct sockaddr *) &serv_addr, SUN_LEN(&serv_addr))) { + shutdown(fd, SHUT_RDWR); + close(fd); + fd = -1; + } - if ((ai_return = getaddrinfo (host, port, NULL, &ai_list)) != 0) { - char errbuf[1024]; - ERROR ("memcached: getaddrinfo (%s, %s): %s", - host, port, - (ai_return == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (ai_return)); - return -1; - } + } else { - fd = -1; - for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { - /* create our socket descriptor */ - if ((fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol)) < 0) { - char errbuf[1024]; - ERROR ("memcached: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf))); - continue; - } - - /* connect to the memcached daemon */ - if (connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen)) { - shutdown(fd, SHUT_RDWR); - close(fd); - fd = -1; - continue; - } + const char *host; + const char *port; - /* A socket could be opened and connecting succeeded. We're - * done. */ - break; - } + struct addrinfo ai_hints; + struct addrinfo *ai_list, *ai_ptr; + int ai_return = 0; - freeaddrinfo (ai_list); + memset (&ai_hints, '\0', sizeof (ai_hints)); + ai_hints.ai_flags = 0; +#ifdef AI_ADDRCONFIG + /* ai_hints.ai_flags |= AI_ADDRCONFIG; */ +#endif + ai_hints.ai_family = AF_INET; + ai_hints.ai_socktype = SOCK_STREAM; + ai_hints.ai_protocol = 0; + + host = memcached_host; + if (host == NULL) { + host = MEMCACHED_DEF_HOST; + } + + port = memcached_port; + if (strlen (port) == 0) { + port = MEMCACHED_DEF_PORT; + } + + if ((ai_return = getaddrinfo (host, port, NULL, &ai_list)) != 0) { + char errbuf[1024]; + ERROR ("memcached: getaddrinfo (%s, %s): %s", + host, port, + (ai_return == EAI_SYSTEM) + ? sstrerror (errno, errbuf, sizeof (errbuf)) + : gai_strerror (ai_return)); + return -1; + } + + fd = -1; + for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { + /* create our socket descriptor */ + if ((fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol)) < 0) { + char errbuf[1024]; + ERROR ("memcached: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf))); + continue; + } + + /* connect to the memcached daemon */ + if (connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen)) { + shutdown(fd, SHUT_RDWR); + close(fd); + fd = -1; + continue; + } + + /* A socket could be opened and connecting succeeded. We're + * done. */ + break; + } + + freeaddrinfo (ai_list); + } if (fd < 0) { ERROR ("memcached: Could not connect to daemon."); @@ -134,7 +163,7 @@ static int memcached_query_daemon (char *buffer, int buffer_size) /* {{{ */ p.events = POLLIN | POLLERR | POLLHUP; p.revents = 0; - status = poll (&p, /* nfds = */ 1, /* timeout = */ interval_g); + status = poll (&p, /* nfds = */ 1, /* timeout = */ 1000 * interval_g); if (status <= 0) { if (status == 0) @@ -204,7 +233,12 @@ static int memcached_query_daemon (char *buffer, int buffer_size) /* {{{ */ static int memcached_config (const char *key, const char *value) /* {{{ */ { - if (strcasecmp (key, "Host") == 0) { + if (strcasecmp (key, "Socket") == 0) { + if (memcached_socket != NULL) { + free (memcached_socket); + } + memcached_socket = strdup (value); + } else if (strcasecmp (key, "Host") == 0) { if (memcached_host != NULL) { free (memcached_host); } @@ -234,7 +268,6 @@ static void submit_counter (const char *type, const char *type_inst, vl.values = values; vl.values_len = 1; - vl.time = time (NULL); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "memcached", sizeof (vl.plugin)); sstrncpy (vl.type, type, sizeof (vl.type)); @@ -321,6 +354,8 @@ static int memcached_read (void) /* {{{ */ gauge_t bytes_used = NAN; gauge_t bytes_total = NAN; + gauge_t hits = NAN; + gauge_t gets = NAN; counter_t rusage_user = 0; counter_t rusage_syst = 0; counter_t octets_rx = 0; @@ -366,7 +401,7 @@ static int memcached_read (void) /* {{{ */ { rusage_syst = atoll(fields[2]); } - + /* * Number of threads of this instance */ @@ -382,7 +417,7 @@ static int memcached_read (void) /* {{{ */ { submit_gauge ("memcached_items", "current", atof (fields[2])); } -/* +/* else if (FIELD_IS ("total_items")) { total_items = atoll(fields[2]); @@ -430,6 +465,8 @@ static int memcached_read (void) /* {{{ */ { const char *name = fields[1] + 4; submit_counter ("memcached_command", name, atoll (fields[2])); + if (strcmp (name, "get") == 0) + gets = atof (fields[2]); } /* @@ -438,6 +475,7 @@ static int memcached_read (void) /* {{{ */ else if (FIELD_IS ("get_hits")) { submit_counter ("memcached_ops", "hits", atoll (fields[2])); + hits = atof (fields[2]); } else if (FIELD_IS ("get_misses")) { @@ -463,13 +501,23 @@ static int memcached_read (void) /* {{{ */ if (!isnan (bytes_used) && !isnan (bytes_total) && (bytes_used <= bytes_total)) submit_gauge2 ("df", "cache", bytes_used, bytes_total - bytes_used); - + if ((rusage_user != 0) || (rusage_syst != 0)) submit_counter2 ("ps_cputime", NULL, rusage_user, rusage_syst); if ((octets_rx != 0) || (octets_tx != 0)) submit_counter2 ("memcached_octets", NULL, octets_rx, octets_tx); - + + if (!isnan (gets) && !isnan (hits)) + { + gauge_t rate = NAN; + + if (gets != 0.0) + rate = 100.0 * hits / gets; + + submit_gauge ("percent", "hitratio", rate); + } + return 0; } /* }}} */