diff --git a/api/api-doc/collectd.json b/api/api-doc/collectd.json new file mode 100644 index 0000000000..88f92d3f48 --- /dev/null +++ b/api/api-doc/collectd.json @@ -0,0 +1,118 @@ +{ + "apiVersion":"0.0.1", + "swaggerVersion":"1.2", + "basePath":"{{Protocol}}://{{Host}}", + "resourcePath":"/collectd", + "produces":[ + "application/json" + ], + "apis":[ + { + "path":"/collectd/{pluginid}", + "operations":[ + { + "method":"GET", + "summary":"Get a collectd value", + "type":"array", + "items":{ + "type":"collectd_value" + }, + "nickname":"get_collectd", + "produces":[ + "application/json" + ], + "parameters":[ + { + "name":"pluginid", + "description":"The plugin ID", + "required":true, + "allowMultiple":false, + "type":"string", + "paramType":"path" + }, + { + "name":"instance", + "description":"The plugin instance", + "required":false, + "allowMultiple":false, + "type":"string", + "paramType":"query" + }, + { + "name":"type", + "description":"The plugin type", + "required":true, + "allowMultiple":false, + "type":"string", + "paramType":"query" + }, + { + "name":"type_instance", + "description":"The plugin type instance", + "required":false, + "allowMultiple":false, + "type":"string", + "paramType":"query" + } + ] + } + ] + }, + { + "path":"/collectd/", + "operations":[ + { + "method":"GET", + "summary":"Get a collectd value", + "type":"array", + "items":{ + "type":"type_instance_id" + }, + "nickname":"get_collectd_items", + "produces":[ + "application/json" + ], + "parameters":[ + ] + } + ] + } + ], + "models":{ + "type_instance_id":{ + "id":"type_instance_id", + "description":"A type instance ID", + "properties":{ + "plugin":{ + "type":"string", + "description":"The plugin ID" + }, + "plugin_instance":{ + "type":"string", + "description":"The plugin instance" + }, + "type":{ + "type":"string", + "description":"The plugin type" + }, + "type_instance":{ + "type":"string", + "description":"The plugin type instance" + } + } + }, + "collectd_value":{ + "id":"collectd_value", + "description":"Holds a collectd value", + "properties":{ + "values":{ + "description":"An array of values", + "type":"array", + "items":{ + "type":"double" + } + } + } + } + } +} \ No newline at end of file diff --git a/api/api.cc b/api/api.cc index caea8695f9..9577d63372 100644 --- a/api/api.cc +++ b/api/api.cc @@ -14,7 +14,7 @@ #include "messaging_service.hh" #include "storage_proxy.hh" #include "cache_service.hh" - +#include "collectd.hh" namespace api { future<> set_server(http_context& ctx) { @@ -52,7 +52,9 @@ future<> set_server(http_context& ctx) { rb->register_function(r, "cache_service", "The cache service API"); set_cache_service(ctx,r); - + rb->register_function(r, "collectd", + "The collectd API"); + set_collectd(ctx, r); }); } diff --git a/api/collectd.cc b/api/collectd.cc new file mode 100644 index 0000000000..8032dd1b73 --- /dev/null +++ b/api/collectd.cc @@ -0,0 +1,73 @@ +/* + * Copyright 2015 Cloudius Systems + */ + +#include "collectd.hh" +#include "api/api-doc/collectd.json.hh" +#include "core/scollectd.hh" +#include "core/scollectd_api.hh" +#include "endian.h" +#include + +namespace api { + +using namespace scollectd; +namespace cd = httpd::collectd_json; + +static auto transformer(const std::vector& values) { + cd::collectd_value collected_value; + for (auto v: values) { + switch (v._type) { + case scollectd::data_type::GAUGE: + collected_value.values.push(v.u._d); + break; + case scollectd::data_type::DERIVE: + collected_value.values.push(v.u._i); + break; + default: + collected_value.values.push(v.u._ui); + break; + } + } + return collected_value; +} + +void set_collectd(http_context& ctx, routes& r) { + cd::get_collectd.set(r, [&ctx](std::unique_ptr req) { + + auto id = make_shared(req->param["pluginid"], + req->get_query_param("instance"), req->get_query_param("type"), + req->get_query_param("type_instance")); + + + return do_with(std::vector(), [id] (auto& vec) { + vec.resize(smp::count); + return parallel_for_each(boost::irange(0u, smp::count), [&vec, id] (auto cpu) { + return smp::submit_to(cpu, [id = *id] { + return scollectd::get_collectd_value(id); + }).then([&vec, cpu] (auto res) { + vec[cpu] = transformer(res); + }); + }).then([&vec] { + return make_ready_future(vec); + }); + }); + }); + + cd::get_collectd_items.set(r, [](const_req req) { + std::vector res; + auto ids = scollectd::get_collectd_ids(); + for (auto i: ids) { + cd::type_instance_id id; + id.plugin = i.plugin(); + id.plugin_instance = i.plugin_instance(); + id.type = i.type(); + id.type_instance = i.type_instance(); + res.push_back(id); + } + return res; + }); +} + +} + diff --git a/api/collectd.hh b/api/collectd.hh new file mode 100644 index 0000000000..04841bdafd --- /dev/null +++ b/api/collectd.hh @@ -0,0 +1,18 @@ +/* + * Copyright 2015 Cloudius Systems + */ + +#ifndef API_COLLECTD_HH_ +#define API_COLLECTD_HH_ + +#include "api.hh" + +namespace api { + +void set_collectd(http_context& ctx, routes& r); + +} + + + +#endif /* API_COLLECTD_HH_ */ diff --git a/configure.py b/configure.py index 456f50c45d..2c4df86ecc 100755 --- a/configure.py +++ b/configure.py @@ -335,6 +335,8 @@ api = ['api/api.cc', 'api/storage_proxy.cc', 'api/api-doc/cache_service.json', 'api/cache_service.cc', + 'api/api-doc/collectd.json', + 'api/collectd.cc', ] boost_test_lib = [ diff --git a/core/scollectd.cc b/core/scollectd.cc index e80813a209..37d8e2daaf 100644 --- a/core/scollectd.cc +++ b/core/scollectd.cc @@ -488,9 +488,9 @@ boost::program_options::options_description get_options_description() { } std::vector get_collectd_value( - shared_ptr id) { + const scollectd::type_instance_id& id) { std::vector res_values; - auto raw_types = get_impl().get_values(*id); + auto raw_types = get_impl().get_values(id); if (raw_types == nullptr) { return res_values; } diff --git a/core/scollectd_api.hh b/core/scollectd_api.hh index 550c4fe8d4..2a46ad5e50 100644 --- a/core/scollectd_api.hh +++ b/core/scollectd_api.hh @@ -49,7 +49,7 @@ struct collectd_value { }; std::vector get_collectd_value( - shared_ptr id); + const scollectd::type_instance_id& id); std::vector get_collectd_ids();