X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fmemcached.c;h=ee3dbe12d67c4998b3ac65ede2f808016370023f;hb=aff80830f1154a5b6c4da16a0b1033aafde14e24;hp=2d999ce4e15be392dc9a3faed8dfca34395fee4c;hpb=10c85e89cbd077980ae297b17a23bbc42ce5d3d5;p=collectd.git diff --git a/src/memcached.c b/src/memcached.c index 2d999ce4..ee3dbe12 100644 --- a/src/memcached.c +++ b/src/memcached.c @@ -1,8 +1,9 @@ /** * collectd - src/memcached.c, based on src/hddtemp.c * Copyright (C) 2007 Antony Dovgal - * Copyright (C) 2007-2009 Florian Forster + * Copyright (C) 2007-2010 Florian Forster * Copyright (C) 2009 Doug MacEachern + * Copyright (C) 2009 Franck Lombardi * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -20,8 +21,9 @@ * * Authors: * Antony Dovgal - * Florian octo Forster + * Florian octo Forster * Doug MacEachern + * Franck Lombardi **/ #include "collectd.h" @@ -32,9 +34,15 @@ # include # include # include +# include # include # include +/* Hack to work around the missing define in AIX */ +#ifndef MSG_DONTWAIT +# define MSG_DONTWAIT MSG_NONBLOCK +#endif + #define MEMCACHED_DEF_HOST "127.0.0.1" #define MEMCACHED_DEF_PORT "11211" @@ -42,11 +50,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]; @@ -55,67 +65,98 @@ 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 sockaddr_un serv_addr; - struct addrinfo ai_hints; - struct addrinfo *ai_list, *ai_ptr; - int ai_return, i = 0; + memset (&serv_addr, 0, sizeof (serv_addr)); + serv_addr.sun_family = AF_UNIX; + sstrncpy (serv_addr.sun_path, memcached_socket, + sizeof (serv_addr.sun_path)); - 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; + /* create our socket descriptor */ + fd = socket (AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + char errbuf[1024]; + ERROR ("memcached: unix socket: %s", sstrerror (errno, errbuf, + sizeof (errbuf))); + return -1; + } - host = memcached_host; - if (host == NULL) { - host = MEMCACHED_DEF_HOST; + /* connect to the memcached daemon */ + status = (ssize_t) connect (fd, (struct sockaddr *) &serv_addr, + sizeof (serv_addr)); + if (status != 0) { + shutdown (fd, SHUT_RDWR); + close (fd); + fd = -1; + } } + else { /* if (memcached_socket == NULL) */ + const char *host; + const char *port; - port = memcached_port; - if (strlen (port) == 0) { - port = MEMCACHED_DEF_PORT; - } + struct addrinfo ai_hints; + struct addrinfo *ai_list, *ai_ptr; + int ai_return = 0; - if ((ai_return = getaddrinfo (host, port, &ai_hints, &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; - } + 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; - 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) { + 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, &ai_hints, &ai_list)) != 0) { char errbuf[1024]; - ERROR ("memcached: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf))); - continue; + ERROR ("memcached: getaddrinfo (%s, %s): %s", + host, port, + (ai_return == EAI_SYSTEM) + ? sstrerror (errno, errbuf, sizeof (errbuf)) + : gai_strerror (ai_return)); + return -1; } - /* 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; + fd = -1; + for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { + /* create our socket descriptor */ + fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (fd < 0) { + char errbuf[1024]; + ERROR ("memcached: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf))); + continue; + } + + /* connect to the memcached daemon */ + status = (ssize_t) connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) { + shutdown (fd, SHUT_RDWR); + close (fd); + fd = -1; + continue; + } + + /* A socket could be opened and connecting succeeded. We're + * done. */ + break; } - /* A socket could be opened and connecting succeeded. We're - * done. */ - break; + freeaddrinfo (ai_list); } - freeaddrinfo (ai_list); - if (fd < 0) { ERROR ("memcached: Could not connect to daemon."); return -1; @@ -135,12 +176,14 @@ static int memcached_query_daemon (char *buffer, int buffer_size) /* {{{ */ p.events = POLLIN | POLLERR | POLLHUP; p.revents = 0; - status = poll (&p, /* nfds = */ 1, /* timeout = */ 1000 * interval_g); + status = poll (&p, /* nfds = */ 1, + /* timeout = */ CDTIME_T_TO_MS (interval_g)); if (status <= 0) { if (status == 0) { - ERROR ("memcached: poll(2) timed out after %i seconds.", interval_g); + ERROR ("memcached: poll(2) timed out after %.3f seconds.", + CDTIME_T_TO_DOUBLE (interval_g)); } else { @@ -205,7 +248,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); } @@ -225,13 +273,13 @@ static int memcached_config (const char *key, const char *value) /* {{{ */ } /* }}} */ -static void submit_counter (const char *type, const char *type_inst, - counter_t value) /* {{{ */ +static void submit_derive (const char *type, const char *type_inst, + 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; @@ -245,18 +293,17 @@ static void submit_counter (const char *type, const char *type_inst, } /* void memcached_submit_cmd */ /* }}} */ -static void submit_counter2 (const char *type, const char *type_inst, - counter_t value0, counter_t value1) /* {{{ */ +static void submit_derive2 (const char *type, const char *type_inst, + derive_t value0, derive_t value1) /* {{{ */ { value_t values[2]; value_list_t vl = VALUE_LIST_INIT; - values[0].counter = value0; - values[1].counter = value1; + values[0].derive = value0; + values[1].derive = value1; vl.values = values; vl.values_len = 2; - 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)); @@ -277,7 +324,6 @@ static void submit_gauge (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)); @@ -299,7 +345,6 @@ static void submit_gauge2 (const char *type, const char *type_inst, vl.values = values; vl.values_len = 2; - 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)); @@ -323,10 +368,10 @@ static int memcached_read (void) /* {{{ */ 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; - counter_t octets_tx = 0; + derive_t rusage_user = 0; + derive_t rusage_syst = 0; + derive_t octets_rx = 0; + derive_t octets_tx = 0; /* get data from daemon */ if (memcached_query_daemon (buf, sizeof (buf)) < 0) { @@ -336,13 +381,13 @@ static int memcached_read (void) /* {{{ */ #define FIELD_IS(cnst) \ (((sizeof(cnst) - 1) == name_len) && (strcmp (cnst, fields[1]) == 0)) - ptr = buf; - saveptr = NULL; - while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL) + ptr = buf; + saveptr = NULL; + while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL) { int name_len; - ptr = NULL; + ptr = NULL; fields_num = strsplit(line, fields, 3); if (fields_num != 3) @@ -368,7 +413,7 @@ static int memcached_read (void) /* {{{ */ { rusage_syst = atoll(fields[2]); } - + /* * Number of threads of this instance */ @@ -384,12 +429,6 @@ static int memcached_read (void) /* {{{ */ { submit_gauge ("memcached_items", "current", atof (fields[2])); } -/* - else if (FIELD_IS ("total_items")) - { - total_items = atoll(fields[2]); - } - */ /* * Number of bytes used and available (total - used) @@ -410,20 +449,6 @@ static int memcached_read (void) /* {{{ */ { submit_gauge ("memcached_connections", "current", atof (fields[2])); } -/* - else if (FIELD_IS("total_connections")) - { - total_connections = atoll(fields[2]); - } -*/ - -/* - * ``Number of connection structures allocated by the server'' - else if (FIELD_IS ("connection_structures")) - { - connection_structures = atof(fields[2]); - } - */ /* * Commands @@ -431,7 +456,7 @@ static int memcached_read (void) /* {{{ */ else if ((name_len > 4) && (strncmp (fields[1], "cmd_", 4) == 0)) { const char *name = fields[1] + 4; - submit_counter ("memcached_command", name, atoll (fields[2])); + submit_derive ("memcached_command", name, atoll (fields[2])); if (strcmp (name, "get") == 0) gets = atof (fields[2]); } @@ -441,16 +466,16 @@ static int memcached_read (void) /* {{{ */ */ else if (FIELD_IS ("get_hits")) { - submit_counter ("memcached_ops", "hits", atoll (fields[2])); + submit_derive ("memcached_ops", "hits", atoll (fields[2])); hits = atof (fields[2]); } else if (FIELD_IS ("get_misses")) { - submit_counter ("memcached_ops", "misses", atoll (fields[2])); + submit_derive ("memcached_ops", "misses", atoll (fields[2])); } else if (FIELD_IS ("evictions")) { - submit_counter ("memcached_ops", "evictions", atoll (fields[2])); + submit_derive ("memcached_ops", "evictions", atoll (fields[2])); } /* @@ -468,13 +493,13 @@ 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); + submit_derive2 ("ps_cputime", NULL, rusage_user, rusage_syst); if ((octets_rx != 0) || (octets_tx != 0)) - submit_counter2 ("memcached_octets", NULL, octets_rx, octets_tx); - + submit_derive2 ("memcached_octets", NULL, octets_rx, octets_tx); + if (!isnan (gets) && !isnan (hits)) { gauge_t rate = NAN; @@ -501,7 +526,7 @@ void module_register (void) /* {{{ */ * tab-width: 4 * c-basic-offset: 4 * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 + * vim600: sw=4 ts=4 fdm=marker noexpandtab + * vim<600: sw=4 ts=4 noexpandtab */