Run clang-format after removing ssnprintf
[collectd.git] / src / memcached.c
index 02215e1..e4ccbce 100644 (file)
 
 struct memcached_s {
   char *name;
-  char *socket;
   char *host;
-  char *port;
+  char *socket;
+  char *connhost;
+  char *connport;
 };
 typedef struct memcached_s memcached_t;
 
@@ -57,9 +58,10 @@ static void memcached_free(void *arg) {
     return;
 
   sfree(st->name);
-  sfree(st->socket);
   sfree(st->host);
-  sfree(st->port);
+  sfree(st->socket);
+  sfree(st->connhost);
+  sfree(st->connport);
   sfree(st);
 }
 
@@ -76,7 +78,7 @@ static int memcached_connect_unix(memcached_t *st) {
     char errbuf[1024];
     ERROR("memcached plugin: memcached_connect_unix: socket(2) failed: %s",
           sstrerror(errno, errbuf, sizeof(errbuf)));
-    return (-1);
+    return -1;
   }
 
   /* connect to the memcached daemon */
@@ -87,33 +89,27 @@ static int memcached_connect_unix(memcached_t *st) {
     fd = -1;
   }
 
-  return (fd);
+  return fd;
 } /* 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);
+    return -1;
   }
 
   for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
@@ -142,14 +138,14 @@ static int memcached_connect_inet(memcached_t *st) {
   }
 
   freeaddrinfo(ai_list);
-  return (fd);
+  return fd;
 } /* int memcached_connect_inet */
 
 static int memcached_connect(memcached_t *st) {
   if (st->socket != NULL)
-    return (memcached_connect_unix(st));
+    return memcached_connect_unix(st);
   else
-    return (memcached_connect_inet(st));
+    return memcached_connect_inet(st);
 }
 
 static int memcached_query_daemon(char *buffer, size_t buffer_size,
@@ -171,7 +167,7 @@ static int memcached_query_daemon(char *buffer, size_t buffer_size,
           sstrerror(errno, errbuf, sizeof(errbuf)));
     shutdown(fd, SHUT_RDWR);
     close(fd);
-    return (-1);
+    return -1;
   }
 
   /* receive data from the memcached daemon */
@@ -192,7 +188,7 @@ static int memcached_query_daemon(char *buffer, size_t buffer_size,
             sstrerror(errno, errbuf, sizeof(errbuf)));
       shutdown(fd, SHUT_RDWR);
       close(fd);
-      return (-1);
+      return -1;
     }
 
     buffer_fill += (size_t)status;
@@ -216,37 +212,23 @@ static int memcached_query_daemon(char *buffer, size_t buffer_size,
 
   shutdown(fd, SHUT_RDWR);
   close(fd);
-  return (status);
+  return status;
 } /* 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)
@@ -257,15 +239,14 @@ static void submit_derive(const char *type, const char *type_inst,
 
 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));
@@ -275,13 +256,10 @@ static void submit_derive2(const char *type, const char *type_inst,
 
 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)
@@ -292,15 +270,14 @@ static void submit_gauge(const char *type, const char *type_inst, gauge_t value,
 
 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));
@@ -435,8 +412,10 @@ static int memcached_read(user_data_t *user_data) {
     }
 
     /*
-     * Operations on the cache, i. e. cache hits, cache misses and evictions of
-     * items
+     * Operations on the cache:
+     * - get hits/misses
+     * - delete hits/misses
+     * - evictions
      */
     else if (FIELD_IS("get_hits")) {
       submit_derive("memcached_ops", "hits", atoll(fields[2]), st);
@@ -445,6 +424,10 @@ static int memcached_read(user_data_t *user_data) {
       submit_derive("memcached_ops", "misses", atoll(fields[2]), st);
     } else if (FIELD_IS("evictions")) {
       submit_derive("memcached_ops", "evictions", atoll(fields[2]), st);
+    } else if (FIELD_IS("delete_hits")) {
+      submit_derive("memcached_ops", "delete_hits", atoll(fields[2]), st);
+    } else if (FIELD_IS("delete_misses")) {
+      submit_derive("memcached_ops", "delete_misses", atoll(fields[2]), st);
     }
 
     /*
@@ -494,23 +477,62 @@ static int memcached_add_read_callback(memcached_t *st) {
   char callback_name[3 * DATA_MAX_NAME_LEN];
   int status;
 
-  assert(st->name != NULL);
-  ssnprintf(callback_name, sizeof(callback_name), "memcached/%s", st->name);
+  snprintf(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);
+  return status;
 } /* int memcached_add_read_callback */
 
 /* Configuration handling functiions
  * <Plugin memcached>
  *   <Instance "instance_name">
  *     Host foo.zomg.com
+ *     Address 1.2.3.4
  *     Port "1234"
  *   </Instance>
  * </Plugin>
@@ -525,23 +547,22 @@ static int config_add_instance(oconfig_item_t *ci) {
   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);
+    return status;
   }
-  assert(st->name != NULL);
 
   for (int i = 0; i < ci->children_num; i++) {
     oconfig_item_t *child = ci->children + i;
@@ -550,8 +571,10 @@ static int config_add_instance(oconfig_item_t *ci) {
       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;
@@ -566,10 +589,10 @@ static int config_add_instance(oconfig_item_t *ci) {
 
   if (status != 0) {
     memcached_free(st);
-    return (-1);
+    return -1;
   }
 
-  return (0);
+  return 0;
 }
 
 static int memcached_config(oconfig_item_t *ci) {
@@ -585,7 +608,7 @@ static int memcached_config(oconfig_item_t *ci) {
     } else if (!have_instance_block) {
       /* Non-instance option: Assume legacy configuration (without <Instance />
        * blocks) and call config_add_instance() with the <Plugin /> block. */
-      return (config_add_instance(ci));
+      return config_add_instance(ci);
     } else
       WARNING("memcached plugin: The configuration option "
               "\"%s\" is not allowed here. Did you "
@@ -594,7 +617,7 @@ static int memcached_config(oconfig_item_t *ci) {
               child->key);
   } /* for (ci->children) */
 
-  return (status);
+  return status;
 }
 
 static int memcached_init(void) {
@@ -602,16 +625,17 @@ static int memcached_init(void) {
   int status;
 
   if (memcached_have_instances)
-    return (0);
+    return 0;
 
   /* No instances were configured, lets start a default instance. */
   st = calloc(1, sizeof(*st));
   if (st == NULL)
-    return (ENOMEM);
-  st->name = sstrdup("__legacy__");
-  st->socket = NULL;
+    return ENOMEM;
+  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)
@@ -619,7 +643,7 @@ static int memcached_init(void) {
   else
     memcached_free(st);
 
-  return (status);
+  return status;
 } /* int memcached_init */
 
 void module_register(void) {