struct memcached_s {
char *name;
- char *socket;
char *host;
- char *port;
+ char *socket;
+ char *connhost;
+ char *connport;
};
typedef struct memcached_s memcached_t;
return;
sfree(st->name);
- sfree(st->socket);
sfree(st->host);
- sfree(st->port);
+ sfree(st->socket);
+ sfree(st->connhost);
+ sfree(st->connport);
sfree(st);
}
} /* int memcached_connect_unix */
static int memcached_connect_inet(memcached_t *st) {
- const char *host;
- const char *port;
-
struct addrinfo *ai_list;
int status;
int fd = -1;
- host = (st->host != NULL) ? st->host : MEMCACHED_DEF_HOST;
- port = (st->port != NULL) ? st->port : MEMCACHED_DEF_PORT;
-
struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
.ai_flags = AI_ADDRCONFIG,
.ai_socktype = SOCK_STREAM};
- status = getaddrinfo(host, port, &ai_hints, &ai_list);
+ status = getaddrinfo(st->connhost, st->connport, &ai_hints, &ai_list);
if (status != 0) {
char errbuf[1024];
ERROR("memcached plugin: memcached_connect_inet: "
"getaddrinfo(%s,%s) failed: %s",
- host, port,
+ st->connhost, st->connport,
(status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(status));
return (-1);
} /* int memcached_query_daemon */
static void memcached_init_vl(value_list_t *vl, memcached_t const *st) {
- char const *host = st->host;
-
- /* Set vl->host to hostname_g, if:
- * - Legacy mode is used.
- * - "Socket" option is given (doc: "Host option is ignored").
- * - "Host" option is not provided.
- * - "Host" option is set to "localhost" or "127.0.0.1". */
- if ((strcmp(st->name, "__legacy__") == 0) || (st->socket != NULL) ||
- (st->host == NULL) || (strcmp("127.0.0.1", st->host) == 0) ||
- (strcmp("localhost", st->host) == 0))
- host = hostname_g;
-
sstrncpy(vl->plugin, "memcached", sizeof(vl->plugin));
- sstrncpy(vl->host, host, sizeof(vl->host));
- if (strcmp(st->name, "__legacy__") != 0)
+ if (st->host != NULL)
+ sstrncpy(vl->host, st->host, sizeof(vl->host));
+ if (st->name != NULL)
sstrncpy(vl->plugin_instance, st->name, sizeof(vl->plugin_instance));
}
static void submit_derive(const char *type, const char *type_inst,
derive_t value, memcached_t *st) {
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- memcached_init_vl(&vl, st);
-
- values[0].derive = value;
- vl.values = values;
+ memcached_init_vl(&vl, st);
+ vl.values = &(value_t){.derive = value};
vl.values_len = 1;
sstrncpy(vl.type, type, sizeof(vl.type));
if (type_inst != NULL)
static void submit_derive2(const char *type, const char *type_inst,
derive_t value0, derive_t value1, memcached_t *st) {
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
- memcached_init_vl(&vl, st);
-
- values[0].derive = value0;
- values[1].derive = value1;
+ value_t values[] = {
+ {.derive = value0}, {.derive = value1},
+ };
+ memcached_init_vl(&vl, st);
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE(values);
sstrncpy(vl.type, type, sizeof(vl.type));
if (type_inst != NULL)
sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance));
static void submit_gauge(const char *type, const char *type_inst, gauge_t value,
memcached_t *st) {
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- memcached_init_vl(&vl, st);
- values[0].gauge = value;
-
- vl.values = values;
+ memcached_init_vl(&vl, st);
+ vl.values = &(value_t){.gauge = value};
vl.values_len = 1;
sstrncpy(vl.type, type, sizeof(vl.type));
if (type_inst != NULL)
static void submit_gauge2(const char *type, const char *type_inst,
gauge_t value0, gauge_t value1, memcached_t *st) {
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
- memcached_init_vl(&vl, st);
-
- values[0].gauge = value0;
- values[1].gauge = value1;
+ value_t values[] = {
+ {.gauge = value0}, {.gauge = value1},
+ };
+ memcached_init_vl(&vl, st);
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE(values);
sstrncpy(vl.type, type, sizeof(vl.type));
if (type_inst != NULL)
sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance));
* CPU time consumed by the memcached process
*/
if (FIELD_IS("rusage_user")) {
- rusage_user = atoll(fields[2]);
+ /* Convert to useconds */
+ rusage_user = atof(fields[2]) * 1000000;
} else if (FIELD_IS("rusage_system")) {
- rusage_syst = atoll(fields[2]);
+ rusage_syst = atof(fields[2]) * 1000000;
}
/*
char callback_name[3 * DATA_MAX_NAME_LEN];
int status;
- assert(st->name != NULL);
- ssnprintf(callback_name, sizeof(callback_name), "memcached/%s", st->name);
+ ssnprintf(callback_name, sizeof(callback_name), "memcached/%s",
+ (st->name != NULL) ? st->name : "__legacy__");
+
+ /* If no <Address> used then:
+ * - Connect to the destination specified by <Host>, if present.
+ * If not, use the default address.
+ * - Use the default hostname (set st->host to NULL), if
+ * - Legacy mode is used (no configuration options at all), or
+ * - "Host" option is not provided, or
+ * - "Host" option is set to "localhost" or "127.0.0.1".
+ *
+ * If <Address> used then host may be set to "localhost" or "127.0.0.1"
+ * explicitly.
+ */
+ if (st->connhost == NULL) {
+ if (st->host) {
+ st->connhost = strdup(st->host);
+ if (st->connhost == NULL)
+ return (ENOMEM);
+
+ if ((strcmp("127.0.0.1", st->host) == 0) ||
+ (strcmp("localhost", st->host) == 0))
+ sfree(st->host);
+ } else {
+ st->connhost = strdup(MEMCACHED_DEF_HOST);
+ if (st->connhost == NULL)
+ return (ENOMEM);
+ }
+ }
+
+ if (st->connport == NULL) {
+ st->connport = strdup(MEMCACHED_DEF_PORT);
+ if (st->connport == NULL)
+ return (ENOMEM);
+ }
+
+ assert(st->connhost != NULL);
+ assert(st->connport != NULL);
- user_data_t ud = {.data = st, .free_func = memcached_free};
+ status = plugin_register_complex_read(
+ /* group = */ "memcached",
+ /* name = */ callback_name,
+ /* callback = */ memcached_read,
+ /* interval = */ 0, &(user_data_t){
+ .data = st, .free_func = memcached_free,
+ });
- status = plugin_register_complex_read(/* group = */ "memcached",
- /* name = */ callback_name,
- /* callback = */ memcached_read,
- /* interval = */ 0,
- /* user_data = */ &ud);
return (status);
} /* int memcached_add_read_callback */
* <Plugin memcached>
* <Instance "instance_name">
* Host foo.zomg.com
+ * Address 1.2.3.4
* Port "1234"
* </Instance>
* </Plugin>
st = calloc(1, sizeof(*st));
if (st == NULL) {
ERROR("memcached plugin: calloc failed.");
- return (-1);
+ return (ENOMEM);
}
st->name = NULL;
- st->socket = NULL;
st->host = NULL;
- st->port = NULL;
+ st->socket = NULL;
+ st->connhost = NULL;
+ st->connport = NULL;
- if (strcasecmp(ci->key, "Plugin") == 0) /* default instance */
- st->name = sstrdup("__legacy__");
- else /* <Instance /> block */
+ if (strcasecmp(ci->key, "Instance") == 0)
status = cf_util_get_string(ci, &st->name);
+
if (status != 0) {
sfree(st);
return (status);
}
- assert(st->name != NULL);
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
status = cf_util_get_string(child, &st->socket);
else if (strcasecmp("Host", child->key) == 0)
status = cf_util_get_string(child, &st->host);
+ else if (strcasecmp("Address", child->key) == 0)
+ status = cf_util_get_string(child, &st->connhost);
else if (strcasecmp("Port", child->key) == 0)
- status = cf_util_get_service(child, &st->port);
+ status = cf_util_get_service(child, &st->connport);
else {
WARNING("memcached plugin: Option `%s' not allowed here.", child->key);
status = -1;
st = calloc(1, sizeof(*st));
if (st == NULL)
return (ENOMEM);
- st->name = sstrdup("__legacy__");
- st->socket = NULL;
+ st->name = NULL;
st->host = NULL;
- st->port = NULL;
+ st->socket = NULL;
+ st->connhost = NULL;
+ st->connport = NULL;
status = memcached_add_read_callback(st);
if (status == 0)