/**
- * collectd - src/memcached.c
- * Copyright (C) 2007 Antony Dovgal, heavily based on hddtemp.c
+ * collectd - src/memcached.c, based on src/hddtemp.c
+ * Copyright (C) 2007 Antony Dovgal
+ * Copyright (C) 2005,2006 Vincent Stehlé
*
* 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
*
* Authors:
* Antony Dovgal <tony at daylessday dot org>
- *
+ * Vincent Stehlé <vincent.stehle at free.fr>
+ * Florian octo Forster <octo at verplant.org>
**/
#include "collectd.h"
# include <sys/socket.h>
# include <netinet/in.h>
# include <netinet/tcp.h>
-# include <libgen.h> /* for basename */
-
-#if HAVE_LINUX_MAJOR_H
-# include <linux/major.h>
-#endif
#define MEMCACHED_DEF_HOST "127.0.0.1"
#define MEMCACHED_DEF_PORT "11211"
static const char *config_keys[] =
{
"Host",
- "Port",
- NULL
+ "Port"
};
-static int config_keys_num = 2;
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
static char *memcached_host = NULL;
static char memcached_port[16];
{
struct pollfd p;
- int n;
+ int status;
+ memset (&p, 0, sizeof (p));
p.fd = fd;
- p.events = POLLIN|POLLERR|POLLHUP;
+ p.events = POLLIN | POLLERR | POLLHUP;
p.revents = 0;
- n = poll(&p, 1, 3);
-
- if (n <= 0) {
- ERROR ("memcached: poll() failed or timed out");
- return -1;
+ status = poll (&p, /* nfds = */ 1, /* timeout = */ 1000 * interval_g);
+ if (status <= 0)
+ {
+ if (status == 0)
+ {
+ ERROR ("memcached: poll(2) timed out after %i seconds.", interval_g);
+ }
+ else
+ {
+ char errbuf[1024];
+ ERROR ("memcached: poll(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
+ shutdown (fd, SHUT_RDWR);
+ close (fd);
+ return (-1);
}
}
} else if (strcasecmp (key, "Port") == 0) {
int port = (int) (atof (value));
if ((port > 0) && (port <= 65535)) {
- snprintf (memcached_port, sizeof (memcached_port), "%i", port);
+ ssnprintf (memcached_port, sizeof (memcached_port), "%i", port);
} else {
- strncpy (memcached_port, value, sizeof (memcached_port));
+ sstrncpy (memcached_port, value, sizeof (memcached_port));
}
- memcached_port[sizeof (memcached_port) - 1] = '\0';
} else {
return -1;
}
vl.values = values;
vl.values_len = 1;
- vl.time = time (NULL);
- strcpy (vl.host, hostname_g);
- strcpy (vl.plugin, "memcached");
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "memcached", sizeof (vl.plugin));
+ sstrncpy (vl.type, type, sizeof (vl.type));
if (type_inst != NULL)
- {
- strncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
- vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
- }
+ sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
- plugin_dispatch_values (type, &vl);
+ plugin_dispatch_values (&vl);
} /* void memcached_submit_cmd */
/* }}} */
vl.values = values;
vl.values_len = 2;
vl.time = time (NULL);
- strcpy (vl.host, hostname_g);
- strcpy (vl.plugin, "memcached");
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "memcached", sizeof (vl.plugin));
+ sstrncpy (vl.type, type, sizeof (vl.type));
if (type_inst != NULL)
- {
- strncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
- vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
- }
+ sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
- plugin_dispatch_values (type, &vl);
+ plugin_dispatch_values (&vl);
} /* void memcached_submit_cmd */
/* }}} */
vl.values = values;
vl.values_len = 1;
vl.time = time (NULL);
- strcpy (vl.host, hostname_g);
- strcpy (vl.plugin, "memcached");
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "memcached", sizeof (vl.plugin));
+ sstrncpy (vl.type, type, sizeof (vl.type));
if (type_inst != NULL)
- {
- strncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
- vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
- }
+ sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
- plugin_dispatch_values (type, &vl);
+ plugin_dispatch_values (&vl);
}
/* }}} */
vl.values = values;
vl.values_len = 2;
vl.time = time (NULL);
- strcpy (vl.host, hostname_g);
- strcpy (vl.plugin, "memcached");
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "memcached", sizeof (vl.plugin));
+ sstrncpy (vl.type, type, sizeof (vl.type));
if (type_inst != NULL)
- {
- strncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
- vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
- }
+ sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
- plugin_dispatch_values (type, &vl);
+ plugin_dispatch_values (&vl);
}
/* }}} */
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;
{
const char *name = fields[1] + 4;
submit_counter ("memcached_command", name, atoll (fields[2]));
+ if (strcmp (name, "get") == 0)
+ gets = atof (fields[2]);
}
/*
else if (FIELD_IS ("get_hits"))
{
submit_counter ("memcached_ops", "hits", atoll (fields[2]));
+ hits = atof (fields[2]);
}
else if (FIELD_IS ("get_misses"))
{
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;
}
/* }}} */