Merge pull request #396 from radford/perl-debug-compile-fix
[collectd.git] / src / memcached.c
index a4dbae2..e2ccfee 100644 (file)
@@ -79,11 +79,20 @@ static int memcached_connect_unix (memcached_t *st)
   if (fd < 0)
   {
     char errbuf[1024];
-    ERROR ("memcached: memcached_connect_unix: socket(2) failed: %s",
+    ERROR ("memcached plugin: memcached_connect_unix: socket(2) failed: %s",
         sstrerror (errno, errbuf, sizeof (errbuf)));
     return (-1);
   }
 
+  /* connect to the memcached daemon */
+  int status = connect (fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
+  if (status != 0)
+  {
+      shutdown (fd, SHUT_RDWR);
+      close (fd);
+      fd = -1;
+  }
+
   return (fd);
 } /* int memcached_connect_unix */
 
@@ -114,7 +123,8 @@ static int memcached_connect_inet (memcached_t *st)
   if (status != 0)
   {
     char errbuf[1024];
-    ERROR ("memcached: memcached_connect_inet: getaddrinfo(%s,%s) failed: %s",
+    ERROR ("memcached plugin: memcached_connect_inet: "
+        "getaddrinfo(%s,%s) failed: %s",
         host, port,
         (status == EAI_SYSTEM)
         ? sstrerror (errno, errbuf, sizeof (errbuf))
@@ -129,7 +139,8 @@ static int memcached_connect_inet (memcached_t *st)
     if (fd < 0)
     {
       char errbuf[1024];
-      WARNING ("memcached: memcached_connect_inet: socket(2) failed: %s",
+      WARNING ("memcached plugin: memcached_connect_inet: "
+          "socket(2) failed: %s",
           sstrerror (errno, errbuf, sizeof (errbuf)));
       continue;
     }
@@ -168,7 +179,8 @@ static int memcached_query_daemon (char *buffer, size_t buffer_size, memcached_t
 
   fd = memcached_connect (st);
   if (fd < 0) {
-    ERROR ("memcached: Could not connect to daemon.");
+    ERROR ("memcached plugin: Instance \"%s\" could not connect to daemon.",
+        st->name);
     return -1;
   }
 
@@ -231,20 +243,36 @@ static int memcached_query_daemon (char *buffer, size_t buffer_size, memcached_t
   return (status);
 } /* int memcached_query_daemon */
 
+static void memcached_init_vl (value_list_t *vl, memcached_t const *st)
+{
+  sstrncpy (vl->plugin, "memcached", sizeof (vl->plugin));
+  if (strcmp (st->name, "__legacy__") == 0) /* legacy mode */
+  {
+    sstrncpy (vl->host, hostname_g, sizeof (vl->host));
+  }
+  else
+  {
+    if (st->socket != NULL)
+      sstrncpy (vl->host, hostname_g, sizeof (vl->host));
+    else
+      sstrncpy (vl->host,
+          (st->host != NULL) ? st->host : MEMCACHED_DEF_HOST,
+          sizeof (vl->host));
+    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;
   vl.values_len = 1;
-  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
-  sstrncpy (vl.plugin, "memcached", sizeof (vl.plugin));
-  if (st->name != NULL)
-    sstrncpy (vl.plugin_instance, st->name,  sizeof (vl.plugin_instance));
   sstrncpy (vl.type, type, sizeof (vl.type));
   if (type_inst != NULL)
     sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
@@ -257,16 +285,13 @@ static void submit_derive2 (const char *type, const char *type_inst,
 {
   value_t values[2];
   value_list_t vl = VALUE_LIST_INIT;
+  memcached_init_vl (&vl, st);
 
   values[0].derive = value0;
   values[1].derive = value1;
 
   vl.values = values;
   vl.values_len = 2;
-  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
-  sstrncpy (vl.plugin, "memcached", sizeof (vl.plugin));
-  if (st->name != NULL)
-    sstrncpy (vl.plugin_instance, st->name,  sizeof (vl.plugin_instance));
   sstrncpy (vl.type, type, sizeof (vl.type));
   if (type_inst != NULL)
     sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
@@ -279,15 +304,12 @@ static void submit_gauge (const char *type, const char *type_inst,
 {
   value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
+  memcached_init_vl (&vl, st);
 
   values[0].gauge = value;
 
   vl.values = values;
   vl.values_len = 1;
-  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
-  sstrncpy (vl.plugin, "memcached", sizeof (vl.plugin));
-  if (st->name != NULL)
-    sstrncpy (vl.plugin_instance, st->name,  sizeof (vl.plugin_instance));
   sstrncpy (vl.type, type, sizeof (vl.type));
   if (type_inst != NULL)
     sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
@@ -300,16 +322,13 @@ static void submit_gauge2 (const char *type, const char *type_inst,
 {
   value_t values[2];
   value_list_t vl = VALUE_LIST_INIT;
+  memcached_init_vl (&vl, st);
 
   values[0].gauge = value0;
   values[1].gauge = value1;
 
   vl.values = values;
   vl.values_len = 2;
-  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
-  sstrncpy (vl.plugin, "memcached", sizeof (vl.plugin));
-  if (st->name != NULL)
-    sstrncpy (vl.plugin_instance, st->name,  sizeof (vl.plugin_instance));
   sstrncpy (vl.type, type, sizeof (vl.type));
   if (type_inst != NULL)
     sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
@@ -330,6 +349,10 @@ static int memcached_read (user_data_t *user_data)
   gauge_t bytes_total = NAN;
   gauge_t hits = NAN;
   gauge_t gets = NAN;
+  gauge_t incr_hits = NAN;
+  derive_t incr = 0;
+  gauge_t decr_hits = NAN;
+  derive_t decr = 0;
   derive_t rusage_user = 0;
   derive_t rusage_syst = 0;
   derive_t octets_rx = 0;
@@ -364,7 +387,7 @@ static int memcached_read (user_data_t *user_data)
 
     /*
      * For an explanation on these fields please refer to
-     * <http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt>
+     * <https://github.com/memcached/memcached/blob/master/doc/protocol.txt>
      */
 
     /*
@@ -414,6 +437,10 @@ static int memcached_read (user_data_t *user_data)
     {
       submit_gauge ("memcached_connections", "current", atof (fields[2]), st);
     }
+    else if (FIELD_IS ("listen_disabled_num"))
+    {
+      submit_derive ("memcached_connections", "listen_disabled", atof (fields[2]), st);
+    }
 
     /*
      * Commands
@@ -427,6 +454,36 @@ static int memcached_read (user_data_t *user_data)
     }
 
     /*
+     * Increment/Decrement
+     */
+    else if (FIELD_IS("incr_misses"))
+    {
+      derive_t incr_count = atoll (fields[2]);
+      submit_derive ("memcached_ops", "incr_misses", incr_count, st);
+      incr += incr_count;
+    }
+    else if (FIELD_IS ("incr_hits"))
+    {
+      derive_t incr_count = atoll (fields[2]);
+      submit_derive ("memcached_ops", "incr_hits", incr_count, st);
+      incr_hits = atof (fields[2]);
+      incr += incr_count;
+    }
+    else if (FIELD_IS ("decr_misses"))
+    {
+      derive_t decr_count = atoll (fields[2]);
+      submit_derive ("memcached_ops", "decr_misses", decr_count, st);
+      decr += decr_count;
+    }
+    else if (FIELD_IS ("decr_hits"))
+    {
+      derive_t decr_count = atoll (fields[2]);
+      submit_derive ("memcached_ops", "decr_hits", decr_count, st);
+      decr_hits = atof (fields[2]);
+      decr += decr_count;
+    }
+
+    /*
      * Operations on the cache, i. e. cache hits, cache misses and evictions of items
      */
     else if (FIELD_IS ("get_hits"))
@@ -475,6 +532,20 @@ static int memcached_read (user_data_t *user_data)
     submit_gauge ("percent", "hitratio", rate, st);
   }
 
+  if (!isnan (incr_hits) && incr != 0)
+  {
+    gauge_t incr_rate = 100.0 * incr_hits / incr;
+    submit_gauge ("percent", "incr_hitratio", incr_rate, st);
+    submit_derive ("memcached_ops", "incr", incr, st);
+  }
+
+  if (!isnan (decr_hits) && decr != 0)
+  {
+    gauge_t decr_rate = 100.0 * decr_hits / decr;
+    submit_gauge ("percent", "decr_hitratio", decr_rate, st);
+    submit_derive ("memcached_ops", "decr", decr, st);
+  }
+
   return 0;
 } /* int memcached_read */
 
@@ -530,7 +601,7 @@ static int config_add_instance(oconfig_item_t *ci)
   st->port = NULL;
 
   if (strcasecmp (ci->key, "Plugin") == 0) /* default instance */
-    st->name = sstrdup ("default");
+    st->name = sstrdup ("__legacy__");
   else /* <Instance /> block */
     status = cf_util_get_string (ci, &st->name);
   if (status != 0)
@@ -618,7 +689,7 @@ static int memcached_init (void)
   if (st == NULL)
     return (ENOMEM);
   memset (st, 0, sizeof (*st));
-  st->name = sstrdup ("default");
+  st->name = sstrdup ("__legacy__");
   st->socket = NULL;
   st->host = NULL;
   st->port = NULL;