Merge remote-tracking branch 'upstream/master'
authorZebity Spring <zebity@yahoo.com>
Thu, 16 May 2019 12:24:51 +0000 (22:24 +1000)
committerZebity Spring <zebity@yahoo.com>
Thu, 16 May 2019 12:24:51 +0000 (22:24 +1000)
src/collectd.conf.in
src/collectd.conf.pod
src/curl.c
src/curl_json.c
src/curl_xml.c
src/virt.c

index f8e5288..7f09c5c 100644 (file)
 #<Plugin curl>
 #  <Page "stock_quotes">
 #    URL "http://finance.google.com/finance?q=NYSE%3AAMD"
+#    AddressFamily "any"
 #    User "foo"
 #    Password "bar"
 #    Digest false
 
 #<Plugin curl_json>
 #  <URL "http://localhost:80/test.json">
+#    AddressFamily "any"
 #    Instance "test_http_json"
 #    <Key "testArray/0">
 #      Type "gauge"
 # }
 ## See: http://wiki.apache.org/couchdb/Runtime_Statistics
 #  <URL "http://localhost:5984/_stats">
+#    AddressFamily "ipv4"
 #    Instance "httpd"
 #    <Key "httpd/requests/count">
 #      Type "http_requests"
 #  </URL>
 ## Database status metrics:
 #  <URL "http://localhost:5984/_all_dbs">
+#    AddressFamily "ipv6"
 #    Instance "dbs"
 #    <Key "*/doc_count">
 #      Type "gauge"
 
 #<Plugin curl_xml>
 #  <URL "http://localhost/stats.xml">
+#    AddressFamily "any"
 #    Host "my_host"
 #    #Plugin "stats"
 #    Instance "some_instance"
index fb0751a..71931c2 100644 (file)
@@ -1804,6 +1804,7 @@ finance page and dispatch the value to collectd.
     <Page "stock_quotes">
       Plugin "quotes"
       URL "http://finance.google.com/finance?q=NYSE%3AAMD"
+      AddressFamily "any"
       User "foo"
       Password "bar"
       Digest false
@@ -1844,6 +1845,18 @@ Defaults to C<curl>.
 URL of the web site to retrieve. Since a regular expression will be used to
 extract information from this data, non-binary data is a big plus here ;)
 
+=item B<AddressFamily> I<Type>
+
+IP version to resolve URL to. Useful in cases when hostname in URL resolves
+to both IPv4 and IPv6 addresses, and you are interested in using one of them
+specifically.
+Use C<ipv4> to enforce IPv4, C<ipv6> to enforce IPv6, or C<any> to keep the
+default behavior of resolving addresses to all IP versions your system allows.
+If C<libcurl> is compiled without IPv6 support, using C<ipv6> will result in
+a warning and fallback to C<any>.
+If C<Type> cannot be parsed, a warning will be printed and the whole B<Page>
+block will be ignored.
+
 =item B<User> I<Name>
 
 Username to use if authorization is required to read the page.
@@ -1955,6 +1968,7 @@ C<_stats> runtime statistics module of I<CouchDB>
 
   <Plugin curl_json>
     <URL "http://localhost:5984/_stats">
+      AddressFamily "any"
       Instance "httpd"
       <Key "httpd/requests/count">
         Type "http_requests"
@@ -1999,6 +2013,18 @@ The following options are valid within B<URL> blocks:
 
 =over 4
 
+=item B<AddressFamily> I<Type>
+
+IP version to resolve URL to. Useful in cases when hostname in URL resolves
+to both IPv4 and IPv6 addresses, and you are interested in using one of them
+specifically.
+Use C<ipv4> to enforce IPv4, C<ipv6> to enforce IPv6, or C<any> to keep the
+default behavior of resolving addresses to all IP versions your system allows.
+If C<libcurl> is compiled without IPv6 support, using C<ipv6> will result in
+a warning and fallback to C<any>.
+If C<Type> cannot be parsed, a warning will be printed and the whole B<URL>
+block will be ignored.
+
 =item B<Host> I<Name>
 
 Use I<Name> as the host name when submitting values. Defaults to the global
@@ -2070,6 +2096,7 @@ The B<curl_xml plugin> uses B<libcurl> (L<http://curl.haxx.se/>) and B<libxml2>
 
  <Plugin "curl_xml">
    <URL "http://localhost/stats.xml">
+     AddressFamily "any"
      Host "my_host"
      #Plugin "curl_xml"
      Instance "some_instance"
@@ -2106,6 +2133,18 @@ Within the B<URL> block the following options are accepted:
 
 =over 4
 
+=item B<AddressFamily> I<Type>
+
+IP version to resolve URL to. Useful in cases when hostname in URL resolves
+to both IPv4 and IPv6 addresses, and you are interested in using one of them
+specifically.
+Use C<ipv4> to enforce IPv4, C<ipv6> to enforce IPv6, or C<any> to keep the
+default behavior of resolving addresses to all IP versions your system allows.
+If C<libcurl> is compiled without IPv6 support, using C<ipv6> will result in
+a warning and fallback to C<any>.
+If C<Type> cannot be parsed, a warning will be printed and the whole B<URL>
+block will be ignored.
+
 =item B<Host> I<Name>
 
 Use I<Name> as the host name when submitting values. Defaults to the global
@@ -9466,9 +9505,7 @@ I<0.9.5> or later.
 =item B<disk_err>: report disk errors if any occured. Requires libvirt API version
 I<0.9.10> or later.
 
-=item B<domain_state>: report domain state and reason in human-readable format as
-a notification. If libvirt API version I<0.9.2> or later is available, domain
-reason will be included in notification.
+=item B<domain_state>: report domain state and reason as 'domain_state' metric.
 
 =item B<fs_info>: report file system information as a notification. Requires
 libvirt API version I<1.2.11> or later. Can be collected only if I<Guest Agent>
index 9ad3dc8..e3e3c17 100644 (file)
@@ -57,6 +57,7 @@ struct web_page_s /* {{{ */
   char *instance;
 
   char *url;
+  int address_family;
   char *user;
   char *pass;
   char *credentials;
@@ -345,6 +346,7 @@ static int cc_page_init_curl(web_page_t *wp) /* {{{ */
   curl_easy_setopt(wp->curl, CURLOPT_ERRORBUFFER, wp->curl_errbuf);
   curl_easy_setopt(wp->curl, CURLOPT_FOLLOWLOCATION, 1L);
   curl_easy_setopt(wp->curl, CURLOPT_MAXREDIRS, 50L);
+  curl_easy_setopt(wp->curl, CURLOPT_IPRESOLVE, wp->address_family);
 
   if (wp->user != NULL) {
 #ifdef HAVE_CURLOPT_USERNAME
@@ -411,6 +413,7 @@ static int cc_config_add_page(oconfig_item_t *ci) /* {{{ */
   }
   page->plugin_name = NULL;
   page->url = NULL;
+  page->address_family = CURL_IPRESOLVE_WHATEVER;
   page->user = NULL;
   page->pass = NULL;
   page->digest = false;
@@ -437,7 +440,34 @@ static int cc_config_add_page(oconfig_item_t *ci) /* {{{ */
       status = cf_util_get_string(child, &page->plugin_name);
     else if (strcasecmp("URL", child->key) == 0)
       status = cf_util_get_string(child, &page->url);
-    else if (strcasecmp("User", child->key) == 0)
+    else if (strcasecmp("AddressFamily", child->key) == 0) {
+      char *af = NULL;
+      status = cf_util_get_string(child, &af);
+      if (status != 0 || af == NULL) {
+        WARNING("curl plugin: Cannot parse value of `%s' "
+                "for instance `%s'.",
+                child->key, page->instance);
+      } else if (strcasecmp("any", af) == 0) {
+        page->address_family = CURL_IPRESOLVE_WHATEVER;
+      } else if (strcasecmp("ipv4", af) == 0) {
+        page->address_family = CURL_IPRESOLVE_V4;
+      } else if (strcasecmp("ipv6", af) == 0) {
+        /* If curl supports ipv6, use it. If not, log a warning and
+         * fall back to default - don't set status to non-zero.
+         */
+        curl_version_info_data *curl_info = curl_version_info(CURLVERSION_NOW);
+        if (curl_info->features & CURL_VERSION_IPV6)
+          page->address_family = CURL_IPRESOLVE_V6;
+        else
+          WARNING("curl plugin: IPv6 not supported by this libCURL. "
+                  "Using fallback `any'.");
+      } else {
+        WARNING("curl plugin: Unsupported value of `%s' "
+                "for instance `%s'.",
+                child->key, page->instance);
+        status = -1;
+      }
+    } else if (strcasecmp("User", child->key) == 0)
       status = cf_util_get_string(child, &page->user);
     else if (strcasecmp("Password", child->key) == 0)
       status = cf_util_get_string(child, &page->pass);
index a26664f..9d01e6e 100644 (file)
@@ -88,6 +88,7 @@ struct cj_s /* {{{ */
   char *sock;
 
   char *url;
+  int address_family;
   char *user;
   char *pass;
   char *credentials;
@@ -582,6 +583,7 @@ static int cj_init_curl(cj_t *db) /* {{{ */
   curl_easy_setopt(db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf);
   curl_easy_setopt(db->curl, CURLOPT_FOLLOWLOCATION, 1L);
   curl_easy_setopt(db->curl, CURLOPT_MAXREDIRS, 50L);
+  curl_easy_setopt(db->curl, CURLOPT_IPRESOLVE, db->address_family);
 
   if (db->user != NULL) {
 #ifdef HAVE_CURLOPT_USERNAME
@@ -649,6 +651,7 @@ static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */
   }
 
   db->timeout = -1;
+  db->address_family = CURL_IPRESOLVE_WHATEVER;
 
   if (strcasecmp("URL", ci->key) == 0)
     status = cf_util_get_string(ci, &db->url);
@@ -702,6 +705,31 @@ static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */
       db->stats = curl_stats_from_config(child);
       if (db->stats == NULL)
         status = -1;
+    } else if (db->url && strcasecmp("AddressFamily", child->key) == 0) {
+      char *af = NULL;
+      status = cf_util_get_string(child, &af);
+      if (status != 0 || af == NULL) {
+        WARNING("curl_json plugin: Cannot parse value of `%s' for URL `%s'.",
+                child->key, db->url);
+      } else if (strcasecmp("any", af) == 0) {
+        db->address_family = CURL_IPRESOLVE_WHATEVER;
+      } else if (strcasecmp("ipv4", af) == 0) {
+        db->address_family = CURL_IPRESOLVE_V4;
+      } else if (strcasecmp("ipv6", af) == 0) {
+        /* If curl supports ipv6, use it. If not, log a warning and
+         * fall back to default - don't set status to non-zero.
+         */
+        curl_version_info_data *curl_info = curl_version_info(CURLVERSION_NOW);
+        if (curl_info->features & CURL_VERSION_IPV6)
+          db->address_family = CURL_IPRESOLVE_V6;
+        else
+          WARNING("curl_json plugin: IPv6 not supported by this libCURL. "
+                  "Using fallback `any'.");
+      } else {
+        WARNING("curl_json plugin: Unsupported value of `%s' for URL `%s'.",
+                child->key, db->url);
+        status = -1;
+      }
     } else {
       WARNING("curl_json plugin: Option `%s' not allowed here.", child->key);
       status = -1;
index ed70f69..ce6bd46 100644 (file)
@@ -76,6 +76,7 @@ struct cx_s /* {{{ */
   char *host;
 
   char *url;
+  int address_family;
   char *user;
   char *pass;
   char *credentials;
@@ -736,6 +737,7 @@ static int cx_init_curl(cx_t *db) /* {{{ */
   curl_easy_setopt(db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf);
   curl_easy_setopt(db->curl, CURLOPT_FOLLOWLOCATION, 1L);
   curl_easy_setopt(db->curl, CURLOPT_MAXREDIRS, 50L);
+  curl_easy_setopt(db->curl, CURLOPT_IPRESOLVE, db->address_family);
 
   if (db->user != NULL) {
 #ifdef HAVE_CURLOPT_USERNAME
@@ -814,6 +816,7 @@ static int cx_config_add_url(oconfig_item_t *ci) /* {{{ */
   }
 
   db->timeout = -1;
+  db->address_family = CURL_IPRESOLVE_WHATEVER;
 
   int status = cf_util_get_string(ci, &db->url);
   if (status != 0) {
@@ -863,6 +866,31 @@ static int cx_config_add_url(oconfig_item_t *ci) /* {{{ */
       db->stats = curl_stats_from_config(child);
       if (db->stats == NULL)
         status = -1;
+    } else if (strcasecmp("AddressFamily", child->key) == 0) {
+      char *af = NULL;
+      status = cf_util_get_string(child, &af);
+      if (status != 0 || af == NULL) {
+        WARNING("curl_xml plugin: Cannot parse value of `%s' for URL `%s'.",
+                child->key, db->url);
+      } else if (strcasecmp("any", af) == 0) {
+        db->address_family = CURL_IPRESOLVE_WHATEVER;
+      } else if (strcasecmp("ipv4", af) == 0) {
+        db->address_family = CURL_IPRESOLVE_V4;
+      } else if (strcasecmp("ipv6", af) == 0) {
+        /* If curl supports ipv6, use it. If not, log a warning and
+         * fall back to default - don't set status to non-zero.
+         */
+        curl_version_info_data *curl_info = curl_version_info(CURLVERSION_NOW);
+        if (curl_info->features & CURL_VERSION_IPV6)
+          db->address_family = CURL_IPRESOLVE_V6;
+        else
+          WARNING("curl_xml plugin: IPv6 not supported by this libCURL. "
+                  "Using fallback `any'.");
+      } else {
+        WARNING("curl_xml plugin: Unsupported value of `%s' for URL `%s'.",
+                child->key, db->url);
+        status = -1;
+      }
     } else {
       WARNING("curl_xml plugin: Option `%s' not allowed here.", child->key);
       status = -1;
index d3d8c6a..11481a4 100644 (file)
@@ -1665,16 +1665,7 @@ static int get_pcpu_stats(virDomainPtr dom) {
 #endif /* HAVE_CPU_STATS */
 
 #ifdef HAVE_DOM_REASON
-
-static void domain_state_submit(virDomainPtr dom, int state, int reason) {
-  value_t values[] = {
-      {.gauge = (gauge_t)state}, {.gauge = (gauge_t)reason},
-  };
-
-  submit(dom, "domain_state", NULL, values, STATIC_ARRAY_SIZE(values));
-}
-
-static int get_domain_state(virDomainPtr domain) {
+static int submit_domain_state(virDomainPtr domain) {
   int domain_state = 0;
   int domain_reason = 0;
 
@@ -1685,9 +1676,13 @@ static int get_domain_state(virDomainPtr domain) {
     return status;
   }
 
-  domain_state_submit(domain, domain_state, domain_reason);
+  value_t values[] = {
+      {.gauge = (gauge_t)domain_state}, {.gauge = (gauge_t)domain_reason},
+  };
+
+  submit(domain, "domain_state", NULL, values, STATIC_ARRAY_SIZE(values));
 
-  return status;
+  return 0;
 }
 
 #ifdef HAVE_LIST_ALL_DOMAINS
@@ -1702,8 +1697,7 @@ static int get_domain_state_notify(virDomainPtr domain) {
     return status;
   }
 
-  if (persistent_notification)
-    domain_state_submit_notif(domain, domain_state, domain_reason);
+  domain_state_submit_notif(domain, domain_state, domain_reason);
 
   return status;
 }
@@ -1737,9 +1731,9 @@ static int get_memory_stats(virDomainPtr domain) {
       swap_in = minfo[i].val;
     else if (minfo[i].tag == VIR_DOMAIN_MEMORY_STAT_SWAP_OUT)
       swap_out = minfo[i].val;
-    else if (minfo[i].tag == VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT)
-      min_flt = minfo[i].val;
     else if (minfo[i].tag == VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT)
+      min_flt = minfo[i].val;
+    else if (minfo[i].tag == VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT)
       maj_flt = minfo[i].val;
 #ifdef LIBVIR_CHECK_VERSION
 #if LIBVIR_CHECK_VERSION(2, 1, 0)
@@ -2007,7 +2001,7 @@ static int get_domain_metrics(domain_t *domain) {
      * however it doesn't provide a reason for entering particular state.
      * We need to get it from virDomainGetState.
      */
-    GET_STATS(get_domain_state, "domain reason", domain->ptr);
+    GET_STATS(submit_domain_state, "domain reason", domain->ptr);
 #endif
   }
 
@@ -2363,8 +2357,8 @@ static int lv_read(user_data_t *ud) {
     if (dom->active)
       status = get_domain_metrics(dom);
 #ifdef HAVE_DOM_REASON
-    else
-      status = get_domain_state(dom->ptr);
+    else if (extra_stats & ex_stats_domain_state)
+      status = submit_domain_state(dom->ptr);
 #endif
 
     if (status != 0)