collectd/collectd — pull request #154 by ymettier (2012-10-11 12:41:41+00:00)
Title: New json-rpc over http plugin

Hello,

This is a new plugin called jsonrpc.
Its goal is to implement a JSON-RPC over HTTP server.

I developped it for perfwatcher, but I think that some will want to extend it. So I tried to make it modular.

It comes with 3 source files (and their headers) for modularity :
* jsonrpc.c : the core (including the http server and the json-rpc parser)
* jsonrpc_cb_base.c : some generic methods
* jsonrpc_cb_perfwatcher.c : some methods that I think specific to perfwatcher

At compile time, you can of course enable or disable this plugin. You can also compile only the "base" or the "perfwatcher" methods, or both, or none (who wants none ?)

Because I did not want to reimplement a http server, I tried to find a library and I chose libmicrohttpd (http://www.gnu.org/software/libmicrohttpd/). Same thing with the json parser : I chose json-c (http://oss.metaparadigm.com/json-c/ ; version 0.10 or newer needed because of a bug in 0.9).

Currently implemented methods :
* from "base" :
* _listval_ : just like listval in unixsocks
* _getval_ : would be just like getval in unixsocks, but also supports multiple types in one request
* from "perfwatcher" :
* _pw_get_status_ : specify a timeout and a list of servers and, for each server, it will answer you if the server is up or down or unknown (tests the last update date and compare it to now minus the timeout)
* _pw_get_metric_ : specify a list of servers and it will return the aggregated list of plugin-instance/type-instance of those servers.

This is modular. If you want to implement a generic method (like the currently missing "putval"), append it to jsonrpc_cb_base.c. If, like me with perfwatcher, you have specific needs, create your jsonrpc_cb_xxx.c/h files like I did with jsonrpc_cb_base and jsonrpc_cb_perfwatcher.

Here is an example. I would like to send the following data to know the cpu-0/cpu-idle and load/local of my localhost collectd :

{
"jsonrpc": "2.0",
"method": "getval",
"params": [
"localhost/cpu-0/cpu-idle",
"localhost/load/load"
],
"id": 3
}

Using curl (jsonrpc is running the server on port 8080) :

$ curl --data '{ "jsonrpc": "2.0", "method": "getval", "params": [ "localhost/cpu-0/cpu-idle", "localhost/load/load" ], "id": 3 }' http://localhost:8080/

Here is the (indented) answer from jsonrpc plugin :

{
"jsonrpc": "2.0",
"result": {
"localhost\/cpu-0\/cpu-idle": { "value": 9.149981 },
"localhost\/load\/load": { "shortterm": 15.860000, "midterm": 16.460000, "longterm": 16.460000 }
},
"id": 3
}

WARNING : the http server currently implements no authentication mecanism. Do not use it if your data are confidential !

TODO :
* implement some authentication mecanism
* improve the local cache of data (currenly no read access is allowed when the cache is refreshed) : would maybe solve a latency problem
* improve the documentation of the methods

Well, have fun with jsonrpc plugin !

Regards,
Yves