Description
I have a number of custom Python plugins that output data fine with the CSV writer and with write_http
using Format "Command"
. I'm using Collectd 5.4.1 in debug mode. When I change the formatting to JSON, the write_http plugin breaks with:
plugin: plugin_write: Writing values via write_http.
format_json: values_to_json: buffer = [100];
format_json: dstypes_to_json: buffer = ["gauge"];
format_json: dsnames_to_json: buffer = ["value"];
Filter subsystem: Built-in target `write': Dispatching value to all write plugins failed with status -1.
If this meta_data_to_json()
block of code doesn't run, i.e. I comment it out, then the plugin runs. Data is written and, when the 4K buffer is full, sent over the wire. For this testing I'm using netcat on localhost and I see the data POSTed and collectd syslog log entries like:
format_json: dsnames_to_json: buffer = ["value"];
format_json: value_list_to_json: buffer = {......}
write_http plugin: localhost:8080 buffer 735/4096 (17.9443%)
...
write_http plugin: wh_flush_nolock: timeout = 0.000; send_buffer_fill = 3920;
In utils_format_json.c, vl->meta
is not NULL at line 363 and inside the function at line 250, keys_num
is zero, which triggers this if condition that returns an error. I'm not setting any metadata—didn't even know it was a feature—so the problem might be with the way the Python plugin system sets up the initial meta attribute. Or it might be simply that the JSON parser can't handle an empty dictionary (e.g. {}
).
Here's a hack and a distilled sample of Python plugin code:
import collectd
val = collectd.Values(
plugin="test",
type="gauge",
type_instance="metric1",
meta={'0': True}, # HACK with this dummy dict in place JSON parsing works
value=100)
val.dispatch()