Monitoring your Foxx applications
Note: this recipe is working with ArangoDB 2.5 Foxx
Problem
How to integrate a Foxx application into a monitoring system using the collectd curl_JSON
plugin.
Solution
Since Foxx native tongue is JSON, integrating it with the collectd curl_JSON plugin should be an easy exercise. We have a Foxx-Application which can receive Data and write it into a collection. We specify an easy input Model:
Model = Foxx.Model.extend({
schema: {
// Describe the attributes with Joi here
'_key': Joi.string(),
'value': Joi.number()
}
});
And use a simple Foxx-Route to inject data into our collection:
/** Creates a new FirstCollection
*
* Creates a new FirstCollection-Item. The information has to be in the
* requestBody.
*/
controller.post('/firstCollection', function (req, res) {
var firstCollection = req.params('firstCollection');
firstCollection.attributes.Date = Date.now();
res.json(FirstCollection_repo.save(firstCollection).forClient());
}).bodyParam('firstCollection', {
description: 'The FirstCollection you want to create',
type: FirstCollection
});
Which we may do using cURL
:
echo '{"value":1 ,"_key":"13"}' | \
curl -d @- http://localhost:8529/_db/_system/collectable_foxx/data/firstCollection/firstCollection
We’d expect the value to be in the range of 1 to 5. Maybe the source of this data is a web-poll or something similar.
We now add another Foxx-route which we want to link with collectd
:
/**
* we use a group-by construct to get the values:
*/
var db = require('org/arangodb').db;
var searchQuery = 'FOR x IN @@collection FILTER x.Date >= @until collect value=x.value with count into counter RETURN {[[CONCAT("choice", value)] : counter }';
controller.get('/firstCollection/lastSeconds/:nSeconds', function (req, res) {
var until = Date.now() - req.params('nSeconds') * 1000;
res.json(
db._query(searchQuery, {
'@collection': FirstCollection_repo.collection.name(),
'until': until
}).toArray()
);
}).pathParam('nSeconds', {
description: 'look up to n Seconds into the past',
type: joi.string().required()
});
We inspect the return document using curl and jq for nice formatting:
curl 'http://localhost:8529/_db/_system/collectable_foxx/data/firstCollection/firstCollection/lastSeconds/10' |jq "."
[
{
"1": 3
"3": 7
}
]
We have to design the return values in a way that collectd’s config syntax can simply grab it. This Route returns an object with flat key values where keys may range from 0 to 5. We create a simple collectd configuration in /etc/collectd/collectd.conf.d/foxx_simple.conf
that matches our API:
# Load the plug-in:
LoadPlugin curl_json
# we need to use our own types to generate individual names for our gauges:
TypesDB "/etc/collectd/collectd.conf.d/foxx_simple_types.db"
<Plugin curl_json>
# Adjust the URL so collectd can reach your arangod:
<URL "http://localhost:8529/_db/_system/collectable_foxx/data/firstCollection/firstCollection/lastSeconds/10">
# Set your authentication to Aardvark here:
# User "foo"
# Password "bar"
<Key "choice0">
Type "the_values"
</Key>
<Key "choice1">
Type "first_values"
</Key>
<Key "choice2">
Type "second_values"
</Key>
<Key "choice3">
Type "third_values"
</Key>
<Key "choice4">
Type "fourth_values"
</Key>
<Key "choice5">
Type "fifth_values"
</Key>
</URL>
</Plugin>
To get nice metric names, we specify our own types.db
file in /etc/collectd/collectd.conf.d/foxx_simple_types.db
:
the_values value:GAUGE:U:U
first_values value:GAUGE:U:U
second_values value:GAUGE:U:U
third_values value:GAUGE:U:U
fourth_values value:GAUGE:U:U
fifth_values value:GAUGE:U:U