utils_format_json: serialize nan and inf as null, as per JSON spec
authorChris Buben <cbuben@eventlogic.com>
Thu, 4 Feb 2010 08:52:30 +0000 (00:52 -0800)
committerFlorian Forster <octo@huhu.verplant.org>
Thu, 4 Feb 2010 09:20:24 +0000 (10:20 +0100)
I'm deserializing JSON output from the write_http plugin using ruby-yajl.
yajl was puking on the literal value nan encoded in the output.

[
    {
        "plugin": "memcached",
        "interval": 10,
        "host": "myhost",
        "values": [
            nan,
            5
        ],
        "time": 1265239180,
        "plugin_instance": "",
        "type_instance": "",
        "type": "ps_count"
    }
]

After some research, ECMA-262 15.12.3 says nan and infinite numbers
aren't representable in JSON and should be serialized as the string
null. I figure any strictly-compliant JSON parser will fail on parsing
JSON data containing nans as emitted by collectd's utils_format_json
routines.

This patch makes collectd's JSON output compliant in the case of
infinite or nan gauge values.

Signed-off-by: Florian Forster <octo@huhu.verplant.org>
src/utils_format_json.c

index a919316..dda2234 100644 (file)
@@ -98,7 +98,12 @@ static int values_to_json (char *buffer, size_t buffer_size, /* {{{ */
       BUFFER_ADD (",");
 
     if (ds->ds[i].type == DS_TYPE_GAUGE)
-      BUFFER_ADD ("%g", vl->values[i].gauge);
+    {
+      if(isnan(vl->values[i].gauge) || isinf(vl->values[i].gauge))
+        BUFFER_ADD ("null");
+      else
+        BUFFER_ADD ("%g", vl->values[i].gauge);
+    }
     else if (ds->ds[i].type == DS_TYPE_COUNTER)
       BUFFER_ADD ("%llu", vl->values[i].counter);
     else if (ds->ds[i].type == DS_TYPE_DERIVE)