Merge remote-tracking branch 'github/pr/2488'
authorFlorian Forster <octo@collectd.org>
Wed, 18 Oct 2017 18:27:04 +0000 (20:27 +0200)
committerFlorian Forster <octo@collectd.org>
Wed, 18 Oct 2017 18:27:04 +0000 (20:27 +0200)
AUTHORS
src/collectd.conf.in
src/collectd.conf.pod
src/filecount.c
src/snmp.c
src/utils_format_kairosdb.c
src/utils_format_kairosdb.h
src/write_http.c

diff --git a/AUTHORS b/AUTHORS
index b99c156..4df743c 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -116,6 +116,9 @@ Dan Ryder <daryder at cisco.com>
 David Bacher <drbacher at gmail.com>
  - serial plugin.
 
+Denis Pompilio <denis.pompilio at gmail.com>
+ - Improvements to the write_http plugin.
+
 Doug MacEachern <dougm at hyperic.com>
  - The `-T' option (config testing mode).
  - OpenVPN plugin.
index 425f1dd..261abdf 100644 (file)
 #              Size "+10k"
 #              Recursive true
 #              IncludeHidden false
+#              RegularOnly true
 #              #FilesSizeType "bytes"
 #              #FilesCountType "files"
 #              #TypeInstance "instance"
 #              Header "X-Custom-Header: custom_value"
 #              SSLVersion "TLSv1"
 #              Format "Command"
+#              Prefix "collectd"  # metric prefix, only available for KAIROSDB format
 #              Attribute "key" "value"     # only available for KAIROSDB format
 #              TTL 0   # data ttl, only available for KAIROSDB format
 #              Metrics true
index 9548fd6..4c4c261 100644 (file)
@@ -2834,6 +2834,11 @@ Controls whether or not to include "hidden" files and directories in the count.
 "Hidden" files and directories are those, whose name begins with a dot.
 Defaults to I<false>, i.e. by default hidden files and directories are ignored.
 
+=item B<RegularOnly> I<true>|I<false>
+
+Controls whether or not to include only regular files in the count.
+Defaults to I<true>, i.e. by default non regular files are ignored.
+
 =item B<FilesSizeType> I<Type>
 
 Sets the type used to dispatch files combined size. Empty value ("") disables
@@ -6804,12 +6809,15 @@ C<I<prefix>/var/run/collectd-powerdns>.
 
 =head2 Plugin C<processes>
 
-=over 4
+Collects information about processes of local system.
 
-=item B<Process> I<Name>
+By default, with no process matches configured, only general statistics is
+collected: the number of processes in each state and fork rate.
+
+Process matches can be configured by B<Process> and B<ProcessMatch> options.
+These may also be a block in which further options may be specified.
 
-Select more detailed statistics of processes matching this name. The statistics
-collected for these selected processes are:
+The statistics collected for matched processes are:
  - size of the resident segment size (RSS)
  - user- and system-time used
  - number of processes
@@ -6820,21 +6828,49 @@ collected for these selected processes are:
  - context switches (under Linux)
  - minor and major pagefaults.
 
-Some platforms have a limit on the length of process names. I<Name> must stay
-below this limit.
+B<Synopsis:>
+
+ <Plugin processes>
+   CollectFileDescriptor true
+   CollectContextSwitch true
+   Process "name"
+   ProcessMatch "name" "regex"
+   <Process "collectd">
+     CollectFileDescriptor false
+     CollectContextSwitch false
+   </Process>
+   <ProcessMatch "name" "regex">
+     CollectFileDescriptor false
+     CollectContextSwitch true
+   </Process>
+ </Plugin>
+
+=over 4
+
+=item B<Process> I<Name>
+
+Select more detailed statistics of processes matching this name.
+
+Some platforms have a limit on the length of process names.
+I<Name> must stay below this limit.
 
 =item B<ProcessMatch> I<name> I<regex>
 
-Similar to the B<Process> option this allows one to select more detailed
-statistics of processes matching the specified I<regex> (see L<regex(7)> for
-details). The statistics of all matching processes are summed up and
-dispatched to the daemon using the specified I<name> as an identifier. This
-allows one to "group" several processes together. I<name> must not contain
-slashes.
+Select more detailed statistics of processes matching the specified I<regex>
+(see L<regex(7)> for details). The statistics of all matching processes are
+summed up and dispatched to the daemon using the specified I<name> as an
+identifier. This allows one to "group" several processes together.
+I<name> must not contain slashes.
 
 =item B<CollectContextSwitch> I<Boolean>
 
-Collect context switch of the process.
+Collect the number of context switches for matched processes.
+Disabled by default.
+
+=item B<CollectFileDescriptor> I<Boolean>
+
+Collect number of file descriptors of matched processes.
+Disabled by default.
 
 =item B<CollectMemoryMaps> I<Boolean>
 
@@ -6844,6 +6880,10 @@ the Linux kernel.
 
 =back
 
+Options B<CollectContextSwitch> and B<CollectFileDescriptor> may be used inside
+B<Process> and B<ProcessMatch> blocks - then they affect corresponding match
+only. Otherwise they set the default value for subsequent matches.
+
 =head2 Plugin C<protocols>
 
 Collects a lot of information about various network protocols, such as I<IP>,
@@ -9270,6 +9310,12 @@ Sets the Cassandra ttl for the data points.
 
 Please refer to L<http://kairosdb.github.io/docs/build/html/restapi/AddDataPoints.html?highlight=ttl>
 
+=item B<Prefix> I<String>
+
+Only available for the KAIROSDB output format.
+
+Sets the metrics prefix I<string>. Defaults to I<collectd>.
+
 =item B<Metrics> B<true>|B<false>
 
 Controls whether I<metrics> are POSTed to this location. Defaults to B<true>.
index 5b812b8..7842aa6 100644 (file)
@@ -34,6 +34,7 @@
 
 #define FC_RECURSIVE 1
 #define FC_HIDDEN 2
+#define FC_REGULAR 4
 
 struct fc_directory_conf_s {
   char *path;
@@ -340,7 +341,7 @@ static int fc_config_add_dir(oconfig_item_t *ci) {
     return -1;
   }
 
-  dir->options = FC_RECURSIVE;
+  dir->options = FC_RECURSIVE | FC_REGULAR;
 
   dir->name = NULL;
   dir->plugin_name = strdup("filecount");
@@ -377,6 +378,8 @@ static int fc_config_add_dir(oconfig_item_t *ci) {
       status = fc_config_add_dir_option(dir, option, FC_RECURSIVE);
     else if (strcasecmp("IncludeHidden", option->key) == 0)
       status = fc_config_add_dir_option(dir, option, FC_HIDDEN);
+    else if (strcasecmp("RegularOnly", option->key) == 0)
+      status = fc_config_add_dir_option(dir, option, FC_REGULAR);
     else if (strcasecmp("FilesSizeType", option->key) == 0)
       status = cf_util_get_string(option, &dir->files_size_type);
     else if (strcasecmp("FilesCountType", option->key) == 0)
@@ -488,7 +491,7 @@ static int fc_read_dir_callback(const char *dirname, const char *filename,
         abs_path, fc_read_dir_callback, dir,
         /* include hidden = */ (dir->options & FC_HIDDEN) ? 1 : 0);
     return status;
-  } else if (!S_ISREG(statbuf.st_mode)) {
+  } else if ((dir->options & FC_REGULAR) && !S_ISREG(statbuf.st_mode)) {
     return 0;
   }
 
@@ -498,6 +501,11 @@ static int fc_read_dir_callback(const char *dirname, const char *filename,
       return 0;
   }
 
+  if (!S_ISREG(statbuf.st_mode)) {
+    dir->files_num++;
+    return 0;
+  }
+
   if (dir->mtime != 0) {
     time_t mtime = dir->now;
 
index 38141e4..0a20e34 100644 (file)
@@ -63,7 +63,7 @@ struct data_definition_s {
   struct data_definition_s *next;
   char **ignores;
   size_t ignores_len;
-  int invert_match;
+  _Bool invert_match;
 };
 typedef struct data_definition_s data_definition_t;
 
@@ -329,29 +329,14 @@ static int csnmp_config_add_data_blacklist(data_definition_t *dd,
   return 0;
 } /* int csnmp_config_add_data_blacklist */
 
-static int csnmp_config_add_data_blacklist_match_inverted(data_definition_t *dd,
-                                                          oconfig_item_t *ci) {
-  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) {
-    WARNING("snmp plugin: `InvertMatch' needs exactly one boolean argument.");
-    return -1;
-  }
-
-  dd->invert_match = ci->values[0].value.boolean ? 1 : 0;
-
-  return 0;
-} /* int csnmp_config_add_data_blacklist_match_inverted */
-
 static int csnmp_config_add_data(oconfig_item_t *ci) {
-  data_definition_t *dd;
-  int status = 0;
-
-  dd = calloc(1, sizeof(*dd));
+  data_definition_t *dd = calloc(1, sizeof(*dd));
   if (dd == NULL)
     return -1;
 
-  status = cf_util_get_string(ci, &dd->name);
+  int status = cf_util_get_string(ci, &dd->name);
   if (status != 0) {
-    free(dd);
+    sfree(dd);
     return -1;
   }
 
@@ -378,7 +363,7 @@ static int csnmp_config_add_data(oconfig_item_t *ci) {
     else if (strcasecmp("Ignore", option->key) == 0)
       status = csnmp_config_add_data_blacklist(dd, option);
     else if (strcasecmp("InvertMatch", option->key) == 0)
-      status = csnmp_config_add_data_blacklist_match_inverted(dd, option);
+      status = cf_util_get_boolean(option, &dd->invert_match);
     else {
       WARNING("snmp plugin: Option `%s' not allowed here.", option->key);
       status = -1;
@@ -1051,7 +1036,6 @@ static int csnmp_instance_list_add(csnmp_list_instances_t **head,
   struct variable_list *vb;
   oid_t vb_name;
   int status;
-  uint32_t is_matched;
 
   /* Set vb on the last variable */
   for (vb = res->variables; (vb != NULL) && (vb->next_variable != NULL);
@@ -1081,11 +1065,11 @@ static int csnmp_instance_list_add(csnmp_list_instances_t **head,
     char *ptr;
 
     csnmp_strvbcopy(il->instance, vb, sizeof(il->instance));
-    is_matched = 0;
+    _Bool is_matched = 0;
     for (uint32_t i = 0; i < dd->ignores_len; i++) {
       status = fnmatch(dd->ignores[i], il->instance, 0);
       if (status == 0) {
-        if (dd->invert_match == 0) {
+        if (!dd->invert_match) {
           sfree(il);
           return 0;
         } else {
@@ -1094,7 +1078,7 @@ static int csnmp_instance_list_add(csnmp_list_instances_t **head,
         }
       }
     }
-    if (dd->invert_match != 0 && is_matched == 0) {
+    if (dd->invert_match && !is_matched) {
       sfree(il);
       return 0;
     }
index 0128c57..460f807 100644 (file)
@@ -183,7 +183,8 @@ static int value_list_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */
                                   const data_set_t *ds, const value_list_t *vl,
                                   int store_rates,
                                   char const *const *http_attrs,
-                                  size_t http_attrs_num, int data_ttl) {
+                                  size_t http_attrs_num, int data_ttl,
+                                  char const *metrics_prefix) {
   char temp[512];
   size_t offset = 0;
   int status;
@@ -212,11 +213,13 @@ static int value_list_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */
   for (size_t i = 0; i < ds->ds_num; i++) {
     /* All value lists have a leading comma. The first one will be replaced with
      * a square bracket in `format_kairosdb_finalize'. */
-    BUFFER_ADD(",{");
+    BUFFER_ADD(",{\"name\":\"");
 
-    BUFFER_ADD("\"name\":\"collectd");
+    if (metrics_prefix != NULL) {
+      BUFFER_ADD("%s.", metrics_prefix);
+    }
 
-    BUFFER_ADD(".%s", vl->plugin);
+    BUFFER_ADD("%s", vl->plugin);
 
     status = values_to_kairosdb(temp, sizeof(temp), ds, vl, store_rates, i);
     if (status != 0)
@@ -263,12 +266,14 @@ static int format_kairosdb_value_list_nocheck(
     char *buffer, /* {{{ */
     size_t *ret_buffer_fill, size_t *ret_buffer_free, const data_set_t *ds,
     const value_list_t *vl, int store_rates, size_t temp_size,
-    char const *const *http_attrs, size_t http_attrs_num, int data_ttl) {
+    char const *const *http_attrs, size_t http_attrs_num, int data_ttl,
+    char const *metrics_prefix) {
   char temp[temp_size];
   int status;
 
   status = value_list_to_kairosdb(temp, sizeof(temp), ds, vl, store_rates,
-                                  http_attrs, http_attrs_num, data_ttl);
+                                  http_attrs, http_attrs_num, data_ttl,
+                                  metrics_prefix);
   if (status != 0)
     return status;
   temp_size = strlen(temp);
@@ -337,7 +342,8 @@ int format_kairosdb_value_list(char *buffer, /* {{{ */
                                size_t *ret_buffer_fill, size_t *ret_buffer_free,
                                const data_set_t *ds, const value_list_t *vl,
                                int store_rates, char const *const *http_attrs,
-                               size_t http_attrs_num, int data_ttl) {
+                               size_t http_attrs_num, int data_ttl,
+                               char const *metrics_prefix) {
   if ((buffer == NULL) || (ret_buffer_fill == NULL) ||
       (ret_buffer_free == NULL) || (ds == NULL) || (vl == NULL))
     return -EINVAL;
@@ -347,7 +353,8 @@ int format_kairosdb_value_list(char *buffer, /* {{{ */
 
   return format_kairosdb_value_list_nocheck(
       buffer, ret_buffer_fill, ret_buffer_free, ds, vl, store_rates,
-      (*ret_buffer_free) - 2, http_attrs, http_attrs_num, data_ttl);
+      (*ret_buffer_free) - 2, http_attrs, http_attrs_num, data_ttl,
+      metrics_prefix);
 } /* }}} int format_kairosdb_value_list */
 
 /* vim: set sw=2 sts=2 et fdm=marker : */
index 3a4c7c7..7b9e0e7 100644 (file)
@@ -41,7 +41,8 @@ int format_kairosdb_value_list(char *buffer, size_t *ret_buffer_fill,
                                size_t *ret_buffer_free, const data_set_t *ds,
                                const value_list_t *vl, int store_rates,
                                char const *const *http_attrs,
-                               size_t http_attrs_num, int data_ttl);
+                               size_t http_attrs_num, int data_ttl,
+                               char const *metrics_prefix);
 int format_kairosdb_finalize(char *buffer, size_t *ret_buffer_fill,
                              size_t *ret_buffer_free);
 
index 06327ed..87e518b 100644 (file)
 #define WRITE_HTTP_DEFAULT_BUFFER_SIZE 4096
 #endif
 
+#ifndef WRITE_HTTP_DEFAULT_PREFIX
+#define WRITE_HTTP_DEFAULT_PREFIX "collectd"
+#endif
+
 /*
  * Private variables
  */
@@ -80,6 +84,7 @@ struct wh_callback_s {
   pthread_mutex_t send_lock;
 
   int data_ttl;
+  char *metrics_prefix;
 };
 typedef struct wh_callback_s wh_callback_t;
 
@@ -328,6 +333,7 @@ static void wh_callback_free(void *data) /* {{{ */
   sfree(cb->clientcert);
   sfree(cb->clientkeypass);
   sfree(cb->send_buffer);
+  sfree(cb->metrics_prefix);
 
   sfree(cb);
 } /* }}} void wh_callback_free */
@@ -476,7 +482,7 @@ static int wh_write_kairosdb(const data_set_t *ds,
   status = format_kairosdb_value_list(
       cb->send_buffer, &cb->send_buffer_fill, &cb->send_buffer_free, ds, vl,
       cb->store_rates, (char const *const *)http_attrs, http_attrs_num,
-      cb->data_ttl);
+      cb->data_ttl, cb->metrics_prefix);
   if (status == -ENOMEM) {
     status = wh_flush_nolock(/* timeout = */ 0, cb);
     if (status != 0) {
@@ -488,7 +494,7 @@ static int wh_write_kairosdb(const data_set_t *ds,
     status = format_kairosdb_value_list(
         cb->send_buffer, &cb->send_buffer_fill, &cb->send_buffer_free, ds, vl,
         cb->store_rates, (char const *const *)http_attrs, http_attrs_num,
-        cb->data_ttl);
+        cb->data_ttl, cb->metrics_prefix);
   }
   if (status != 0) {
     pthread_mutex_unlock(&cb->send_lock);
@@ -629,6 +635,13 @@ static int wh_config_node(oconfig_item_t *ci) /* {{{ */
   cb->send_metrics = 1;
   cb->send_notifications = 0;
   cb->data_ttl = 0;
+  cb->metrics_prefix = strdup(WRITE_HTTP_DEFAULT_PREFIX);
+
+  if (cb->metrics_prefix == NULL) {
+    ERROR("write_http plugin: strdup failed.");
+    sfree(cb);
+    return -1;
+  }
 
   pthread_mutex_init(&cb->send_lock, /* attr = */ NULL);
 
@@ -740,6 +753,8 @@ static int wh_config_node(oconfig_item_t *ci) /* {{{ */
       sfree(val);
     } else if (strcasecmp("TTL", child->key) == 0) {
       status = cf_util_get_int(child, &cb->data_ttl);
+    } else if (strcasecmp("Prefix", child->key) == 0) {
+      status = cf_util_get_string(child, &cb->metrics_prefix);
     } else {
       ERROR("write_http plugin: Invalid configuration "
             "option: %s.",
@@ -770,6 +785,9 @@ static int wh_config_node(oconfig_item_t *ci) /* {{{ */
     return -1;
   }
 
+  if (strlen(cb->metrics_prefix) == 0)
+    sfree(cb->metrics_prefix);
+
   if (cb->low_speed_limit > 0)
     cb->low_speed_time = CDTIME_T_TO_TIME_T(plugin_get_interval());