Un connecteur de flux dédié à vos besoins
![Stacks Image 701495](files/stacks-image-5e5c3bc.gif)
Centreon fourni un nouveau connecteur pour son broker. Celui-ci permet de développer son propre connecteur pour interfacer Centreon avec des produits tiers non prévus dans la liste des connecteurs Broker. Avec un peu de code LUA, vous aurez la possibilité d'envoyer des données de supervision à une application. Le but de cet article, n'est pas de vous faire un cours sur LUA, je n'en ai pas la prétention. Par contre, je vais vous présenter, pas à pas, la construction d'un connecteur très simple. Nous prendrons un exemple qui m'avais été demandé, il y a quelque mois, la possibilité de récupérer une ou plusieurs métriques d'un hôte sélectionné.
Premier programme initial
Nous commencerons par le minimum vital, un programme affichant les événements dans un fichier de log. Pour cela, nous allons configurer le connecteur Stream du Broker. Sélectionnez Configuration —> Pollers —> Broker configuration. Cliquez sur la configuration broker central-broker-master et sélectionnez l'onglet Output. Pour ajouter le connecteur, sélectionnez Stream connector et cliquez sur Add.
![Stacks Image 701346](files/stacks-image-ab3ca68-762x272.png)
Configuration du connecteur
Pour ce premier test, nous ajouterons le nom test1 et le fichier contenant notre programme lua /usr/local/src/test1.lua. Il faudra veiller à ce que l'utilisateur centreon-broker puisse lire le fichier. Celui-ci devra aussi être exécutable. N'oubliez pas d'appliquer la configuration. Voici donc le premier programme.
function init(conf)
broker_log:set_parameters(3, "/var/log/centreon-broker/test1_connecteur.log")
end
function write(d)
for k,v in pairs(d) do
broker_log:info(3, k .. " => " .. tostring(v))
end
return true
end
Le programme comporte deux fonctions obligatoires init et write. La première va initialiser le fichier de log. Assurez-vous aussi que le broker peut créer et écrire dans le dossier cible. La deuxième fonction vous permettra de récupérer les informations du moteur de supervision selon la documentation officielle de Centreon. Dans notre premier cas, nous récupérons tous les événements et nous les envoyons dans le fichier de log.
Attention, pour prendre en compte ce connecteur ainsi que toute autre modification de celui-ci, il faudra redémarrer le broker.
Attention, pour prendre en compte ce connecteur ainsi que toute autre modification de celui-ci, il faudra redémarrer le broker.
service cbd restart
Pour vérifier les éventuelles erreurs, n'hésitez pas à lire le fichier de log de la configuration principale du broker.
tailf /var/log/centreon-broker/central-master-broker.log
Voici un exemple d'erreur que vous pourriez avoir
[1519481045] error: lua: '/usr/local/src/test2.lua' could not be loaded: /usr/local/src/test2.lua:5: 'do' expected near 'broker_log'
Et enfin, voici un extrait du fichier de log créé avec notre connecteur.
tailf /var/log/centreon-broker/test1_connecteur.log
sam. 24 févr. 2018 17:53:41 CET: INFO: service_id => 7
sam. 24 févr. 2018 17:53:41 CET: INFO: type => 196613
sam. 24 févr. 2018 17:53:41 CET: INFO: category => 3
sam. 24 févr. 2018 17:53:41 CET: INFO: host_id => 5
sam. 24 févr. 2018 17:53:41 CET: INFO: index_id => 1
sam. 24 févr. 2018 17:53:41 CET: INFO: element => 5
sam. 24 févr. 2018 17:53:41 CET: INFO: service_id => 8
sam. 24 févr. 2018 17:53:41 CET: INFO: type => 196613
Deuxième programme, filtrer les métriques
Maintenant, il est temps de filtrer les événements pour ne récupérer que les données liées aux métriques. Nous créons un deuxième programme nommé test2. Configurez votre broker comme précédemment et appliquez la configuration.
![Stacks Image 34361](files/stacks-image-fa3572b.png)
Configuration du connecteur
Ce programme comporte une condition pour filtrer nos données. Nous utiliserons deux paramètres pour cela : category et element. Le premier paramètre correspond au type d'événement défini dans le tableau de la page du protocole BBDO. Le deuxième correspond à un élément précis par rapport au type d'événement. Voici un tableau regroupant toutes les catégories et les éléments associés.
![Stacks Image 701528](files/stacks-image-6caafae.jpg)
Liste des catégories et éléments
Dans notre exemple, nous choisirons le type de catégorie storage et plus précisément le type élément metric.
function init(conf)
broker_log:set_parameters(3, "/var/log/centreon-broker/test2_connecteur.log")
end
function write(d)
if d.category == 3 and d.element == 1 then
for i,v in pairs(d) do
broker_log:info(3, i .. " => " .. tostring(v))
end
end
return true
end
N'oubliez pas de redémarrer le broker pour prendre en compte les nouveaux paramètres. Voici le résultat :
tailf /var/log/centreon-broker/test2_connecteur.log
sam. 24 févr. 2018 18:05:17 CET: INFO: service_id => 7
sam. 24 févr. 2018 18:05:17 CET: INFO: type => 196609
sam. 24 févr. 2018 18:05:17 CET: INFO: ctime => 1519481738
sam. 24 févr. 2018 18:05:17 CET: INFO: host_id => 5
sam. 24 févr. 2018 18:05:17 CET: INFO: element => 1
sam. 24 févr. 2018 18:05:17 CET: INFO: is_for_rebuild => false
sam. 24 févr. 2018 18:05:17 CET: INFO: metric_id => 1
sam. 24 févr. 2018 18:05:17 CET: INFO: name => rta
sam. 24 févr. 2018 18:05:17 CET: INFO: category => 3
sam. 24 févr. 2018 18:05:17 CET: INFO: interval => 60
sam. 24 févr. 2018 18:05:17 CET: INFO: rrd_len => 15552000
sam. 24 févr. 2018 18:05:17 CET: INFO: value => 0.012
sam. 24 févr. 2018 18:05:17 CET: INFO: value_type => 0
Les données sont limitées aux métriques, les valeurs qui nous intéressent sont le nom de la métrique (name), sa date (ctime), sa valeur (value) et son appartenance à un service (service_id) et à un hôte (host_id)
Troisième programme, fonction get_hostname
Il peut être intéressant de récupérer le nom de l'hôte grâce à l'ID host_id. Centreon pense à nous, en nous fournissant une fonction bien pratique get_hostname. Celle-ci nous permettra de récupérer le nom de l'hôte. Commençons par modifier notre broker.
![Stacks Image 701413](files/stacks-image-0c66d2b.png)
Configuration du connecteur
Le programme comporte la fonction get_hostname() et permet d'initialiser la variable locale hostname. Il est important de vérifier la validité de cette variable pour éviter un message d'erreur si celle-ci est égal à nil. Important, vous devrez peut-être recharger le cache NEB en redémarrant le moteur engine si vous n'avez pas le résultat escompté.
function init(conf)
broker_log:set_parameters(3, "/var/log/centreon-broker/test3_connecteur.log")
end
function write(d)
if d.category == 3 and d.element == 1 then
local hostname = broker_cache:get_hostname(d.host_id)
if hostname then
broker_log:info(3,"host name " .. hostname .. " corresponds to host id " .. d.host_id)
else
broker_log:info(3,"pas de hostname ")
end
for i,v in pairs(d) do
broker_log:info(3, i .. " => " .. tostring(v))
end
end
return true
end
N'oubliez pas de redémarrer le broker pour prendre en compte les nouveaux paramètres. Voici le résultat :
tailf /var/log/centreon-broker/test3_connecteur.log
sam. 24 févr. 2018 22:39:20 CET: INFO: host name Central-server corresponds to host id 5
sam. 24 févr. 2018 22:39:20 CET: INFO: service_id => 99
sam. 24 févr. 2018 22:39:20 CET: INFO: type => 196609
sam. 24 févr. 2018 22:39:20 CET: INFO: ctime => 1519508356
sam. 24 févr. 2018 22:39:20 CET: INFO: host_id => 5
sam. 24 févr. 2018 22:39:20 CET: INFO: element => 1
sam. 24 févr. 2018 22:39:20 CET: INFO: is_for_rebuild => false
sam. 24 févr. 2018 22:39:20 CET: INFO: metric_id => 14
sam. 24 févr. 2018 22:39:20 CET: INFO: name => load15
sam. 24 févr. 2018 22:39:20 CET: INFO: category => 3
sam. 24 févr. 2018 22:39:20 CET: INFO: interval => 300
sam. 24 févr. 2018 22:39:20 CET: INFO: rrd_len => 15552000
sam. 24 févr. 2018 22:39:20 CET: INFO: value => 0.02
sam. 24 févr. 2018 22:39:20 CET: INFO: value_type => 0
Quatrième programme, utilisation de paramètres
Pour obtenir le programme final, nous aurons besoin de renseigner l'ID du service pour exporter ses métriques. Nous utiliserons la propriété LUA parameters fournis dans la configuration du connecteur. Modifions notre broker en ajoutant un paramètre de type Number.
![Stacks Image 34546](files/stacks-image-c677ecf-802x346.png)
Configuration du connecteur
La valeur du paramètre correspond à un ID d'un service. Pour le trouver ? très simple, allez dans la page de configuration des services et survolez le nom d'un service. Le lien contenant l'ID du service s'affichera en bas de la fenêtre du navigateur comme le montre cet exemple.
![Stacks Image 701422](files/stacks-image-c26e433-500x66.png)
Récupérez l'ID d'un service
Ce programme comporte une nouvelle fonctionnalité. Dans la fonction init(), nous initialiserons la variable NumService avec le paramètre défini dans la configuration du broker. Ensuite, nous nous servirons de cette variable pour filtrer sur ce service et récupérer les informations de la métrique.
function init(conf)
NumService = conf['NumService']
broker_log:set_parameters(3, "/var/log/centreon-broker/test4_connecteur.log")
end
function write(d)
if d.category == 3 and d.service_id == NumService then
local timeunix, libelle, valeur
for i,v in pairs(d) do
if i == "value" then
valeur = v
end
if i == "ctime" then
timeunix = v
end
if i == "name" then
libelle = v
end
end
broker_log:info(3, "metric ".. " => " .. tostring(timeunix) .. ";" .. tostring(libelle) .. ";" .. tostring(valeur))
end
return true
end
N'oubliez pas de redémarrer le broker pour prendre en compte les nouveaux paramètres. Voici le résultat :
tailf /var/log/centreon-broker/test4_connecteur.log
sam. 24 févr. 2018 22:41:33 CET: INFO: metric => 1519507756;load1;0.14
sam. 24 févr. 2018 22:41:33 CET: INFO: metric => 1519507756;load5;0.09
sam. 24 févr. 2018 22:41:33 CET: INFO: metric => 1519507756;load15;0.02
sam. 24 févr. 2018 22:41:33 CET: INFO: metric => 1519508056;load1;0.08
sam. 24 févr. 2018 22:41:33 CET: INFO: metric => 1519508056;load5;0.07
sam. 24 févr. 2018 22:41:33 CET: INFO: metric => 1519508056;load15;0.02
Cinquième programme, utilisation de la fonction filtre
Une autre fonction optionnelle filter() permet de filtrer les données à traiter par la fonction write(), comme le montre ce programme.
function init(conf)
NumService = conf['NumService']
broker_log:set_parameters(3, "/var/log/centreon-broker/test5_connecteur.log")
end
function filter(category, element)
return category == 3 and element == 1
end
function write(d)
if d.category == 3 and d.service_id == NumService then
local timeunix, libelle, valeur
for i,v in pairs(d) do
if i == "value" then
valeur = v
end
if i == "ctime" then
timeunix = v
end
if i == "name" then
libelle = v
end
end
broker_log:info(3, "metric ".. " => " .. tostring(timeunix) .. ";" .. tostring(libelle) .. ";" .. tostring(valeur))
end
return true
end
Sixième programme, création d'un fichier
Continuons avec notre projet, nous avons besoin de créer un fichier pour stocker nos métriques. Nous utiliserons les fonctions LUA avec un deuxième paramètre. Configurez le broker avec un deuxième paramètre de type String.
![Stacks Image 701443](files/stacks-image-95adf55-822x430.png)
Configuration du connecteur
Ce programme va gérer la création d'un fichier texte en mode ajout. Ne pas oubliez les droits d'écriture du fichier pour le dossier cible.
function init(conf)
NumService = conf['NumService']
FileOutput = conf['FileOuput']
broker_log:set_parameters(3, "/var/log/centreon-broker/test6_connecteur.log")
end
function filter(category, element)
return category == 3 and element == 1
end
function write(d)
if d.category == 3 and d.service_id == NumService then
local timeunix, libelle, valeur
for i,v in pairs(d) do
if i == "value" then
valeur = v
end
if i == "ctime" then
timeunix = v
end
if i == "name" then
libelle = v
end
end
local file = io.open(FileOutput, 'a')
file:write(tostring(timeunix) .. ";" .. tostring(libelle) .. ";" .. tostring(valeur) .. "\n")
file:close()
broker_log:info(3, "metric ".. " => " .. tostring(timeunix) .. ";" .. tostring(libelle) .. ";" .. tostring(valeur))
end
return true
end
Le programme va créer un fichier test6_output.txt contenant les donnes métriques. N'oubliez pas de redémarrer le broker pour prendre en compte les nouveaux paramètres. Voici le résultat :
tailf /var/log/centreon-broker/test6_output.txt
1519572154;load1;0
1519572154;load5;0
1519572154;load15;0.19
1519572454;load1;0
1519572454;load5;0
1519572454;load15;0.13
Septième programme, le programme final
Nous terminerons par ce dernier programme. En effet, pour pouvoir utiliser les données avec un tableur comme Excel, il serait judicieux de mettre les valeurs sur une même ligne pour chaque vérification. Nous utiliserons deux variables pour borner les métriques. Les paramètres First et End serviront à encadrer les métriques lorsqu'il y a plus d'une métrique. Pour un service utilisant une seule métrique, il faudra initialiser le paramètre First à unique. Voici les deux configurations possibles :
Service avec une métrique
C'est le cas le plus simple. Il suffira d'ajouter un paramètre First de type String et de l'initialiser à unique.
![Stacks Image 701466](files/stacks-image-4879692-834x530.png)
Configuration du connecteur
Service avec plusieurs métriques
Pour le cas à plusieurs métriques, nous utiliserons la page de détails d'un service et regarder le champ Performance Data. Prendre la première métrique et l'initialiser dans le paramètre First et la dernière métrique et l'initialiser dans le paramètre End.
![Stacks Image 701458](files/stacks-image-f2f4f45-732x248.png)
Vérification des métriques
![Stacks Image 701475](files/stacks-image-5ac8172-806x622.png)
Configuration du connecteur
Le programme
Voici le programme final. Celui-ci va créer un fichier de type CSV pour une utilisation ultérieure avec un tableur par exemple.
function init(conf)
NumService = conf['NumService']
FileOutput = conf['FileOuput']
MetricFirst = conf['First']
MetricEnd = conf['End']
broker_log:set_parameters(3, "/var/log/centreon-broker/test7_connecteur.log")
end
function filter(category, element)
return category == 3 and element == 1
end
function write(d)
if d.category == 3 and d.service_id == NumService then
local timeunix, libelle, valeur
for i,v in pairs(d) do
if i == "value" then
valeur = v
end
if i == "ctime" then
timeunix = v
end
if i == "name" then
libelle = v
end
end
local file = io.open(FileOutput, 'a')
if MetricFirst == "unique" then
file:write(tostring(timeunix) .. ";" .. tostring(valeur) .. "\n" )
elseif libelle == MetricFirst then
file:write(tostring(timeunix) .. ";" .. tostring(valeur) )
elseif libelle == MetricEnd then
file:write(";" .. tostring(valeur) .. "\n")
else
file:write(";" .. tostring(valeur) )
end
file:close()
broker_log:info(3, "metric ".. " => " .. tostring(timeunix) .. ";" .. tostring(libelle) .. ";" .. tostring(valeur))
end
return true
end
Pour une seule métrique, le programme va créer un fichier test7a_output.txt contenant les donnes métriques. N'oubliez pas de redémarrer le broker pour prendre en compte les nouveaux paramètres. Voici le résultat :
tailf /var/log/centreon-broker/test7a_output.txt
1519577245;14
1519577574;15
1519578474;14
1519577245;14
1519577245;14
1519577574;15
1519578474;14
1519578474;14
1519578649;15
1519578649;15
1519578682;15
Pour plusieurs métriques, le programme va créer un fichier test7b_output.txt contenant les donnes métriques. Voici le résultat :
tailf /var/log/centreon-broker/test7b_output.txt
1519579282;0.01;0;0.038;0.002
1519579342;0.011;0;0.04;0.004
1519579402;0.011;0;0.043;0.003
1519579462;0.012;0;0.042;0.004
1519579522;0.01;0;0.038;0.002
1519579582;0.009;0;0.032;0.002
1519579642;0.009;0;0.037;0.002
1519579702;0.012;0;0.047;0.003
1519579762;0.01;0;0.038;0.003
1519579822;0.01;0;0.037;0.002
Il sera possible de récupérer le fichier pour l'utiliser avec un tableur comme ceci. Astuce pour récupérer la date d'un timestamp Unix (cellule/86400)+25569 et formater la cellule au format personnalisé jj/mm/aaaa hh:mm
![Stacks Image 701523](files/stacks-image-b61658c-1174x654.png)
Configuration du connecteur
Il est possible d'améliorer ce programme avec une connexion TCP pour envoyer les données sur une autre machine, par exemple. Ce sera peut-être l'occasion de réaliser un autre article…