From: Pavel Rochnyak Date: Wed, 15 May 2019 03:28:20 +0000 (+0700) Subject: Merge pull request #2986 from shastah/feature/curl-address-family X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=ff8b75e1820552a8bbd1832544451723cbde768b;hp=-c;p=collectd.git Merge pull request #2986 from shastah/feature/curl-address-family curl plugin: add AddressFamily --- ff8b75e1820552a8bbd1832544451723cbde768b diff --combined src/collectd.conf.in index f8e52881,7f5bda37..7f09c5cc --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@@ -223,7 -223,6 +223,7 @@@ #@BUILD_PLUGIN_WRITE_RIEMANN_TRUE@LoadPlugin write_riemann #@BUILD_PLUGIN_WRITE_SENSU_TRUE@LoadPlugin write_sensu #@BUILD_PLUGIN_WRITE_STACKDRIVER_TRUE@LoadPlugin write_stackdriver +#@BUILD_PLUGIN_WRITE_SYSLOG_TRUE@LoadPlugin write_syslog #@BUILD_PLUGIN_WRITE_TSDB_TRUE@LoadPlugin write_tsdb #@BUILD_PLUGIN_XENCPU_TRUE@LoadPlugin xencpu #@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms @@@ -404,6 -403,7 +404,7 @@@ # # # URL "http://finance.google.com/finance?q=NYSE%3AAMD" + # AddressFamily "any" # User "foo" # Password "bar" # Digest false @@@ -426,6 -426,7 +427,7 @@@ # # + # AddressFamily "any" # Instance "test_http_json" # # Type "gauge" @@@ -462,6 -463,7 +464,7 @@@ # } ## See: http://wiki.apache.org/couchdb/Runtime_Statistics # + # AddressFamily "ipv4" # Instance "httpd" # # Type "http_requests" @@@ -477,6 -479,7 +480,7 @@@ # ## Database status metrics: # + # AddressFamily "ipv6" # Instance "dbs" # # Type "gauge" @@@ -492,6 -495,7 +496,7 @@@ # # + # AddressFamily "any" # Host "my_host" # #Plugin "stats" # Instance "some_instance" @@@ -704,7 -708,6 +709,7 @@@ # # Cores "0-2" +# Processes "sshd" # # @@@ -1666,20 -1669,16 +1671,20 @@@ # Connection "xen:///" # RefreshInterval 60 # Domain "name" +# ReportBlockDevices true +# ReportNetworkInterfaces true # BlockDevice "name:device" # BlockDeviceFormat target # BlockDeviceFormatBasename false # InterfaceDevice "name:device" # IgnoreSelected false # HostnameFormat name +# HostnameMetadataXPath "/instance/name/text()" +# HostnameMetadataNS "http://openstack.org/xmlns/libvirt/nova/1.0" # InterfaceFormat name # PluginInstanceFormat name # Instances 1 -# ExtraStats "cpu_util disk disk_err domain_state fs_info job_stats_background pcpu perf vcpupin" +# ExtraStats "cpu_util disk disk_err domain_state fs_info job_stats_background pcpu perf vcpupin disk_physical disk_allocation disk_capacity" # PersistentNotification false # @@@ -1702,7 -1701,6 +1707,7 @@@ # SeparateInstances false # PreserveSeparator false # DropDuplicateFields false +# ReverseHost false # # @@@ -1811,18 -1809,6 +1816,18 @@@ # Url "https://monitoring.googleapis.com/v3" # +# +# +# Host "localhost" +# Port "44514" +# Prefix "collectd" +# MessageFormat "human" +# HostTags "" +# StoreRates false +# AlwaysAppendDS false +# +# + # # # Host "localhost" diff --combined src/collectd.conf.pod index 800c0d22,cf048724..71931c2b --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@@ -1656,24 -1656,15 +1656,24 @@@ Defaults to B =head2 Plugin C -This plugin doesn't have any options. It reads +This plugin is available on Linux and FreeBSD only. It doesn't have any +options. On Linux it reads F (for the first CPU installed) to get the current CPU frequency. If this file does not exist make sure B (L) or a similar tool is installed and an "cpu governor" (that's a kernel module) is loaded. -If the system has the I kernel module loaded, this plugin reports -the rate of p-state (cpu frequency) transitions and the percentage of time spent -in each p-state. +On Linux, if the system has the I kernel module loaded, this +plugin reports the rate of p-state (cpu frequency) transitions and the +percentage of time spent in each p-state. + +On FreeBSD it does a sysctl dev.cpu.0.freq and submits this as instance 0. +At this time FreeBSD only has one frequency setting for all cores. +See the BUGS section in the FreeBSD man page for cpufreq(4) for more details. + +On FreeBSD the plugin checks the success of sysctl dev.cpu.0.freq and +unregisters the plugin when this fails. A message will be logged to indicate +this. =head2 Plugin C @@@ -1804,6 -1795,7 +1804,7 @@@ finance page and dispatch the value to Plugin "quotes" URL "http://finance.google.com/finance?q=NYSE%3AAMD" + AddressFamily "any" User "foo" Password "bar" Digest false @@@ -1844,6 -1836,18 +1845,18 @@@ Defaults to C 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 I + + 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 to enforce IPv4, C to enforce IPv6, or C to keep the + default behavior of resolving addresses to all IP versions your system allows. + If C is compiled without IPv6 support, using C will result in + a warning and fallback to C. + If C cannot be parsed, a warning will be printed and the whole B + block will be ignored. + =item B I Username to use if authorization is required to read the page. @@@ -1955,6 -1959,7 +1968,7 @@@ C<_stats> runtime statistics module of + AddressFamily "any" Instance "httpd" Type "http_requests" @@@ -1999,6 -2004,18 +2013,18 @@@ The following options are valid within =over 4 + =item B I + + 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 to enforce IPv4, C to enforce IPv6, or C to keep the + default behavior of resolving addresses to all IP versions your system allows. + If C is compiled without IPv6 support, using C will result in + a warning and fallback to C. + If C cannot be parsed, a warning will be printed and the whole B + block will be ignored. + =item B I Use I as the host name when submitting values. Defaults to the global @@@ -2070,6 -2087,7 +2096,7 @@@ The B uses B + AddressFamily "any" Host "my_host" #Plugin "curl_xml" Instance "some_instance" @@@ -2106,6 -2124,18 +2133,18 @@@ Within the B block the following o =over 4 + =item B I + + 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 to enforce IPv4, C to enforce IPv6, or C to keep the + default behavior of resolving addresses to all IP versions your system allows. + If C is compiled without IPv6 support, using C will result in + a warning and fallback to C. + If C cannot be parsed, a warning will be printed and the whole B + block will be ignored. + =item B I Use I as the host name when submitting values. Defaults to the global @@@ -3507,7 -3537,6 +3546,7 @@@ B Cores "0-2" "3,4,6" "8-10,15" + Processes "sshd,qemu-system-x86" "bash" B @@@ -3523,10 -3552,11 +3562,10 @@@ recommended to set interval higher tha =item B I -All events are reported on a per core basis. Monitoring of the events can be -configured for group of cores (aggregated statistics). This field defines groups -of cores on which to monitor supported events. The field is represented as list -of strings with core group values. Each string represents a list of cores in a -group. Allowed formats are: +Monitoring of the events can be configured for group of cores +(aggregated statistics). This field defines groups of cores on which to monitor +supported events. The field is represented as list of strings with core group +values. Each string represents a list of cores in a group. Allowed formats are: 0,1,2,3 0-10,20-18 1,3,5-8,10,0x10-12 @@@ -3534,15 -3564,6 +3573,15 @@@ If an empty string is provided as value for this field default cores configuration is applied - a separate group is created for each core. +=item B I + +Monitoring of the events can be configured for group of processes +(aggregated statistics). This field defines groups of processes on which to +monitor supported events. The field is represented as list of strings with +process names group values. Each string represents a list of processes in a +group. Allowed format is: + sshd,bash,qemu + =back B By default global interval is used to retrieve statistics on monitored @@@ -4462,12 -4483,6 +4501,12 @@@ For Modbus/RTU, specifies the path to t For Modbus/RTU, specifies the baud rate of the serial device. Note, connections currently support only 8/N/1. +=item B I + +For Modbus/RTU, specifies the type of the serial device. +RS232, RS422 and RS485 are supported. Defaults to RS232. +Available only on Linux systems with libmodbus>=2.9.4. + =item B I Sets the interval (in seconds) in which the values will be collected from this @@@ -5357,9 -5372,8 +5396,9 @@@ When configuring with B onl namely octets, packets, and errors. These statistics are collected by the C plugin, too, so using both at the same time is no benefit. -When configured with B all counters B the basic ones, -so that no data needs to be collected twice if you use the C plugin. +When configured with B all counters B the basic ones +will be collected, so that no data needs to be collected twice if you use the +C plugin. This includes dropped packets, received multicast packets, collisions and a whole zoo of differentiated RX and TX errors. You can try the following command to get an idea of what awaits you: @@@ -6299,7 -6313,6 +6338,7 @@@ B The plugin provides the following configuration options: @@@ -6333,13 -6346,6 +6372,13 @@@ omitted or is empty then all OVS bridge Default: empty (monitor all bridges) +=item B B|B + +Indicates that the plugin should gather statistics for individual interfaces +in addition to ports. This can be useful when monitoring an OVS setup with +bond ports, where you might wish to know individual statistics for the +interfaces included in the bonds. Defaults to B. + =back =head2 Plugin C @@@ -8421,26 -8427,26 +8460,26 @@@ Sets how the values are cumulated. I -Calculate the average. +Calculate the average of all values matched during the interval. =item B -Use the smallest number only. +Report the smallest value matched during the interval. =item B -Use the greatest number only. +Report the greatest value matched during the interval. =item B -Use the last number found. +Report the last value matched during the interval. =item B -Use the last number found. The number is not reset at the end of an interval. -It is continously reported until another number is matched. This is intended -for cases in which only state changes are reported, for example a thermometer -that only reports the temperature when it changes. +Report the last matching value. The metric is I reset to C at the end +of an interval. It is continuously reported until another value is matched. +This is intended for cases in which only state changes are reported, for +example a thermometer that only reports the temperature when it changes. =item B @@@ -8471,9 -8477,6 +8510,9 @@@ Increase the internal counter by one. T not use the matched subexpression, but simply count the number of matched lines. Thus, you may use a regular expression without submatch in this case. +B is reset to I after every read, unlike other B +metrics which are reset to C. + =item B Type to do calculations based on the distribution of values, primarily @@@ -8547,12 -8550,8 +8586,12 @@@ The B and B type point number, using L. The B and B types interpret the submatch as an unsigned integer using L. The B types interpret the submatch as a signed integer using -L. B and B do not use the submatch at all -and it may be omitted in this case. +L. B, B and B do not use the +submatch at all and it may be omitted in this case. + +The B types, unless noted otherwise, are reset to C after being +reported. In other words, B reports the average of all values +matched since the last metric was reported (or C if there was no match). =item B I @@@ -9276,51 -9275,13 +9315,51 @@@ surrounded by I and collectd wa The default is to collect statistics for all domains and all their devices. -Example: +B B and B options are related to +corresponding B<*Format> options. Specifically, B filtering depends +on B setting - if user wants to filter block devices by +'target' name then B option has to be set to 'target' and +B option must be set to a valid block device target +name("/:hdb/"). Mixing formats and filter values from different worlds (i.e., +using 'target' name as B value with B set to +'source') may lead to unexpected results (all devices filtered out or all +visible, depending on the value of B option). +Similarly, option B is related to B setting +(i.e., when user wants to use MAC address as a filter then B +has to be set to 'address' - using wrong type here may filter out all of the +interfaces). + +B + +Ignore all I devices on any domain, but other block devices (eg. I) +will be collected: BlockDevice "/:hdb/" IgnoreSelected "true" + BlockDeviceFormat "target" -Ignore all I devices on any domain, but other block devices (eg. I) -will be collected. +B + +Collect metrics only for block device on 'baremetal0' domain when its +'source' matches given path: + + BlockDevice "baremetal0:/var/lib/libvirt/images/baremetal0.qcow2" + BlockDeviceFormat source + +As you can see it is possible to filter devices/interfaces using +various formats - for block devices 'target' or 'source' name can be +used. Interfaces can be filtered using 'name', 'address' or 'number'. + +B + +Collect metrics only for domains 'baremetal0' and 'baremetal1' and +ignore any other domain: + + Domain "baremetal0" + Domain "baremetal1" + +It is possible to filter multiple block devices/domains/interfaces by +adding multiple filtering entries in separate lines. =item B B|B @@@ -9351,11 -9312,6 +9390,11 @@@ to C Setting C will cause the I to be set to C. +B this option determines also what field will be used for +filtering over block devices (filter value in B +will be applied to target or source). More info about filtering +block devices can be found in the description of B. + =item B B|B The B controls whether the full path or the @@@ -9370,7 -9326,7 +9409,7 @@@ be set to C will cause the I to be set to C. -=item B B +=item B B When the virt plugin logs data, it sets the hostname of the collected data according to this setting. The default is to use the guest name as provided by @@@ -9383,9 -9339,6 +9422,9 @@@ B means to use the global B though. +B means use information from guest's metadata. Use +B and B to localize this information. + You can also specify combinations of these fields. For example B means to concatenate the guest name and UUID (with a literal colon character between, thus I<"foo:1234-1234-1234-1234">). @@@ -9394,7 -9347,7 +9433,7 @@@ At the moment of writing (collectd-5.5) characters. In case when combination of fields exceeds 62 characters, hostname will be truncated without a warning. -=item B B|B
+=item B B|B
|B When the virt plugin logs interface data, it sets the name of the collected data according to this setting. The default is to use the path as provided by @@@ -9404,47 -9357,23 +9443,47 @@@ setting B B
means use the interface's mac address. This is useful since the interface path might change between reboots of a guest or across migrations. -=item B B +B means use the interface's number in guest. + +B this option determines also what field will be used for +filtering over interface device (filter value in B +will be applied to name, address or number). More info about filtering +interfaces can be found in the description of B. + +=item B B When the virt plugin logs data, it sets the plugin_instance of the collected data according to this setting. The default is to not set the plugin_instance. B means use the guest's name as provided by the hypervisor. B means use the guest's UUID. +B means use information from guest's metadata. You can also specify combinations of the B and B fields. For example B means to concatenate the guest name and UUID (with a literal colon character between, thus I<"foo:1234-1234-1234-1234">). -=item B B +=item B B -How many read instances you want to use for this plugin. The default is one, -and the sensible setting is a multiple of the B value. -If you are not sure, just use the default setting. +When B is used in B or B, this +selects in which metadata namespace we will pick the hostname. The default is +I. + +=item B B + +When B is used in B or B, this +describes where the hostname is located in the libvirt metadata. The default is +I. + +=item B B|B + +Enabled by default. Allows to disable stats reporting of block devices for +whole plugin. + +=item B B|B + +Enabled by default. Allows to disable stats reporting of network interfaces for +whole plugin. =item B B @@@ -9466,7 -9395,9 +9505,7 @@@ I<0.9.5> or later =item B: report disk errors if any occured. Requires libvirt API version I<0.9.10> or later. -=item B: 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: report domain state and reason as 'domain_state' metric. =item B: report file system information as a notification. Requires libvirt API version I<1.2.11> or later. Can be collected only if I @@@ -9491,53 -9422,14 +9530,53 @@@ B: I metrics can't be colle =item B: report pinning of domain VCPUs to host physical CPUs. +=item B: report 'disk_physical' statistic for disk device. +B: This statistic is only reported for disk devices with 'source' +property available. + +=item B: report 'disk_allocation' statistic for disk device. +B: This statistic is only reported for disk devices with 'source' +property available. + +=item B: report 'disk_capacity' statistic for disk device. +B: This statistic is only reported for disk devices with 'source' +property available. + =back =item B B|B + Override default configuration to only send notifications when there is a change in the lifecycle state of a domain. When set to true notifications will be sent for every read cycle. Default is false. Does not affect the stats being dispatched. +=item B B + +How many read instances you want to use for this plugin. The default is one, +and the sensible setting is a multiple of the B value. + +This option is only useful when domains are specially tagged. +If you are not sure, just use the default setting. + +The reader instance will only query the domains with attached matching tag. +Tags should have the form of 'virt-X' where X is the reader instance number, +starting from 0. + +The special-purpose reader instance #0, guaranteed to be always present, +will query all the domains with missing or unrecognized tag, so no domain will +ever be left out. + +Domain tagging is done with a custom attribute in the libvirt domain metadata +section. Value is selected by an XPath I +expression in the I namespace. +(XPath and namespace values are not configurable yet). + +Tagging could be used by management applications to evenly spread the +load among the reader threads, or to pin on the same threads all +the libvirt domains which use the same shared storage, to minimize +the disruption in presence of storage outages. + =back =head2 Plugin C @@@ -9592,7 -9484,6 +9631,7 @@@ Synopsis LogSendErrors true Prefix "collectd" UseTags false + ReverseHost false @@@ -9704,30 -9595,6 +9743,30 @@@ are not used Default value: B. +=item B B|B + +If set to B, the (dot separated) parts of the B field of the +I will be rewritten in reverse order. The rewrite happens I +special characters are replaced with the B. + +This option might be convenient if the metrics are presented with Graphite in a +DNS like tree structure (probably without replacing dots in hostnames). + +Example: + Hostname "node3.cluster1.example.com" + LoadPlugin "cpu" + LoadPlugin "write_graphite" + + + EscapeCharacter "." + ReverseHost true + + + + result on the wire: com.example.cluster1.node3.cpu-0.cpu-idle 99.900993 1543010932 + +Default value: B. + =back =head2 Plugin C @@@ -10703,141 -10570,6 +10742,141 @@@ C =back +=head2 Plugin C + +The C plugin writes data in I format log messages. +It implements the basic syslog protocol, RFC 5424, extends it with +content-based filtering, rich filtering capabilities, +flexible configuration options and adds features such as using TCP for transport. +The plugin can connect to a I daemon, like syslog-ng and rsyslog, that will +ingest metrics, transform and ship them to the specified output. +The plugin uses I over the "line based" protocol with a default port 44514. +The data will be sent in blocks of at most 1428 bytes to minimize the number of +network packets. + +Synopsis: + + + ResolveInterval 60 + ResolveJitter 60 + + Host "syslog-1.my.domain" + Port "44514" + Prefix "collectd" + MessageFormat "human" + HostTags "" + + + +The configuration consists of one or more EBEIE +blocks and global directives. + +Global directives are: + +=over 4 + +=item B I + +=item B I + +When I connects to a syslog node, it will request the hostname from +DNS. This can become a problem if the syslog node is unavailable or badly +configured because collectd will request DNS in order to reconnect for every +metric, which can flood your DNS. So you can cache the last value for +I seconds. +Defaults to the I of the I, e.g. 10Eseconds. + +You can also define a jitter, a random interval to wait in addition to +I. This prevents all your collectd servers to resolve the +hostname at the same time when the connection fails. +Defaults to the I of the I, e.g. 10Eseconds. + +B If the DNS resolution has already been successful when the socket +closes, the plugin will try to reconnect immediately with the cached +information. DNS is queried only when the socket is closed for a longer than +I + I seconds. + +=back + +Inside the B blocks, the following options are recognized: + +=over 4 + +=item B I
+ +Hostname or address to connect to. Defaults to C. + +=item B I + +Service name or port number to connect to. Defaults to C<44514>. + + +=item B I + +When set, I is added to the end of the metric. +It is intended to be used for adding additional metadata to tag the metric with. +Dots and whitespace are I escaped in this string. + +Examples: + +When MessageFormat is set to "human". + + ["prefix1" "example1"="example1_v"]["prefix2" "example2"="example2_v"]" + +When MessageFormat is set to "JSON", text should be in JSON format. +Escaping the quotation marks is required. + + HostTags "\"prefix1\": {\"example1\":\"example1_v\",\"example2\":\"example2_v\"}" + +=item B I + +I selects the format in which messages are sent to the +syslog deamon, human or JSON. Defaults to human. + +Syslog message format: + +VERSION ISOTIMESTAMP HOSTNAME APPLICATION PID MESSAGEID STRUCTURED-DATA MSG + +The difference between the message formats are in the STRUCTURED-DATA and MSG parts. + +Human format: + + <166>1 ISOTIMESTAMP HOSTNAME collectd PID MESSAGEID + ["collectd" "value": "v1" "plugin"="plugin_v" "plugin_instance"="plugin_instance_v" + "type_instance"="type_instance_v" "type"="type_v" "ds_name"="ds_name_v" "interval"="interval_v" ] + "host_tag_example"="host_tag_example_v" plugin_v.type_v.ds_name_v="v1" + +JSON format: + + <166>1 ISOTIMESTAMP HOSTNAME collectd PID MESSAGEID STRUCTURED-DATA + { + "collectd": { + "time": time_as_epoch, "interval": interval_v, "plugin": "plugin_v", + "plugin_instance": "plugin_instance_v", "type":"type_v", + "type_instance": "type_instance_v", "plugin_v": {"type_v": v1} + } , "host":"host_v", "host_tag_example": "host_tag_example_v" + } + +=item B B|B + +If set to B, convert counter values to rates. If set to B +(the default) counter values are stored as is, as an increasing +integer number. + +=item B B|B + +If set to B, append the name of the I (DS) to the "metric" +identifier. If set to B (the default), this is only done when there is +more than one DS. + +=item B I + +When set, I is added to all metrics names as a prefix. It is intended in +case you want to be able to define the source of the specific metric. Dots and +whitespace are I escaped in this string. + +=back + =head2 Plugin C This plugin collects metrics of hardware CPU load for machine running Xen @@@ -11826,7 -11558,7 +11865,7 @@@ be an FQDN =head1 IGNORELISTS B are a generic framework to either ignore some metrics or report -specific metircs only. Plugins usually provide one or more options to specify +specific metrics only. Plugins usually provide one or more options to specify the items (mounts points, devices, ...) and the boolean option C. diff --combined src/curl.c index 9ad3dc83,292b165f..e3e3c174 --- a/src/curl.c +++ b/src/curl.c @@@ -23,10 -23,10 +23,10 @@@ #include "collectd.h" -#include "common.h" #include "plugin.h" -#include "utils_curl_stats.h" -#include "utils_match.h" +#include "utils/common/common.h" +#include "utils/curl_stats/curl_stats.h" +#include "utils/match/match.h" #include "utils_time.h" #include @@@ -57,6 -57,7 +57,7 @@@ struct web_page_s /* {{{ * char *instance; char *url; + int address_family; char *user; char *pass; char *credentials; @@@ -345,6 -346,7 +346,7 @@@ static int cc_page_init_curl(web_page_ 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 +413,7 @@@ static int cc_config_add_page(oconfig_i } 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 +440,34 @@@ 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); diff --combined src/curl_json.c index a26664f0,4f7852f9..9d01e6e3 --- a/src/curl_json.c +++ b/src/curl_json.c @@@ -23,11 -23,11 +23,11 @@@ #include "collectd.h" -#include "common.h" #include "plugin.h" -#include "utils_avltree.h" +#include "utils/avltree/avltree.h" +#include "utils/common/common.h" +#include "utils/curl_stats/curl_stats.h" #include "utils_complain.h" -#include "utils_curl_stats.h" #include #include @@@ -88,6 -88,7 +88,7 @@@ struct cj_s /* {{{ * char *sock; char *url; + int address_family; char *user; char *pass; char *credentials; @@@ -236,7 -237,7 +237,7 @@@ static int cj_cb_number(void *ctx, cons /* Create a null-terminated version of the string. */ char buffer[number_len + 1]; memcpy(buffer, number, number_len); - buffer[sizeof(buffer) - 1] = 0; + buffer[sizeof(buffer) - 1] = '\0'; if (db->state[db->depth].entry == NULL || db->state[db->depth].entry->type != KEY) { @@@ -272,7 -273,7 +273,7 @@@ static int cj_cb_map_key(void *ctx, uns char name[in_name_len + 1]; memmove(name, in_name, in_name_len); - name[sizeof(name) - 1] = 0; + name[sizeof(name) - 1] = '\0'; if (cj_load_key(ctx, name) != 0) return CJ_CB_ABORT; @@@ -582,6 -583,7 +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 +651,7 @@@ static int cj_config_add_url(oconfig_it } 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 +705,31 @@@ 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; diff --combined src/curl_xml.c index ed70f698,a8bc3c0b..ce6bd468 --- a/src/curl_xml.c +++ b/src/curl_xml.c @@@ -21,9 -21,9 +21,9 @@@ #include "collectd.h" -#include "common.h" #include "plugin.h" -#include "utils_curl_stats.h" +#include "utils/common/common.h" +#include "utils/curl_stats/curl_stats.h" #include "utils_llist.h" #include @@@ -76,6 -76,7 +76,7 @@@ struct cx_s /* {{{ * char *host; char *url; + int address_family; char *user; char *pass; char *credentials; @@@ -736,6 -737,7 +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 +816,7 @@@ static int cx_config_add_url(oconfig_it } 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 +866,31 @@@ 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;