+2011-03-28, Version 5.0.0
+ * collectd: The "FQDNLookup" option is now enabled by default.
+ * collectd: The internal representation of time has been changed to
+ allow a higher accuracy than one second.
+ * collectdcmd: This new command line utility can send various commands
+ to collectd using the UnixSock plugin. Thanks to Håkon Dugstad
+ Johnsen and Sebastian Harl for their code.
+ * collectd-nagios: The "-m" option has been implemented (treat NaNs as
+ critical).
+ * collectd-tg: Traffic generator creating bogus network traffic
+ compatible to the Network plugin. This utility can be used to
+ stress-test new write plugins and collectd in general.
+ * libcollectdclient: Creating and sending network packets has been
+ added to the collectd client library.
+ * All data sets: The data source name of all data sets with exactly
+ one data source has been changed to "value".
+ * All plugins: All "counter" data sources have been converted to
+ "derive" data sources. All plugins now use "derive" by default, but
+ plugins such as the network plugin can still handle "counter", of
+ course. The minimum value of all derive data sources is zero, the
+ maximum value is unspecified.
+ * amqp plugin: The new AMQP plugin can send data to and receive data
+ from an AMQP broker. Thanks to Sebastien Pahl for his code.
+ * apache plugin: Backwards compatibility code has been removed.
+ Support for the IBM HTTP Server has been added. Thanks to Manuel
+ Luis Sanmartín Rozada for his patch.
+ * contextswitch plugin: Support for sysctlbyname(3) has been added.
+ Thanks to Kimo Rosenbaum for his patch.
+ * df plugin: The default behavior has been changed to be equivalent to
+ the "ReportReserved" behavior of v4.
+ * dns plugin: Improved RFC 1035 name parsing has been imported from
+ "dnstop".
+ * exec plugin: Backwards compatibility code has been removed.
+ * GenericJMX plugin: The "InstancePrefix" option has been added to
+ "Connection" blocks.
+ * hddtemp plugin: The "TranslateDevicename" config option has been
+ removed.
+ * interface plugin: Use the "plugin instance" to store the interface
+ value.
+ * libvirt plugin: The "InterfaceFormat" option has been added. Thanks
+ to Ruben Kerkhof for his patch.
+ * lpar plugin: New plugins for "logical partitions", a virtualization
+ technique of POWER CPUs. Thanks to Aurélien Reynaud for his code and
+ patience.
+ * modbus plugin: Support for libmodbus 2.9.2 has been added and the
+ license has been changes to LGPLv2.1.
+ * mysql plugin: Backwards compatibility code has been removed. The
+ data sets used have been improved.
+ * network plugin: The default buffer size has been increased to
+ 1452 bytes.
+ * perl plugin: Backwards compatibility code has been removed.
+ * postgresql plugin: Backwards compatibility code has been removed.
+ * redis plugin: Plugin for collecting statistics from Redis, a key-
+ value store, has been added. Thanks to Andres J. Diaz for his code.
+ * swap plugin: Implement collection of physical and virtual memory
+ statistics under Solaris. The new default is collecting physical
+ memory. Thanks to Aurélien Reynaud for his patches.
+ * threshold plugin: The threshold configuration has been moved into
+ this separate plugin.
+ * unixsock plugin: The "DeleteSocket" option has been added.
+ * varnish plugin: The new Varnish plugin reads statistics from
+ Varnish, a web accelerator. Thanks to Jérôme Renard and Marc
+ Fournier for their contributions.
+ * write_redis: New plugin for writing data to Redis, a key-value
+ store.
+ * zfs_arc plugin: The data sets have been replaced by more elegant
+ alternatives.
+ * v5upgrade target: Target for converting v4 data sets to the v5
+ schema.
+
+ 2011-10-07, Version 4.10.4
+ * collectd: A mutex leak has been fixed in the meta data code. Thanks
+ to Rafal Lesniak for his patch.
+ * collectd: Compatibility fixes for GCC 4.6 have been applied.
+ * csv plugin: The line buffer size has been increased. Thanks to Colin
+ McCabe for the patch.
+ * curl_json plugin: Don't use the "parent" node to build the type
+ instance, if it is empty. Compatibility with libyajl 2 has been
+ added. Thanks to "spupykin" of the Arch Linux project for the initial
+ code.
+ * iptables plugin: Fix linking with some versions of libiptc.
+ * irq plugin: Fix support for interrupts under Linux. The old code
+ assumed that interrupts have a numeric value -- this is no longer
+ true for Linux. Thanks to Bostjan Skufca for implementing this.
+ * notify_desktop plugin: Compatibility with libnotify 0.7 has been
+ added. Thanks to Samuli Suominen for his patch.
+ * processes plugin: Fix handling of regular expressions containing
+ spaces. Thanks for Sebastian Harl for fixing this.
+ * rrdtool, rrdcached plugins: Improve precision of the XFF parameter.
+ Previously, values like 0.999 would have been rounded to 1.0. Thanks
+ to Francois-Xavier Bourlet for fixing this.
+ * Various plugin: Set a multi-threading flag in libcurl. Thanks to Mike
+ Flisher for the fix.
+
2011-03-26, Version 4.10.3
* Documentation: Several updates and additions. Thanks to Sebastian Harl.
* collectd: Build issues (compiler warnings) have been fixed. Thanks to
##############################################################################
#Hostname "localhost"
-FQDNLookup true
+#FQDNLookup true
#BaseDir "@prefix@/var/lib/@PACKAGE_NAME@"
#PIDFile "@prefix@/var/run/@PACKAGE_NAME@.pid"
#PluginDir "@prefix@/lib/@PACKAGE_NAME@"
# to missing dependencies or because they have been deactivated explicitly. #
##############################################################################
+#@BUILD_PLUGIN_AMQP_TRUE@LoadPlugin amqp
#@BUILD_PLUGIN_APACHE_TRUE@LoadPlugin apache
#@BUILD_PLUGIN_APCUPS_TRUE@LoadPlugin apcups
#@BUILD_PLUGIN_APPLE_SENSORS_TRUE@LoadPlugin apple_sensors
#@BUILD_PLUGIN_JAVA_TRUE@LoadPlugin java
#@BUILD_PLUGIN_LIBVIRT_TRUE@LoadPlugin libvirt
@BUILD_PLUGIN_LOAD_TRUE@@BUILD_PLUGIN_LOAD_TRUE@LoadPlugin load
+#@BUILD_PLUGIN_LPAR_TRUE@LoadPlugin lpar
#@BUILD_PLUGIN_MADWIFI_TRUE@LoadPlugin madwifi
#@BUILD_PLUGIN_MBMON_TRUE@LoadPlugin mbmon
#@BUILD_PLUGIN_MEMCACHEC_TRUE@LoadPlugin memcachec
#@BUILD_PLUGIN_ONEWIRE_TRUE@LoadPlugin onewire
#@BUILD_PLUGIN_OPENVPN_TRUE@LoadPlugin openvpn
#@BUILD_PLUGIN_ORACLE_TRUE@LoadPlugin oracle
- #@BUILD_PLUGIN_PERL_TRUE@LoadPlugin perl
+ #@BUILD_PLUGIN_PERL_TRUE@<LoadPlugin perl>
+ #@BUILD_PLUGIN_PERL_TRUE@ Globals true
+ #@BUILD_PLUGIN_PERL_TRUE@</LoadPlugin>
#@BUILD_PLUGIN_PINBA_TRUE@LoadPlugin pinba
#@BUILD_PLUGIN_PING_TRUE@LoadPlugin ping
#@BUILD_PLUGIN_POSTGRESQL_TRUE@LoadPlugin postgresql
#@BUILD_PLUGIN_POWERDNS_TRUE@LoadPlugin powerdns
#@BUILD_PLUGIN_PROCESSES_TRUE@LoadPlugin processes
#@BUILD_PLUGIN_PROTOCOLS_TRUE@LoadPlugin protocols
- #@BUILD_PLUGIN_PYTHON_TRUE@LoadPlugin python
+ #@BUILD_PLUGIN_PYTHON_TRUE@<LoadPlugin python>
+ #@BUILD_PLUGIN_PYTHON_TRUE@ Globals true
+ #@BUILD_PLUGIN_PYTHON_TRUE@</LoadPlugin>
+#@BUILD_PLUGIN_REDIS_TRUE@LoadPlugin redis
#@BUILD_PLUGIN_ROUTEROS_TRUE@LoadPlugin routeros
#@BUILD_PLUGIN_RRDCACHED_TRUE@LoadPlugin rrdcached
@LOAD_PLUGIN_RRDTOOL@LoadPlugin rrdtool
#@BUILD_PLUGIN_UPTIME_TRUE@LoadPlugin uptime
#@BUILD_PLUGIN_USERS_TRUE@LoadPlugin users
#@BUILD_PLUGIN_UUID_TRUE@LoadPlugin uuid
+#@BUILD_PLUGIN_VARNISH_TRUE@LoadPlugin varnish
#@BUILD_PLUGIN_VMEM_TRUE@LoadPlugin vmem
#@BUILD_PLUGIN_VSERVER_TRUE@LoadPlugin vserver
#@BUILD_PLUGIN_WIRELESS_TRUE@LoadPlugin wireless
#@BUILD_PLUGIN_WRITE_HTTP_TRUE@LoadPlugin write_http
+#@BUILD_PLUGIN_WRITE_REDIS_TRUE@LoadPlugin write_redis
#@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms
#@BUILD_PLUGIN_ZFS_ARC_TRUE@LoadPlugin zfs_arc
# ription of those options is available in the collectd.conf(5) manual page. #
##############################################################################
+#<Plugin "amqp">
+# <Publish "name">
+# Host "localhost"
+# Port "5672"
+# VHost "/"
+# User "guest"
+# Password "guest"
+# Exchange "amq.fanout"
+# RoutingKey "collectd"
+# Persistent false
+# StoreRates false
+# </Publish>
+#</Plugin>
+
#<Plugin apache>
-# URL "http://localhost/status?auto"
-# User "www-user"
-# Password "secret"
-# CACert "/etc/ssl/ca.crt"
+# <Instance "local">
+# URL "http://localhost/status?auto"
+# User "www-user"
+# Password "secret"
+# CACert "/etc/ssl/ca.crt"
+# </Instance>
#</Plugin>
#<Plugin apcups>
#<Plugin hddtemp>
# Host "127.0.0.1"
# Port "7634"
-#
-# #----------------------------------------------------------------#
-# # `TranslateDevicename' enables backwards compatibility behavior #
-# # and is enabled by default. Setting this option to `false' is #
-# # highly recommended. #
-# #----------------------------------------------------------------#
-# TranslateDevicename false
#</Plugin>
#<Plugin interface>
# InterfaceDevice "name:device"
# IgnoreSelected false
# HostnameFormat name
+# InterfaceFormat name
+#</Plugin>
+
+#<Plugin lpar>
+# CpuPoolStats false
+# ReportBySerial false
#</Plugin>
#<Plugin madwifi>
# </Module>
#</Plugin>
+#<Plugin redis>
+# <Node example>
+# Host "redis.example.com"
+# Port "6379"
+# Timeout 2000
+# </Node>
+#</Plugin>
+
#<Plugin routeros>
# <Router>
# Host "router.example.com"
# SocketFile "@prefix@/var/run/@PACKAGE_NAME@-unixsock"
# SocketGroup "collectd"
# SocketPerms "0660"
+# DeleteSocket false
#</Plugin>
#<Plugin uuid>
# UUIDFile "/etc/uuid"
#</Plugin>
+#<Plugin varnish>
+# This tag support an argument if you want to
+# monitor the local instance just use </Instance>
+# If you prefer defining another instance you can do
+# so by using <Instance "myinstance">
+# <Instance>
+# CollectCache true
+# CollectBackend true
+# CollectConnections true
+# CollectSHM true
+# CollectESI false
+# CollectFetch false
+# CollectHCB false
+# CollectSMA false
+# CollectSMS false
+# CollectSM false
+# CollectTotals false
+# CollectWorkers false
+# </Instance>
+#</Plugin>
+
#<Plugin vmem>
# Verbose false
#</Plugin>
# </URL>
#</Plugin>
+#<Plugin write_redis>
+# <Node "example">
+# Host "localhost"
+# Port "6379"
+# Timeout 1000
+# </Node>
+#</Plugin>
+
##############################################################################
# Filter configuration #
#----------------------------------------------------------------------------#
#<Chain "PostCache">
# Target "write"
#</Chain>
+
+##############################################################################
+# Threshold configuration #
+#----------------------------------------------------------------------------#
+# The following outlines how to configure collectd's threshold checking #
+# plugin. The plugin and possible configuration options are documented in #
+# the collectd-threshold(5) manual page. #
+##############################################################################
+
+#@BUILD_PLUGIN_THRESHOLD_TRUE@LoadPlugin "threshold"
+#<Plugin "threshold">
+# <Type "foo">
+# WarningMin 0.00
+# WarningMax 1000.00
+# FailureMin 0.00
+# FailureMax 1200.00
+# Invert false
+# Instance "bar"
+# </Type>
+#
+# <Plugin "interface">
+# Instance "eth0"
+# <Type "if_octets">
+# FailureMax 10000000
+# DataSource "rx"
+# </Type>
+# </Plugin>
+#
+# <Host "hostname">
+# <Type "cpu">
+# Instance "idle"
+# FailureMin 10
+# </Type>
+#
+# <Plugin "memory">
+# <Type "memory">
+# Instance "cached"
+# WarningMin 100000000
+# </Type>
+# </Plugin>
+#
+# <Type "load">
+# DataSource "midterm"
+# FailureMax 4
+# Hits 3
+# Hysteresis 3
+# </Type>
+# </Host>
+#</Plugin>
#include "plugin.h"
#include "configfile.h"
#include "utils_avltree.h"
+ #include "utils_complain.h"
#include <curl/curl.h>
#include <yajl/yajl_parse.h>
#define CJ_DEFAULT_HOST "localhost"
#define CJ_KEY_MAGIC 0x43484b59UL /* CHKY */
-#define CJ_IS_KEY(key) (key)->magic == CJ_KEY_MAGIC
+#define CJ_IS_KEY(key) ((key)->magic == CJ_KEY_MAGIC)
#define CJ_ANY "*"
#define COUCH_MIN(x,y) ((x) < (y) ? (x) : (y))
char *user;
char *pass;
char *credentials;
- int verify_peer;
- int verify_host;
+ _Bool verify_peer;
+ _Bool verify_host;
char *cacert;
CURL *curl;
if (db == NULL)
return (0);
- status = yajl_parse(db->yajl, (unsigned char *)buf, len);
+ status = yajl_parse(db->yajl, (unsigned char *) buf, len);
if (status == yajl_status_ok)
{
#if HAVE_YAJL_V2
if (status != yajl_status_ok)
{
unsigned char *msg =
- yajl_get_error(db->yajl, 1, (unsigned char *)buf, len);
+ yajl_get_error(db->yajl, /* verbose = */ 1,
+ /* jsonText = */ (unsigned char *) buf, (unsigned int) len);
ERROR ("curl_json plugin: yajl_parse failed: %s", msg);
yajl_free_error(db->yajl, msg);
return (0); /* abort write callback */
ds = plugin_get_ds (key->type);
if (ds == NULL)
- return -1; /* let plugin_write do the complaining */
- else
- return ds->ds[0].type; /* XXX support ds->ds_len > 1 */
+ {
+ static char type[DATA_MAX_NAME_LEN] = "!!!invalid!!!";
+
+ assert (key->type != NULL);
+ if (strcmp (type, key->type) != 0)
+ {
+ ERROR ("curl_json plugin: Unable to look up DS type \"%s\".",
+ key->type);
+ sstrncpy (type, key->type, sizeof (type));
+ }
+
+ return -1;
+ }
+ else if (ds->ds_num > 1)
+ {
+ static c_complain_t complaint = C_COMPLAIN_INIT_STATIC;
+
+ c_complain_once (LOG_WARNING, &complaint,
+ "curl_json plugin: The type \"%s\" has more than one data source. "
+ "This is currently not supported. I will return the type of the "
+ "first data source, but this will likely lead to problems later on.",
+ key->type);
+ }
+
+ return ds->ds[0].type;
}
/* yajl callbacks */
cj_t *db = (cj_t *)ctx;
cj_key_t *key = db->state[db->depth].key;
- char *endptr;
value_t vt;
int type;
+ int status;
- if (key == NULL)
+ if ((key == NULL) || !CJ_IS_KEY (key))
return (CJ_CB_CONTINUE);
memcpy (buffer, number, number_len);
buffer[sizeof (buffer) - 1] = 0;
type = cj_get_type (key);
- if (type < 0)
- return (CJ_CB_CONTINUE);
-
- endptr = NULL;
- errno = 0;
-
- if (type == DS_TYPE_COUNTER)
- vt.counter = (counter_t) strtoull (buffer, &endptr, /* base = */ 0);
- else if (type == DS_TYPE_GAUGE)
- vt.gauge = (gauge_t) strtod (buffer, &endptr);
- else if (type == DS_TYPE_DERIVE)
- vt.derive = (derive_t) strtoll (buffer, &endptr, /* base = */ 0);
- else if (type == DS_TYPE_ABSOLUTE)
- vt.absolute = (absolute_t) strtoull (buffer, &endptr, /* base = */ 0);
- else
- {
- ERROR ("curl_json plugin: Unknown data source type: \"%s\"", key->type);
- return (CJ_CB_ABORT);
- }
-
- if ((endptr == &buffer[0]) || (errno != 0))
+ status = parse_value (buffer, &vt, type);
+ if (status != 0)
{
- NOTICE ("curl_json plugin: Overflow while parsing number. "
- "Ignoring this value.");
+ NOTICE ("curl_json plugin: Unable to parse number: \"%s\"", buffer);
return (CJ_CB_CONTINUE);
}
yajl_len_t len)
{
cj_t *db = (cj_t *)ctx;
- c_avl_tree_t *tree;
- char *ptr;
-
- if (db->depth != 1) /* e.g. _all_dbs */
- return (CJ_CB_CONTINUE);
+ char str[len + 1];
- cj_cb_map_key (ctx, val, len); /* same logic */
+ /* Create a null-terminated version of the string. */
+ memcpy (str, val, len);
+ str[len] = 0;
- tree = db->state[db->depth].tree;
+ /* No configuration for this string -> simply return. */
+ if (db->state[db->depth].key == NULL)
+ return (CJ_CB_CONTINUE);
- if ((tree != NULL) && (ptr = rindex (db->url, '/')))
+ if (!CJ_IS_KEY (db->state[db->depth].key))
{
- char url[PATH_MAX];
- CURL *curl;
-
- /* url =~ s,[^/]+$,$name, */
- len = (ptr - db->url) + 1;
- ptr = url;
- sstrncpy (ptr, db->url, sizeof (url));
- sstrncpy (ptr + len, db->state[db->depth].name, sizeof (url) - len);
-
- curl = curl_easy_duphandle (db->curl);
- curl_easy_setopt (curl, CURLOPT_URL, url);
- cj_curl_perform (db, curl);
- curl_easy_cleanup (curl);
+ NOTICE ("curl_json plugin: Found string \"%s\", but the configuration "
+ "expects a map here.", str);
+ return (CJ_CB_CONTINUE);
}
- return (CJ_CB_CONTINUE);
-}
+
+ /* Handle the string as if it was a number. */
+ return (cj_cb_number (ctx, (const char *) val, len));
+} /* int cj_cb_string */
static int cj_cb_start (void *ctx)
{
/* Configuration handling functions {{{ */
-static int cj_config_add_string (const char *name, char **dest, /* {{{ */
- oconfig_item_t *ci)
-{
- if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("curl_json plugin: `%s' needs exactly one string argument.", name);
- return (-1);
- }
-
- sfree (*dest);
- *dest = strdup (ci->values[0].value.string);
- if (*dest == NULL)
- return (-1);
-
- return (0);
-} /* }}} int cj_config_add_string */
-
-static int cj_config_set_boolean (const char *name, int *dest, /* {{{ */
- oconfig_item_t *ci)
-{
- if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN))
- {
- WARNING ("curl_json plugin: `%s' needs exactly one boolean argument.", name);
- return (-1);
- }
-
- *dest = ci->values[0].value.boolean ? 1 : 0;
-
- return (0);
-} /* }}} int cj_config_set_boolean */
-
static c_avl_tree_t *cj_avl_create(void)
{
return c_avl_create ((int (*) (const void *, const void *)) strcmp);
if (strcasecmp ("Key", ci->key) == 0)
{
- status = cj_config_add_string ("Key", &key->path, ci);
+ status = cf_util_get_string (ci, &key->path);
if (status != 0)
{
sfree (key);
oconfig_item_t *child = ci->children + i;
if (strcasecmp ("Type", child->key) == 0)
- status = cj_config_add_string ("Type", &key->type, child);
+ status = cf_util_get_string (child, &key->type);
else if (strcasecmp ("Instance", child->key) == 0)
- status = cj_config_add_string ("Instance", &key->instance, child);
+ status = cf_util_get_string (child, &key->instance);
else
{
WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key);
curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials);
}
- curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, db->verify_peer);
+ curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, (int) db->verify_peer);
curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYHOST,
- db->verify_host ? 2 : 0);
+ (int) (db->verify_host ? 2 : 0));
if (db->cacert != NULL)
curl_easy_setopt (db->curl, CURLOPT_CAINFO, db->cacert);
if (strcasecmp ("URL", ci->key) == 0)
{
- status = cj_config_add_string ("URL", &db->url, ci);
+ status = cf_util_get_string (ci, &db->url);
if (status != 0)
{
sfree (db);
oconfig_item_t *child = ci->children + i;
if (strcasecmp ("Instance", child->key) == 0)
- status = cj_config_add_string ("Instance", &db->instance, child);
+ status = cf_util_get_string (child, &db->instance);
else if (strcasecmp ("Host", child->key) == 0)
- status = cj_config_add_string ("Host", &db->host, child);
+ status = cf_util_get_string (child, &db->host);
else if (strcasecmp ("User", child->key) == 0)
- status = cj_config_add_string ("User", &db->user, child);
+ status = cf_util_get_string (child, &db->user);
else if (strcasecmp ("Password", child->key) == 0)
- status = cj_config_add_string ("Password", &db->pass, child);
+ status = cf_util_get_string (child, &db->pass);
else if (strcasecmp ("VerifyPeer", child->key) == 0)
- status = cj_config_set_boolean ("VerifyPeer", &db->verify_peer, child);
+ status = cf_util_get_boolean (child, &db->verify_peer);
else if (strcasecmp ("VerifyHost", child->key) == 0)
- status = cj_config_set_boolean ("VerifyHost", &db->verify_host, child);
+ status = cf_util_get_boolean (child, &db->verify_host);
else if (strcasecmp ("CACert", child->key) == 0)
- status = cj_config_add_string ("CACert", &db->cacert, child);
+ status = cf_util_get_string (child, &db->cacert);
else if (strcasecmp ("Key", child->key) == 0)
status = cj_config_add_key (db, child);
else
host = db->host;
if (key->instance == NULL)
- ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s",
- db->state[db->depth-1].name, db->state[db->depth].name);
+ {
+ if ((db->depth == 0) || (strcmp ("", db->state[db->depth-1].name) == 0))
+ sstrncpy (vl.type_instance, db->state[db->depth].name, sizeof (vl.type_instance));
+ else
+ ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s",
+ db->state[db->depth-1].name, db->state[db->depth].name);
+ }
else
sstrncpy (vl.type_instance, key->instance, sizeof (vl.type_instance));
return (-1);
}
- status = curl_easy_perform (curl);
+ url = NULL;
+ curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
- yajl_free (db->yajl);
- db->yajl = yprev;
+ status = curl_easy_perform (curl);
+ if (status != 0)
+ {
+ ERROR ("curl_json plugin: curl_easy_perform failed with status %i: %s (%s)",
+ status, db->curl_errbuf, (url != NULL) ? url : "<null>");
+ yajl_free (db->yajl);
+ db->yajl = yprev;
+ return (-1);
+ }
- curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rc);
/* The response code is zero if a non-HTTP transport was used. */
if ((rc != 0) && (rc != 200))
{
- ERROR ("curl_json plugin: curl_easy_perform failed with response code %ld (%s)",
- rc, url);
+ ERROR ("curl_json plugin: curl_easy_perform failed with "
+ "response code %ld (%s)", rc, url);
+ yajl_free (db->yajl);
+ db->yajl = yprev;
return (-1);
}
- if (status != 0)
+#if HAVE_YAJL_V2
+ status = yajl_complete_parse(db->yajl);
+#else
+ status = yajl_parse_complete(db->yajl);
+#endif
+ if (status != yajl_status_ok)
{
- ERROR ("curl_json plugin: curl_easy_perform failed with status %i: %s (%s)",
- status, db->curl_errbuf, url);
+ unsigned char *errmsg;
+
+ errmsg = yajl_get_error (db->yajl, /* verbose = */ 0,
+ /* jsonText = */ NULL, /* jsonTextLen = */ 0);
+ ERROR ("curl_json plugin: yajl_parse_complete failed: %s",
+ (char *) errmsg);
+ yajl_free_error (db->yajl, errmsg);
+ yajl_free (db->yajl);
+ db->yajl = yprev;
return (-1);
}
+ yajl_free (db->yajl);
+ db->yajl = yprev;
return (0);
} /* }}} int cj_curl_perform */