Glossaire Keen
Chaque élément du langage des collecteurs, expliqué de la même façon : à quoi il sert, ce qu’il prend, ce qu’il rend, et quelques lignes pour le voir à l’œuvre.
Les constructions
Les instructions qui décident et qui répètent. Chacune ouvre un bloc entre accolades, même pour une seule instruction.
if / elseif / else
if exécute un bloc seulement quand sa condition est vraie. elseif ajoute une autre condition, jugée si les précédentes sont fausses. else prend ce qui reste. Les conditions sont jugées dans l’ordre, et un seul bloc s’exécute.
Écrivez elseif en un seul mot : else if est refusé. else n’a pas de paramètre : son bloc s’exécute quand aucune condition n’est vraie.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
if (condition) | une expression | oui | La condition du premier bloc. |
elseif (condition) | une expression | non (aucun), autant que nécessaire | Une condition de plus, jugée seulement si les précédentes sont fausses. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | L’instruction ne rend pas de valeur. Elle exécute le bloc retenu, ou aucun si aucune condition n’est vraie et qu’il n’y a pas de else. |
Exemples
Un seul cas : arrêter le collecteur quand le site répond autre chose que 200.
if ($answer['status'] != 200) {
fail('critical', 'Réponse en erreur', 'Code ' . $answer['status']);
} Plusieurs cas et un reste : ranger un temps de réponse dans une classe.
if ($answer['time'] > 2000) {
$class = 'lent';
} elseif ($answer['time'] > 500) {
$class = 'moyen';
} else {
$class = 'rapide';
} Une condition faite de plusieurs morceaux, qui ne lit le mot cherché que s’il y en a un.
if ($word != '' && !text.contains($answer['body'], $word)) {
fail('critical', 'Mot absent', 'La page ne contient pas le mot ' . $word . '.');
} Fautes signalées par le master
form_removed: Une forme retirée de PHP :else ifs’écritelseif, et? :s’écrit avec unif.
Les tableaux : array(…) et $a['clé']
Un tableau est une série de cases, chacune avec une étiquette, appelée sa clé. Il s’écrit array(…) : une liste (array('sshd', 'cron'), dont les clés sont 0, 1…), des paires (array('web' => 443)), ou les deux.
Une case se lit avec $a['clé'], ou $a[0], ou $a['clé'][1] pour un tableau dans un tableau. Elle s’écrit avec $a['clé'] = …. Écrire sous une clé qui n’existe pas crée ce qui manque au-dessus, mais la variable elle-même doit exister : créez d’abord le tableau avec $a = array();.
Un tableau est une valeur : l’affecter à une autre variable ou le passer à une fonction en fait une copie. Il garde l’ordre dans lequel ses clés sont entrées, et c’est cet ordre que suit foreach. Une clé est un texte ; un entier pris comme clé vaut son écriture décimale, si bien que $a[1] et $a['1'] désignent la même case.
Pour ajouter à une liste, utilisez list.add ; pour lire une case qui peut manquer, list.get.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
array(éléments) | zéro, un ou plusieurs éléments séparés par des virgules, chacun valeur ou clé => valeur | non (array() est un tableau vide) | Le contenu du tableau. Une virgule après le dernier élément est permise. |
$a[clé] | une expression : un texte ou un entier | oui | La case à lire ou à écrire. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le tableau | tableau | array(…) rend toujours un tableau. |
| Le contenu de la case | texte, nombre, booléen ou tableau | La lecture $a[clé] d’une case qui existe. |
| Rien | — | L’écriture $a[clé] = … est une instruction. |
| Un arrêt, état MISCONFIGURED | — | Lire une variable ou une clé qui n’existe pas, lire dans ce qui n’est pas un tableau, ou écrire dans ce qui n’est pas un tableau. |
Exemples
Une liste, puis des paires.
$services = array('sshd', 'cron');
$ports = array('web' => 443, 'ssh' => 22); Lire une case par son étiquette, puis par son rang.
$port = $ports['web'];
$first = $services[0]; Écrire une case dans un tableau qui contient un tableau : $read['eth0'] est créé au passage.
$read = array();
$read['eth0']['mtu'] = 1500; Fautes signalées par le master
form_removed: Une forme retirée :[1, 2]s’écritarray(1, 2), et$a[] = $xs’écrit$a = list.add($a, $x).variable_unassigned: Une variable lue sans être affectée plus haut dans sa portée. Écrire une case lit la variable : créez le tableau avant.
for
for répète un bloc en comptant. Entre ses parenthèses, trois parties séparées par des points-virgules : l’instruction de départ, la condition pour continuer, et l’instruction exécutée à la fin de chaque tour.
Chaque partie est d’une seule pièce : une affectation, une condition, une affectation. Pour avancer d’un cran, écrivez $i = $i + 1 : $i++ n’existe pas.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
| départ | une affectation, par exemple $i = 1 | oui | Exécutée une fois, avant le premier tour. |
| condition | une expression | oui | Jugée avant chaque tour. La boucle s’arrête quand elle est fausse. |
| pas | une affectation, par exemple $i = $i + 1 | oui | Exécutée à la fin de chaque tour. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | L’instruction ne rend pas de valeur. |
| Un arrêt, état MISCONFIGURED | — | Le plafond de tours est atteint. Le message nomme le plafond et la ligne. |
Exemples
Compter de 1 à 8.
$total = 0;
for ($i = 1; $i <= 8; $i = $i + 1) {
$total = $total + $i;
} Parcourir les lignes d’une sortie en sautant la première, qui est l’en-tête.
$lines = text.lines($df['output']);
for ($i = 1; $i < list.count($lines); $i = $i + 1) {
$f = text.words($lines[$i]);
} Fautes signalées par le master
form_removed: Une forme retirée :++,--et+=s’écrivent$i = $i + 1.
foreach
foreach parcourt un tableau case par case, dans l’ordre où ses clés sont entrées. À chaque tour, le contenu de la case est rangé dans une variable, et le bloc s’exécute.
Avec une seule variable, vous recevez le contenu. Avec deux, écrites $clé => $valeur, la première reçoit l’étiquette de la case et la seconde son contenu.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
expression | un tableau : une variable, un appel de fonction | oui | Ce qu’il faut parcourir. |
as $valeur | une variable | oui | Reçoit le contenu de la case à chaque tour. |
as $clé => $valeur | deux variables | non (une seule variable) | La première reçoit la clé de la case, la seconde son contenu. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | L’instruction ne rend pas de valeur. |
| Un arrêt, état MISCONFIGURED | — | Le plafond de tours est atteint. Le message nomme le plafond et la ligne. |
Exemples
Parcourir les lignes de la sortie d’une commande.
foreach (text.lines($stat['output']) as $line) {
$f = text.words($line);
} Prendre la clé et le contenu : rendre une valeur par interface, nommée par la clé.
foreach ($read as $name => $f) {
value('link', $f['operstate'], $name);
} while
while répète un bloc tant que sa condition est vraie. Elle est jugée avant chaque tour : si elle est fausse d’emblée, le bloc ne s’exécute jamais.
Contrairement à for, rien ne compte à votre place : c’est au bloc de changer ce que la condition regarde. Une boucle ne tourne jamais sans fin : le poller compte les tours et arrête le collecteur au plafond.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
condition | une expression | oui | Jugée avant chaque tour. La boucle s’arrête quand elle est fausse. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | L’instruction ne rend pas de valeur. |
| Un arrêt, état MISCONFIGURED | — | Le plafond de tours est atteint. Le message nomme le plafond et la ligne. |
Exemples
Retirer une unité à chaque tour jusqu’à zéro.
$left = 3;
while ($left > 0) {
$left = $left - 1;
} Attendre trois fois deux secondes.
$tries = 0;
while ($tries < 3) {
time.wait(2);
$tries = $tries + 1;
} Fautes signalées par le master
form_removed: Une forme retirée :dos’écritwhile.
break / continue
Deux mots pour s’échapper d’une boucle. break en sort tout de suite. continue abandonne le tour en cours et passe au suivant.
Ils ne valent que dans une boucle, et seulement pour celle qui les contient. Dans une fonction appelée depuis une boucle, ils sont une faute.
Paramètres
break et continue ne prennent aucun paramètre, pas même un nombre de boucles à quitter.
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Ni l’un ni l’autre ne rend de valeur. |
Exemples
Chercher une ligne dans un tableau, puis arrêter de chercher.
foreach ($interfaces as $row) {
if ($row['name'] == $wanted) {
$current = $row;
break;
}
} Passer à l’interface suivante tant qu’un débit n’est pas connu.
foreach ($read as $name => $f) {
$in = counter.rate('in', $f['statistics/rx_bytes'] * 8, $name);
if ($in == '') {
continue;
}
value('traffic-in', number.round($in), $name);
} Fautes signalées par le master
loop_word_outside_loop:breakoucontinuehors d’une boucle.
Les bases du langage
Ce qui sert dans presque toutes les lignes : les variables, les textes, les nombres, les comparaisons, les commentaires et vos propres fonctions.
Variables et valeurs
Une variable est une boîte qui porte un nom. Son nom commence par $, suivi de lettres minuscules, de chiffres ou de _, sans commencer par un chiffre. Elle naît à sa première affectation : inutile de la créer d’avance.
Une valeur est d’une de ces quatre sortes : un texte, un nombre (entier ou décimal), un booléen (true ou false), un tableau. Il n’y a pas de null : '', le texte vide, dit « rien ». Une variable facultative sans valeur, un réglage vide, un débit pas encore connu valent '', et le test s’écrit if ($x != '').
Une affectation est une instruction, jamais une valeur : if ($x = 1) et $a = $b = 1 sont refusés. Une variable doit être affectée plus haut dans le code avant d’être lue.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$nom | le signe $ et un nom en minuscules ASCII, chiffres et _ | oui | Le nom de la variable. Une majuscule est une faute. |
| valeur | une expression | oui | Ce qui est rangé après le =. Un tableau est copié, jamais partagé. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La valeur rangée | texte, nombre, booléen ou tableau | À chaque lecture de $nom. |
| Un arrêt, état MISCONFIGURED | — | La variable est lue alors qu’elle n’existe pas. |
Exemples
Ranger un texte, un entier, un décimal et un booléen.
$host = 'www.example';
$retries = 3;
$ratio = 0.5;
$ready = true; Tester une variable facultative : sans valeur, elle vaut le texte vide.
$word = variable('web:word', 'text', array(
'label' => 'Mot à trouver dans la page',
'help' => 'Facultatif.',
'required' => false,
));
if ($word != '') {
// …
} Copier un tableau : changer $b ne touche pas $a, dont la case x vaut toujours 1.
$a = array('x' => 1);
$b = $a;
$b['x'] = 2; Fautes signalées par le master
name_invalid: Un nom ou une variable hors de sa forme :$Total,$1,$$nom.variable_unassigned: Une variable lue sans être affectée plus haut dans sa portée.
Textes et concaténation
Un texte s’écrit entre apostrophes ou entre guillemets doubles, et peut tenir sur plusieurs lignes. Entre apostrophes, \' vaut une apostrophe et \\ une barre oblique inverse. Entre guillemets, \n vaut un saut de ligne, \t une tabulation, \" un guillemet. Le signe $ n’y remplace jamais une variable : "$x" est le texte $x.
Le point colle deux valeurs. Il s’écrit avec au moins un blanc de chaque côté : $base . '/api'. Un nombre y vaut son écriture. Sans blanc, c’est une faute : le point collé aux deux noms est réservé aux appels, comme dans cache.get('token').
Le point passe après + et - : 'total ' . $a + $b se lit 'total ' . ($a + $b).
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
gauche . droite | deux valeurs, textes ou nombres | oui | Les deux morceaux à assembler. Un blanc au moins de chaque côté du point. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte assemblé | texte | Toujours. |
Exemples
Ajouter un chemin à une adresse.
$url = $base . '/api/v1/jobs'; Composer une phrase avec des nombres.
$state = $name . ' : ' . $up . ' membre(s) actif(s) sur ' . list.count($members); Un texte entre guillemets, avec un saut de ligne.
$detail = "Ligne 1\nLigne 2"; Fautes signalées par le master
concat_spacing: Un point de concaténation sans blanc d’un côté :$a .$b,'load:'.$r['output'].string_unterminated: Un texte entre guillemets non fermé.character_invalid: Un caractère hors du lexique, hors d’un texte : une lettre accentuée, une espace insécable.
Nombres et calculs
Un nombre est un entier (0, 900) ou un décimal avec un point (0.5, 14.3). Un zéro en tête (017), une lettre collée (1e3, 0x1f) ou deux points (1.5.3, un OID écrit sans guillemets) sont refusés. Un nombre négatif s’écrit avec le - du calcul.
Cinq opérateurs : +, -, *, / et %. La multiplication, la division et le reste passent avant l’addition et la soustraction, de gauche à droite ; des parenthèses forcent l’ordre.
Un calcul prend des nombres, ou des textes qui sont l’écriture d’un nombre : $fields[4] + $fields[5] additionne deux mots lus dans la sortie d’une commande.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
gauche et droite | un nombre, ou un texte qui est l’écriture d’un nombre | oui | Les deux côtés de +, -, *, / et %. |
-valeur | un nombre, ou un texte qui est l’écriture d’un nombre | oui | Le - placé devant une valeur en change le signe. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le résultat | nombre | Quand les deux côtés sont des nombres. |
| Un arrêt, état UNREACHABLE | — | Un des côtés est un texte qui n’est pas l’écriture d’un nombre. |
| Un arrêt, état MISCONFIGURED | — | Une division par zéro. |
Exemples
Un pourcentage d’occupation, avec un arrondi à une décimale.
$busy = number.round(100 * (1 - $idle / $total), 1); Additionner deux mots d’une ligne lue.
$f = text.words($line);
$idle = $f[4] + $f[5]; Passer des bits aux octets.
$bytes = $bits / 8; Fautes signalées par le master
number_invalid: Un nombre hors de sa forme :017,1e3,0x1f,1.5.3.form_removed: Une forme retirée :+=,-=,*=,/=,%=,++,--et**.
Comparaisons et opérateurs logiques
== et != comparent deux valeurs : en nombres quand les deux côtés sont des nombres, en textes sinon. Un nombre comparé à '' est donc toujours différent : 0 != ''. <, >, <= et >= comparent l’ordre.
== et != ne s’enchaînent pas : $a == $b == $c est refusé. Les comparaisons d’ordre non plus : 1 < $x < 9 est refusé. Écrivez 1 < $x && $x < 9.
&& (et), || (ou) et ! (non) combinent des conditions. && et || ne lisent leur côté droit que si le gauche ne décide pas déjà : $limit != '' && $x > $limit ne compare jamais $x à un réglage vide.
Des plus faibles aux plus fortes, les priorités sont : ||, &&, == !=, les comparaisons d’ordre, le point, + -, * / %, puis ! et le - devant une valeur. À priorité égale, la lecture va de gauche à droite.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
== != | deux valeurs | oui | Égalité et différence. Non enchaînables. |
< > <= >= | deux valeurs | oui | Ordre. Non enchaînables. |
&& || | deux conditions | oui | Et, ou. Le côté droit n’est lu que si le gauche ne décide pas déjà. |
! | une condition | oui | Le contraire de la condition qui suit. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
true ou false | booléen | Toujours. Le résultat d’une comparaison n’est jamais secret : vous pouvez comparer un secret. |
Exemples
Comparer un code de réponse.
if ($answer['status'] == 200) {
$health = list.get(json.read($answer['body']), 'status', 'absent');
} Ne comparer à un seuil que s’il est rempli.
if ($expected_speed != '' && $speed < $expected_speed) {
watch.raise('speed-degraded', 'warning', $name . ' négocié à ' . $speed . ' Mbit/s', $name);
} Agir quand une clé manque.
if (!list.has($member_of, $name)) {
value('addresses', list.get($address_count, $name, 0), $name);
} Fautes signalées par le master
form_removed: Une forme retirée :===,!==,<>,<=>s’écrivent==ou!=;and,or,xors’écrivent&&et||.
Commentaires
Un commentaire commence par //, hors d’un texte entre guillemets, et va jusqu’à la fin de la ligne. banshee l’ignore : il n’est là que pour celui qui relira le code.
C’est la seule forme. # et /* … */ sont refusés.
Paramètres
Un commentaire ne prend aucun paramètre : tout ce qui suit // sur la ligne est du texte libre.
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Un commentaire n’a aucun effet sur l’exécution. |
Exemples
Une ligne de commentaire au-dessus de ce qu’elle explique.
// Demande la page au site.
$answer = http.get($url); Un commentaire en fin de ligne.
$retries = 3; // Trois essais au plus. Dans un texte entre apostrophes, // n’ouvre pas de commentaire.
$link = 'https://www.example/'; Fautes signalées par le master
form_removed: Une forme retirée :#et/* … */s’écrivent//.
Vos fonctions : function et return
Une fonction de l’auteur range des instructions sous un nom, pour les employer plusieurs fois. Elle se définit au premier niveau du code, jamais dans un bloc ni dans une autre fonction, avant ou après ses appels.
Elle ne voit que ses paramètres : ni les variables du corps principal, ni global, ni static. return rend toujours une valeur et ne s’écrit que dans une fonction. Aucune fonction ne s’appelle elle-même, ni directement ni par une autre : la récursion est refusée.
Son nom est un nom nu, sans point. Il ne peut être ni un mot-clé, ni un nom de domaine (ssh, snmp, http, json, text, number, list, counter, time, cache, secret, watch), ni l’un des sept mots du collecteur.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
nom | un nom nu, en minuscules, défini une seule fois | oui | Le nom de la fonction. |
$paramètres | des variables, toutes distinctes, sans valeur par défaut | non (aucun) | Ce que la fonction reçoit. Un appel passe exactement autant de valeurs. |
return valeur | une expression | oui, dans la fonction | La valeur que l’appel rend. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
La valeur de return | texte, nombre, booléen ou tableau | À chaque appel de la fonction. |
| Un arrêt, état MISCONFIGURED | — | Le plafond de tours ou d’appels de fonction est atteint. |
Exemples
Une fonction qui calcule un pourcentage, et son appel.
function percent($part, $total) {
return number.round(100 * $part / $total, 1);
}
$used = percent($f[2], $f[1]); Une connexion à une API, qui arrête le collecteur si elle est refusée et rend le jeton sinon.
function login($base, $user, $password) {
$body = json.write(array('username' => $user, 'password' => $password));
$answer = http.post($base . '/api/v1/login', $body, headers=array('Content-Type' => 'application/json'));
if ($answer['status'] != 200) {
fail('misconfigured', 'Connexion refusée, code ' . $answer['status']);
}
$session = json.read($answer['body']);
return $session['access_token'];
} Fautes signalées par le master
function_not_top_level: Une fonction définie dans un bloc ou dans une fonction.function_name_reserved: Une fonction de l’auteur sous un nom réservé.function_defined_twice: Une fonction définie deux fois.parameter_twice: Deux paramètres du même nom.function_recursive: Une fonction qui s’appelle elle-même, directement ou par d’autres.return_outside_function:returnhors d’une fonction.
Ce qui n’existe pas dans Keen
Keen ressemble à un vieux PHP, mais plusieurs formes de PHP en sont retirées, parce qu’elles doublent une forme gardée, se lisent mal ou ouvrent une porte. Écrite dans le code, hors d’un texte entre guillemets et d’un commentaire, une de ces formes est une faute qui la nomme.
| Forme retirée | À écrire à la place |
|---|---|
? : | if … else … |
+= -= *= /= %= .= | $i = $i + 1, $t = $t . 'x' |
++ -- | $i = $i + 1 |
$a[] = $x | $a = list.add($a, $x) |
[1, 2] | array(1, 2) |
=== !== <> <=> | ==, != |
and or xor | &&, || |
** | le calcul |
?? | list.get($a, $k, $défaut) |
else if | elseif |
null | une valeur, ou '' pour « rien » |
echo print | value, fail, skip |
switch case default | if … elseif … |
do | while |
class new -> :: | des fonctions |
global static | un paramètre |
include include_once require require_once eval | rien : un collecteur est un seul code |
& | ^ ~ << >> | rien : ni référence, ni calcul binaire |
@ | rien : une faute ne se tait pas |
| l’accent grave | rien : aucun programme ne se lance sur le poller |
<?php <? ?> | rien : le code commence directement |
# /* … */ | // |
: (la syntaxe if (…): … endif;) | des accolades |
Une fonction qui n’est pas dans ce glossaire n’existe pas : ni file_get_contents, ni exec, ni preg_match, ni isset. Un collecteur n’écrit pas sur le disque, n’ouvre pas de connexion en dehors des fonctions de protocole, ne lance aucun programme sur le poller, et n’écrit jamais un secret en clair.
Paramètres
Ces formes ne prennent aucun paramètre : le master les refuse.
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
Une faute form_removed | une faute du master | Dès qu’une de ces formes est écrite. Le master la nomme, avec sa ligne et sa colonne. |
Une faute function_unknown | une faute du master | Dès qu’une fonction qui n’est pas dans ce glossaire est appelée. |
Exemples
Un test à deux issues s’écrit avec if, jamais avec ? :.
$label = 'non';
if ($answer['status'] == 200) {
$label = 'oui';
} Pour livrer un résultat, value remplace echo.
value('code', $answer['status']); Fautes signalées par le master
form_removed: Une forme retirée, avec la forme nommée.function_unknown: Une fonction qui n’existe pas :foo,snmp.set,watch.max.
Les mots du collecteur
Sept mots s’écrivent seuls, sans domaine, parce qu’ils sont le collecteur lui-même : need, variable, output, per, value, fail et skip.
Les quatre premiers sont des déclarations. Elles viennent en tête du code, avant toute autre instruction, et leurs arguments s’écrivent en clair : un nombre, un texte, true, false, ou un array(…) de ces mêmes choses. Le master les lit sans exécuter le collecteur. Une déclaration placée plus bas, ou mêlée à une expression, est refusée. Aucun nom n’est déclaré deux fois.
Les options d’une déclaration sont un array(…) de paires. Une clé qu’elle ne prend pas est une faute (option_unknown), une valeur hors de sa forme aussi (option_invalid), une option obligatoire absente encore (option_missing), et une clé écrite deux fois n’est pas jugée (option_twice).
need
need demande à banshee une variable standard, ou toute la famille d’un protocole, sans la redéfinir : l’adresse de l’hôte, les accès SSH, la version et la communauté SNMP, le délai HTTP. Leur forme, leur caractère secret et leur validation sont ceux de la variable dans banshee.
Une fonction de protocole ne lit que les variables standard que le collecteur a déclarées. Un jeton posé sur un dossier ne part donc jamais vers une cible dont le collecteur ne parle pas.
Une famille déclare d’un coup tout ce que son protocole lit :
| Famille | Déclare | Obligatoires |
|---|---|---|
protocol:ssh | host:address, protocol:ssh:user, protocol:ssh:fingerprint, protocol:ssh:port, protocol:ssh:timeout, protocol:ssh:password, protocol:ssh:private-key | host:address, protocol:ssh:user, protocol:ssh:fingerprint |
protocol:snmp | host:address, protocol:snmp:version, protocol:snmp:port, protocol:snmp:timeout, protocol:snmp:v2c:community, protocol:snmp:v3:user, protocol:snmp:v3:auth-protocol, protocol:snmp:v3:auth-password, protocol:snmp:v3:priv-protocol, protocol:snmp:v3:priv-password | host:address |
protocol:http | protocol:http:timeout, protocol:http:fingerprint, protocol:http:user-agent, puis les huit variables du profil TLS : protocol:tls:mode, protocol:tls:min-version, protocol:tls:max-version, protocol:tls:suites, protocol:tls:allow-incomplete-chain, protocol:tls:skip-verify, protocol:tls:authorities, protocol:tls:server-name | aucune |
protocol:ntp | protocol:ntp:server, protocol:ntp:timeout | protocol:ntp:server |
protocol:winrm | host:address, protocol:winrm:user, protocol:winrm:password, protocol:winrm:port, protocol:winrm:timeout, protocol:winrm:fingerprint, puis les huit variables du profil TLS, dans l’ordre de protocol:http | host:address, protocol:winrm:user, protocol:winrm:password |
protocol:icmp | host:address, protocol:icmp:count, protocol:icmp:timeout, protocol:icmp:interval | host:address |
protocol:dns | protocol:dns:server, protocol:dns:timeout | aucune |
protocol:tcp | host:address, protocol:tcp:timeout | host:address |
protocol:aws | protocol:aws:access-key-id, protocol:aws:secret-access-key, protocol:aws:session-token | protocol:aws:access-key-id, protocol:aws:secret-access-key |
protocol:ovh | protocol:ovh:application-key, protocol:ovh:application-secret, protocol:ovh:consumer-key | les trois |
protocol:google | protocol:google:service-account-key | protocol:google:service-account-key |
protocol:ntp et protocol:dns ne déclarent pas host:address : ntp.time et dns.resolve interrogent leur serveur, jamais l’hôte. Sans valeur, protocol:dns:server est le résolveur du système du poller.
protocol:aws, protocol:ovh et protocol:google portent les clés d’un fournisseur cloud, et aucune ne déclare host:address : l’API d’un fournisseur est à l’adresse que l’appel écrit. L’adresse de l’API d’OVHcloud, protocol:ovh:endpoint, n’est pas dans la famille : vous la lisez pour écrire l’adresse de la requête, avec son propre need, à côté de la famille.
Les accès HTTP (protocol:http:user, protocol:http:password, protocol:http:token) ne sont dans aucune famille : l’adresse d’une requête est libre, et un accès ne part que vers un collecteur qui le nomme lui-même. Déclarez-les un par un. Le profil TLS, lui, n’est pas un accès : il ne porte aucun secret, et la famille le déclare d’un coup.
Un appel http.get, http.post, http.put ou http.delete demande la famille protocol:http : sans elle, la sonde ne recevrait ni son profil TLS ni son User-Agent, et la connexion suivrait le profil « Standard » contre le réglage du dossier, sans bruit. De même, ntp.time demande protocol:ntp, winrm.run protocol:winrm, icmp.ping protocol:icmp, dns.resolve protocol:dns et tcp.connect protocol:tcp : sans sa famille, un appel ignorerait sans bruit le serveur, le port, le nombre d’échos ou le délai que l’arbre pose. aws.sign, ovh.sign et google.token demandent protocol:aws, protocol:ovh et protocol:google : sans elle, ils n’auraient pas de clé. Un tel appel est une faute (need_missing).
Une variable n’est déclarée qu’une fois. host:address, que deux familles portent, l’est une fois quand le code déclare les deux ; écrite par un need en plus d’une famille qui la porte, elle l’est deux fois, et c’est une faute.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$name | un texte écrit en clair : host:address, une variable protocol:… du catalogue, ou une famille (protocol:ssh, protocol:snmp, protocol:http, protocol:ntp, protocol:winrm, protocol:icmp, protocol:dns, protocol:tcp, protocol:aws, protocol:ovh, protocol:google) | oui | La variable, ou la famille entière. Tout autre nom est refusé, une faute de frappe comme un nom réservé. |
'optional' | le texte optional | non (la variable est obligatoire) | Rend la variable facultative. Refusé sur une famille : chaque variable d’une famille est obligatoire ou facultative comme la table le dit. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La valeur de la variable pour l’hôte de la sonde | texte, nombre ou booléen, selon la forme de la variable | Quand le need est affecté : $address = need('host:address');. Une variable facultative sans valeur rend ''. |
| Rien | — | Le need d’une famille, ou écrit seul. |
| Un arrêt, état MISCONFIGURED | — | Une variable obligatoire n’a pas de valeur. |
Exemples
Tout ce que le protocole SNMP lit, en une ligne.
need('protocol:snmp'); Un jeton HTTP, rangé dans une variable pour le placer dans un en-tête.
need('protocol:http');
$token = need('protocol:http:token');
$answer = http.get($url, headers=array('Authorization' => 'Bearer ' . $token)); Une adresse facultative.
$address = need('host:address', 'optional'); Fautes signalées par le master
need_not_standard: Unneedqui ne nomme ni une variable standard ni une famille :protocol:ssh:pasword,protocol:ftp.need_mode_invalid: Le second argument n’est pas'optional', ou leneedd’une famille en porte un.declared_twice: Un nom déclaré deux fois.declaration_misplaced: Unneedhors de l’en-tête, ou employé dans une expression.need_missing: Un appel de protocole sans leneedde sa famille : unhttp.get, unhttp.post, unhttp.putou unhttp.deletesansneed('protocol:http'), unicmp.pingsansneed('protocol:icmp').
variable
variable déclare un réglage propre au collecteur, que l’administrateur remplit sur la sonde. L’auteur du collecteur en choisit le nom, la forme, le libellé et la phrase d’aide.
Son nom compte de 2 à 8 segments séparés par : (web:url), en minuscules ASCII, chiffres, ., _ et -, et 255 caractères au plus. Il ne peut pas commencer par host, acl ou protocol, qui sont réservés.
Un réglage secret (mot de passe, jeton) se déclare avec 'secret' => true et ne peut avoir de valeur par défaut, parce qu’un secret ne s’écrit pas en clair dans un code.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$name | un texte écrit en clair, de 2 à 8 segments séparés par : | oui | Le nom du réglage. |
$form | text, multiline, integer, boolean ou choice | oui | La forme de la saisie. |
'label' | un texte non vide | oui, dans $options | Le libellé que l’écran montre. |
'help' | un texte non vide | oui, dans $options | La phrase qui explique le réglage. |
'required' | true ou false | non (true) | Un réglage facultatif sans valeur rend ''. |
'secret' | true ou false | non (false) | Marque le réglage comme secret. |
'default' | une valeur bien formée pour la forme : un texte, un entier pour integer, true ou false pour boolean, l’un des choix pour choice | non (aucune valeur par défaut) | Jamais pour un secret. |
'inherit' | down, here ou choice | non (choice) | Le mode d’héritage du réglage, tel que banshee le définit pour ses variables. |
'choices' | un array(…) d’au moins un texte, chacun non vide, tous distincts | oui, et pour choice seulement | Les choix proposés. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La valeur du réglage pour l’hôte de la sonde | nombre pour integer, true ou false pour boolean, texte pour les autres formes | Quand la déclaration est affectée : $url = variable(…);. Un réglage facultatif sans valeur rend ''. |
| Un arrêt, état MISCONFIGURED | — | Un réglage obligatoire n’a pas de valeur. |
Exemples
Une adresse à vérifier.
$url = variable('web:url', 'text', array(
'label' => 'Adresse à vérifier',
'help' => 'Par exemple https://www.example/.',
)); Un mot de passe, secret et sans valeur par défaut.
$password = variable('backup:password', 'text', array(
'secret' => true,
'label' => 'Mot de passe',
'help' => 'Le mot de passe de ce compte.',
)); Un choix parmi une liste.
$mode = variable('web:mode', 'choice', array(
'label' => 'Méthode de contrôle',
'help' => 'Ce que le collecteur vérifie.',
'choices' => array('code', 'mot'),
'default' => 'code',
)); Fautes signalées par le master
variable_name_invalid: Un nom hors de la forme d’un nom de variable.variable_family_reserved: Un nom des familleshost,aclouprotocol.variable_form_invalid: Une forme hors des cinq.option_missing: Une option obligatoire absente :labelouhelp.
output
output annonce une valeur que le collecteur va rendre, pour que banshee puisse l’afficher, la garder et la surveiller. Le master la lit sans exécuter le code.
Chaque output sans per doit être rendu une fois à chaque passage par value. Un output avec per est rendu une fois par instance.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$name | un segment : minuscules ASCII, chiffres, ., _, -, 1 à 64 caractères | oui | Le nom de la valeur, par lequel value et les surveillances la retrouvent : cpu-busy, load-1. |
$sort | number ou text | oui | La sorte de la valeur. |
'label' | un texte non vide | non (l’écran montre le nom) | Le libellé que l’écran montre, par exemple « Débit entrant ». |
'unit' | un texte non vide | non (aucune) | L’unité : %, bit/s. |
'per' | le nom de la sorte d’instances que le per du collecteur déclare | non (la valeur est unique) | La valeur se rend une fois par instance. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. La valeur se rend avec value. |
Exemples
Une valeur unique, avec son libellé et son unité.
output('response-time', 'number', array('label' => 'Temps de réponse', 'unit' => 'ms')); Une valeur de sorte texte.
output('health', 'text', array('label' => 'État déclaré')); Une valeur rendue une fois par interface.
per('interface', 'Interfaces');
output('traffic-in', 'number', array('label' => 'Débit entrant', 'unit' => 'bit/s', 'per' => 'interface')); Fautes signalées par le master
declared_name_invalid: Le nom d’unoutputhors de la forme d’un segment.output_sort_invalid: Une sorte hors denumberettext.per_undeclared: Unoutputdontperne nomme pas la sorte que leperdu collecteur déclare.declared_twice: Un nom d’outputdéclaré deux fois.
per
per déclare la sorte d’instances du collecteur, c’est-à-dire ce qu’il mesure plusieurs fois par passage : une interface, un cœur, un système de fichiers, un service. Il déclare aussi la sélection par défaut. Un collecteur en déclare un au plus.
La sonde porte une seule sélection, pour toutes ses valeurs et toutes ses surveillances : Toutes (sauf les motifs d’ignore), y compris les instances qui apparaîtront plus tard, ou Seulement (les motifs d’only). L’administrateur la change sur la sonde. Aucune surveillance n’a de filtre propre.
Le code ne filtre pas : il rend toutes les instances qu’il voit. C’est le poller qui écarte, avant de juger ou d’envoyer quoi que ce soit, celles qui sont hors de la sélection.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$name | un segment, comme le nom d’un output | oui | Le nom de la sorte d’instances : interface, core, filesystem. |
$label | un texte non vide | oui | Le mot que l’écran montre pour ces instances, au pluriel : « Interfaces », « Cœurs ». |
'ignore' | un array(…) d’au moins un texte non vide, tous distincts | non (aucun) | Les motifs des instances à ne pas regarder : la sélection par défaut est Toutes sauf celles-là. Un motif suit les règles de text.like. |
'only' | un array(…) d’au moins un texte non vide, tous distincts | non (aucun) | Les motifs des seules instances à regarder : la sélection par défaut est Seulement celles-là. Jamais avec ignore. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. Sans ignore ni only, la sélection par défaut est Toutes. |
Exemples
Les interfaces d’un Linux, sans l’interface locale ni celles de Docker.
per('interface', 'Interfaces', array('ignore' => array('lo', 'docker*', 'veth*'))); Deux services regardés par défaut, les autres au choix sur la sonde.
per('service', 'Services', array('only' => array('sshd', 'cron'))); Tous les cœurs.
per('core', 'Cœurs'); Fautes signalées par le master
per_twice: Un secondper.declared_name_invalid: Un nom hors de la forme d’un segment.title_invalid: Un libellé qui n’est pas un texte non vide.option_invalid: Une option hors de sa forme, ouignoreetonlyensemble.
value
value rend une valeur annoncée par output. Son nom s’écrit en clair, et doit être celui d’un output.
Chaque valeur se rend au plus une fois par instance. Une valeur est gardée si le collecteur va jusqu’à sa dernière instruction ; si le collecteur s’arrête par fail ou de lui-même, aucune valeur ne part, même celles rendues avant l’arrêt.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$name | un texte écrit en clair | oui | Le nom d’un output déclaré. |
$value | une expression | oui | La valeur rendue. |
$instance | une expression | oui si l’output est déclaré per, refusé sinon | Le nom de l’instance que la valeur concerne. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | value ne rend pas de valeur. |
| Un arrêt, état MISCONFIGURED | — | Une valeur annoncée n’est jamais rendue, ou l’est deux fois ; ou la valeur est un secret. |
| Un arrêt, état UNREACHABLE | — | La valeur d’un output de sorte number est un texte qui n’est pas l’écriture d’un nombre. |
Exemples
Rendre le code de réponse d’un site.
value('code', $answer['status']); Rendre un état par instance, ici par interface.
value('link', $f['operstate'], $name); Ne rendre une valeur que lorsqu’elle est connue.
if ($busy != '') {
value('core-busy', $busy, $f[0]);
} Fautes signalées par le master
value_output_unknown: Unvaluequi ne nomme aucunoutput.value_instance_required: Unvaluesans instance pour unoutputper.value_instance_forbidden: Unvalueavec instance pour unoutputsansper.argument_not_literal: Un nom qui n’est pas écrit en clair.secret_written: Un secret visible à la lecture passé àvalue.
fail
fail arrête le collecteur sur un état que lui seul connaît. Le résumé et le détail sont le message que la sonde affiche.
Un collecteur arrêté par fail ne livre jamais de valeur, même celles rendues avant, et aucune surveillance n’est jugée : la sonde prend l’état demandé, avec le message.
Trois états sont possibles : critical, misconfigured et unreachable.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$state | critical, misconfigured ou unreachable, écrit en clair | oui | L’état de la sonde. |
$summary | un texte | oui | Le résumé du message. |
$detail | un texte | non (aucun) | Le détail du message. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Aucune valeur | — | fail arrête le collecteur. Il n’y a rien après lui. |
| L’état demandé, CRITICAL, MISCONFIGURED ou UNREACHABLE | état de la sonde, avec le message | À chaque exécution de fail. |
| Un arrêt, état MISCONFIGURED | — | Le résumé ou le détail contient un secret. |
Exemples
Arrêter sur un état critique quand un mot manque.
fail('critical', 'Mot absent', 'La page ne contient pas le mot ' . $word . '.'); Une commande qui échoue sur la cible.
if ($df['exit'] != 0) {
fail('unreachable', 'df a échoué', $df['errors']);
} Une sonde mal réglée.
if (!$found) {
fail('misconfigured', 'Interface introuvable : ' . $wanted);
} Fautes signalées par le master
fail_state_invalid: Un état hors des trois.argument_not_literal: Un état qui n’est pas écrit en clair.secret_written: Un secret visible à la lecture passé àfail.
skip
skip passe le tour : rien ne part, et la sonde garde l’état qu’elle avait (PENDING si elle n’en a pas encore). Servez-vous-en quand le collecteur ne peut pas conclure à ce passage, par exemple au premier relevé d’un compteur.
Si la sonde ne rend plus rien, le master la montre OLD, et la raison du dernier skip se lit dans son détail.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$reason | un texte | oui | Pourquoi le tour est passé. Elle se lit dans le détail de la sonde. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Aucune valeur | — | skip arrête le collecteur sans rien livrer. La sonde garde son état. |
| Un arrêt, état MISCONFIGURED | — | La raison contient un secret. |
Exemples
Attendre un deuxième relevé pour calculer un débit.
if ($in == '' || $out == '') {
skip('Premier relevé, ou compteurs revenus en arrière : le débit viendra au prochain passage');
} Attendre une occupation qui n’est pas encore connue.
if ($global == '') {
skip("Premier relevé : l'occupation viendra au prochain passage");
} Fautes signalées par le master
secret_written: Un secret visible à la lecture passé àskip.
Les surveillances
Un collecteur mesure et propose ses surveillances ; l’administrateur choisit ; le poller juge. Une surveillance est un cas d’usage que l’auteur écrit une fois, avec des seuils par défaut : « Lien tombé », « Saturation entrante ». Sur la page d’une sonde, l’administrateur coche celles qu’il veut et règle leurs seuils, sans voir ni formule ni code. Aucun seuil n’est écrit en dur dans le code.
Une surveillance se déclare en une ligne, dans l’en-tête : le genre est le nom de la méthode (watch.above), et les seuils sont ses options. Neuf genres sont jugés par banshee, un dixième, custom, est jugé par le code lui-même.
| Genre | Ce qu’il juge |
|---|---|
above | la valeur est strictement au-delà d’un seuil |
below | la valeur est strictement en dessous d’un seuil |
increase | un compteur a trop augmenté sur une fenêtre |
silence | la valeur est restée à zéro trop longtemps |
habit | la valeur s’écarte de son habitude, à cette heure et ce jour de la semaine |
deviate | la valeur d’une instance s’écarte des autres instances du même passage |
missing | des instances attendues manquent |
state | la valeur prend l’un des états d’une liste |
expect | la valeur n’est aucune de celles d’une liste |
custom | ce que le code juge lui-même, avec watch.raise |
Les réglages d’une surveillance ont chacun une forme :
- un nombre, écrit en clair, précédé ou non de
-(70,0.5). Son unité est celle de l’output; - une durée, un texte : un entier de 1 à 10 000 sans zéro en tête, une espace, une unité.
s,min,hetddonnent une durée en temps, de 30 jours au plus.runourunsdonnent un nombre de passages, permis dansforseulement :'5 min','1 h','3 runs'; - une liste, un
array(…)d’au moins un élément, sans clé écrite, chaque élément un texte non vide (pourstateetexpect, un texte ou un nombre), tous distincts ; - un texte, dans un
customseulement : un texte non vide.
Tous les seuils sont facultatifs. Un seuil vide, son niveau n’est pas jugé : pas d’avertissement, ou pas de critique. Une surveillance cochée dont aucun seuil n’est rempli ne lève jamais. window, sensitivity et side ne se vident pas.
Après chaque passage qui va jusqu’à la dernière instruction, le poller juge. Pour chaque surveillance cochée et chaque instance gardée par la sélection, il lève un niveau, warning ou critical, quand son seuil est rempli. Le niveau critique se juge avant l’avertissement, et une surveillance lève au plus un niveau par instance, le plus grave. L’état de la sonde est le plus grave de toutes ses levées, OK sans aucune. La phrase d’une levée est composée par banshee, sauf pour un custom.
watch.above
watch.above lève quand la valeur est strictement au-delà d’un seuil : une occupation de processeur ou de lien, un temps de réponse, un nombre d’erreurs. Au seuil exact, rien ne lève.
Avec ahead, la valeur jugée est celle que la tendance de la mesure projette à cette distance : « plein dans la semaine ». La tendance demande un historique de la mesure ; tant qu’il s’apprend, la surveillance ne lève rien et banshee la montre en apprentissage.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
$output | le nom d’un output déclaré | oui | La mesure surveillée. La surveillance regarde chaque instance que le code en rend et que la sélection garde. |
'warning' | un nombre | non (aucun) | Le seuil de l’avertissement, dans l’unité de l’output. |
'critical' | un nombre | non (aucun) | Le seuil du niveau critique. |
'for' | une durée, en passages ou en temps | non (1 run) | Combien de temps la condition doit tenir avant de lever. En passages : à ce passage et aux précédents. En temps : depuis au moins cette durée. Un passage où elle ne tient pas la fait repartir de zéro. |
'ahead' | une durée en temps | non (aucune tendance) | La distance à laquelle la tendance est projetée. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
'help' | un texte non vide | non (aucun) | Une phrase qui dit ce que fait la surveillance, lue sous son titre. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
Une levée warning ou critical, par instance | un niveau et une phrase | La valeur dépasse le seuil depuis la durée de for. Exemple de phrase : eth0 à 93 %, au-delà de 90 % depuis 5 min. |
Exemples
Une saturation d’interface, avec deux niveaux et une durée en temps.
watch.above('saturation-in', 'Saturation entrante', 'in-percent', array('warning' => 70, 'critical' => 90, 'for' => '5 min')); Un cœur saturé trois passages de suite.
watch.above('core-hot', 'Un cœur saturé', 'core-busy', array('warning' => 70, 'for' => '3 runs')); Un disque qui sera plein dans la semaine, d’après la tendance.
watch.above('full-soon', 'Plein dans la semaine', 'used', array('warning' => 99, 'ahead' => '7 d')); Fautes signalées par le master
watch_output_unknown: Une surveillance qui nomme unoutputnon déclaré.watch_output_unfit: Unoutputdont la sorte ou l’absence deperne convient pas au genre.option_unknown: Une clé d’options que la déclaration ne prend pas.kind,output,messageetmatchn’existent plus.option_invalid: Une option hors de sa forme.declared_twice: Un nom déclaré deux fois.
watch.below
watch.below lève quand la valeur est strictement en dessous d’un seuil : un espace libre, un cœur sous-utilisé, une charge de batterie. Il prend les mêmes réglages que watch.above, ahead compris.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
$output | le nom d’un output déclaré | oui | La mesure surveillée. La surveillance regarde chaque instance que le code en rend et que la sélection garde. |
'warning' | un nombre | non (aucun) | Le seuil de l’avertissement, dans l’unité de l’output. |
'critical' | un nombre | non (aucun) | Le seuil du niveau critique. |
'for' | une durée, en passages ou en temps | non (1 run) | Combien de temps la condition doit tenir avant de lever. En passages : à ce passage et aux précédents. En temps : depuis au moins cette durée. Un passage où elle ne tient pas la fait repartir de zéro. |
'ahead' | une durée en temps | non (aucune tendance) | La distance à laquelle la tendance est projetée. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
'help' | un texte non vide | non (aucun) | Une phrase qui dit ce que fait la surveillance, lue sous son titre. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
Une levée warning ou critical, par instance | un niveau et une phrase | La valeur est sous le seuil depuis la durée de for. Exemple de phrase : cpu3 à 12 %, en dessous de 20 %. |
Exemples
Un cœur sous-utilisé.
watch.below('core-idle', 'Un cœur sous-utilisé', 'core-busy', array('warning' => 20)); Une interface sans adresse IP : critique quand il y en a moins de une.
watch.below('no-address', "Plus d'adresse IP", 'addresses', array('critical' => 1)); Un espace libre faible, avec une surveillance décochée d’office.
watch.below('free', "Peu d'espace libre", 'free', array('critical' => 1024, 'enabled' => false)); Fautes signalées par le master
watch_output_unknown: Une surveillance qui nomme unoutputnon déclaré.watch_output_unfit: Unoutputdont la sorte ou l’absence deperne convient pas au genre.option_unknown: Une clé d’options que la déclaration ne prend pas.kind,output,messageetmatchn’existent plus.option_invalid: Une option hors de sa forme.declared_twice: Un nom déclaré deux fois.
watch.increase
watch.increase lève quand un compteur a trop augmenté sur une fenêtre de temps : des changements d’état d’un lien, un nombre d’erreurs cumulé. L’output est un nombre qui ne fait que croître.
La valeur jugée est la valeur actuelle moins la plus ancienne lue dans la fenêtre. Une valeur plus petite que la précédente, un compteur remis à zéro, fait repartir la fenêtre d’elle. Tant que la fenêtre n’est pas pleine, l’augmentation se compte sur ce qui a été lu.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
$output | le nom d’un output déclaré | oui | La mesure surveillée. La surveillance regarde chaque instance que le code en rend et que la sélection garde. |
'warning' | un nombre | non (aucun) | L’augmentation, sur la fenêtre, qui lève l’avertissement. |
'critical' | un nombre | non (aucun) | L’augmentation, sur la fenêtre, qui lève le niveau critique. |
'window' | une durée en temps | non (1 h) | La longueur de la fenêtre. Ne se vide pas. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
'help' | un texte non vide | non (aucun) | Une phrase qui dit ce que fait la surveillance, lue sous son titre. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
Une levée warning ou critical, par instance | un niveau et une phrase | L’augmentation sur la fenêtre est au-delà du seuil. Exemple de phrase : eth0 : +5 en 1 h, au-delà de 3. |
Exemples
Un lien instable : plus de trois changements d’état en une heure.
watch.increase('link-flapping', 'Lien instable', 'carrier-changes', array('warning' => 3, 'window' => '1 h')); Fautes signalées par le master
watch_output_unknown: Une surveillance qui nomme unoutputnon déclaré.watch_output_unfit: Unoutputdont la sorte ou l’absence deperne convient pas au genre.option_unknown: Une clé d’options que la déclaration ne prend pas.kind,output,messageetmatchn’existent plus.option_invalid: Une option hors de sa forme.declared_twice: Un nom déclaré deux fois.
watch.silence
watch.silence lève quand la valeur est restée à zéro trop longtemps : une interface sans aucun paquet, un service qui ne traite plus rien. Les seuils sont des durées.
La valeur doit valoir zéro à ce passage et à chacun de ceux qui l’ont précédé depuis au moins la durée du seuil.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
$output | le nom d’un output déclaré | oui | La mesure surveillée. La surveillance regarde chaque instance que le code en rend et que la sélection garde. |
'warning' | une durée en temps | non (aucun) | Le temps passé à zéro qui lève l’avertissement. |
'critical' | une durée en temps | non (aucun) | Le temps passé à zéro qui lève le niveau critique. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
'help' | un texte non vide | non (aucun) | Une phrase qui dit ce que fait la surveillance, lue sous son titre. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
Une levée warning ou critical, par instance | un niveau et une phrase | La valeur est à zéro depuis la durée du seuil. Exemple de phrase : eth1 à zéro depuis 12 min. |
Exemples
Une interface muette depuis dix minutes, décochée d’office.
watch.silence('mute', 'Interface muette', 'packets', array('warning' => '10 min', 'enabled' => false)); Fautes signalées par le master
watch_output_unknown: Une surveillance qui nomme unoutputnon déclaré.watch_output_unfit: Unoutputdont la sorte ou l’absence deperne convient pas au genre.option_unknown: Une clé d’options que la déclaration ne prend pas.kind,output,messageetmatchn’existent plus.option_invalid: Une option hors de sa forme.declared_twice: Un nom déclaré deux fois.
watch.habit
watch.habit lève quand la valeur s’écarte de son habitude pour cette sonde, à cette heure et ce jour de la semaine. Il ne lève jamais que l’avertissement.
L’habitude demande l’historique de la mesure. Tant qu’il s’apprend, la surveillance ne lève rien et banshee la montre en apprentissage.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
$output | le nom d’un output déclaré | oui | La mesure surveillée. La surveillance regarde chaque instance que le code en rend et que la sélection garde. |
'sensitivity' | low, normal ou high | non (normal) | La sensibilité du jugement de l’écart. Ne se vide pas. |
'floor' | un nombre | non (aucun) | Un plancher : sous cette valeur, la surveillance ne lève jamais. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
'help' | un texte non vide | non (aucun) | Une phrase qui dit ce que fait la surveillance, lue sous son titre. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
Une levée warning, par instance | un niveau et une phrase | La valeur s’écarte de son habitude plus que la sensibilité ne le permet, sans être sous le plancher. Exemple de phrase : eth0 à 840 Mbit/s, d’habitude 120 Mbit/s à cette heure. |
Exemples
Un trafic inhabituel, sans lever sous 10 Mbit/s, décoché d’office.
watch.habit('traffic-unusual', 'Trafic anormal', 'traffic', array('floor' => 10000000, 'enabled' => false)); Fautes signalées par le master
watch_output_unknown: Une surveillance qui nomme unoutputnon déclaré.watch_output_unfit: Unoutputdont la sorte ou l’absence deperne convient pas au genre.option_unknown: Une clé d’options que la déclaration ne prend pas.kind,output,messageetmatchn’existent plus.option_invalid: Une option hors de sa forme.declared_twice: Un nom déclaré deux fois.
watch.deviate
watch.deviate compare les instances entre elles : elle lève quand la valeur d’une instance s’écarte des autres instances du même passage, par exemple un cœur sous-utilisé alors que les autres travaillent. L’output doit être un nombre déclaré per.
L’écart se mesure à la médiane des valeurs des autres instances, c’est-à-dire la valeur du milieu une fois rangées (la moyenne des deux du milieu quand elles sont en nombre pair). Il doit être strictement au-delà du seuil. Un passage qui garde moins de trois instances de l’output ne juge rien et fait repartir for de zéro.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
$output | le nom d’un output déclaré | oui | La mesure surveillée. La surveillance regarde chaque instance que le code en rend et que la sélection garde. |
'warning' | un nombre positif ou nul | non (aucun) | L’écart à la médiane des autres qui lève l’avertissement. Un nombre négatif est refusé. |
'critical' | un nombre positif ou nul | non (aucun) | L’écart qui lève le niveau critique. |
'side' | below, above ou both | non (both) | Le côté où l’écart compte : sous la médiane, au-dessus, ou l’un et l’autre. Ne se vide pas. |
'for' | une durée, en passages ou en temps | non (1 run) | Combien de temps la condition doit tenir avant de lever. En passages : à ce passage et aux précédents. En temps : depuis au moins cette durée. Un passage où elle ne tient pas la fait repartir de zéro. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
'help' | un texte non vide | non (aucun) | Une phrase qui dit ce que fait la surveillance, lue sous son titre. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
Une levée warning ou critical, par instance | un niveau et une phrase | L’écart à la médiane des autres est au-delà du seuil, du bon côté, depuis la durée de for. Exemple de phrase : cpu3 à 5 %, 75 % sous la médiane des autres (80 %). |
Exemples
Un cœur délaissé alors que les autres travaillent.
watch.deviate('core-neglected', 'Un cœur délaissé', 'core-busy', array('side' => 'below', 'warning' => 30)); Un cœur à part, d’un côté ou de l’autre, avec deux niveaux.
watch.deviate('core-off', 'Un cœur à part', 'core-busy', array('warning' => 20, 'critical' => 40)); Fautes signalées par le master
watch_output_unknown: Une surveillance qui nomme unoutputnon déclaré.watch_output_unfit: Unoutputdont la sorte ou l’absence deperne convient pas au genre.option_unknown: Une clé d’options que la déclaration ne prend pas.kind,output,messageetmatchn’existent plus.option_invalid: Une option hors de sa forme.declared_twice: Un nom déclaré deux fois.
watch.missing
watch.missing lève quand des instances attendues manquent : une interface qui a disparu, un système de fichiers qui n’est plus monté. L’output doit être déclaré per, de n’importe quelle sorte.
Il juge sur toutes les instances rendues, sélection ou non. Chaque nom de la liste d’un niveau qui n’est l’instance d’aucune valeur de l’output à ce passage lève ce niveau, une seule fois, avec tous les noms manquants.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
$output | le nom d’un output déclaré | oui | La mesure surveillée. La surveillance regarde chaque instance que le code en rend et que la sélection garde. |
'warning' | une liste de noms d’instances | non (aucun) | Les noms dont l’absence lève l’avertissement. |
'critical' | une liste de noms d’instances | non (aucun) | Les noms dont l’absence lève le niveau critique. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
'help' | un texte non vide | non (aucun) | Une phrase qui dit ce que fait la surveillance, lue sous son titre. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
Une levée warning ou critical | un niveau et une phrase | Un nom de la liste du niveau n’est plus rendu. Exemple de phrase : absentes : eth0, bond0. |
Exemples
Deux interfaces à surveiller, critique si l’une manque, décochée d’office.
watch.missing('missing', 'Interface manquante', 'link', array('critical' => array('eth0', 'bond0'), 'enabled' => false)); Sans nom attendu, la surveillance ne lève rien tant que l’administrateur n’en a pas saisi.
watch.missing('missing', 'Système de fichiers absent', 'used'); Fautes signalées par le master
watch_output_unknown: Une surveillance qui nomme unoutputnon déclaré.watch_output_unfit: Unoutputdont la sorte ou l’absence deperne convient pas au genre.option_unknown: Une clé d’options que la déclaration ne prend pas.kind,output,messageetmatchn’existent plus.option_invalid: Une option hors de sa forme.declared_twice: Un nom déclaré deux fois.
watch.state
watch.state lève quand la valeur prend l’un des états d’une liste : un lien down, une tâche failed. L’output est un nombre ou un texte. Une valeur est comparée sous son écriture de texte.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
$output | le nom d’un output déclaré | oui | La mesure surveillée. La surveillance regarde chaque instance que le code en rend et que la sélection garde. |
'warning' | une liste de valeurs | non (aucune) | Les valeurs qui lèvent l’avertissement. |
'critical' | une liste de valeurs | non (aucune) | Les valeurs qui lèvent le niveau critique. |
'for' | une durée, en passages ou en temps | non (1 run) | Combien de temps la condition doit tenir avant de lever. En passages : à ce passage et aux précédents. En temps : depuis au moins cette durée. Un passage où elle ne tient pas la fait repartir de zéro. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
'help' | un texte non vide | non (aucun) | Une phrase qui dit ce que fait la surveillance, lue sous son titre. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
Une levée warning ou critical, par instance | un niveau et une phrase | La valeur est dans la liste du niveau, depuis la durée de for. Exemple de phrase : eth0 vaut down. |
Exemples
Un lien tombé.
watch.state('link-down', 'Lien tombé', 'link', array('critical' => array('down', 'lowerlayerdown'))); Une tâche de sauvegarde en échec.
watch.state('failed', 'Tâche en échec', 'result', array('critical' => array('failed'))); Fautes signalées par le master
watch_output_unknown: Une surveillance qui nomme unoutputnon déclaré.watch_output_unfit: Unoutputdont la sorte ou l’absence deperne convient pas au genre.option_unknown: Une clé d’options que la déclaration ne prend pas.kind,output,messageetmatchn’existent plus.option_invalid: Une option hors de sa forme.declared_twice: Un nom déclaré deux fois.
watch.expect
watch.expect est l’inverse de watch.state : elle lève quand la valeur n’est aucune de celles d’une liste. La liste est celle des valeurs attendues, et toute autre valeur lève le niveau. L’output est un nombre ou un texte.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
$output | le nom d’un output déclaré | oui | La mesure surveillée. La surveillance regarde chaque instance que le code en rend et que la sélection garde. |
'warning' | une liste de valeurs | non (aucune) | Les valeurs attendues ; toute autre lève l’avertissement. |
'critical' | une liste de valeurs | non (aucune) | Les valeurs attendues ; toute autre lève le niveau critique. |
'for' | une durée, en passages ou en temps | non (1 run) | Combien de temps la condition doit tenir avant de lever. En passages : à ce passage et aux précédents. En temps : depuis au moins cette durée. Un passage où elle ne tient pas la fait repartir de zéro. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
'help' | un texte non vide | non (aucun) | Une phrase qui dit ce que fait la surveillance, lue sous son titre. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
Une levée warning ou critical, par instance | un niveau et une phrase | La valeur n’est dans aucune de la liste du niveau, depuis la durée de for. Exemple de phrase : eth0 vaut 1500, attendu : 9000. |
Exemples
Un code de réponse qui doit valoir 200.
watch.expect('code', 'Réponse en erreur', 'code', array('critical' => array(200))); Un service qui doit être actif.
watch.expect('stopped', 'Service arrêté', 'state', array('critical' => array('active'))); Un nombre de cœurs que l’administrateur renseigne sur la sonde.
watch.expect('core-count', 'Nombre de cœurs inattendu', 'cores'); Fautes signalées par le master
watch_output_unknown: Une surveillance qui nomme unoutputnon déclaré.watch_output_unfit: Unoutputdont la sorte ou l’absence deperne convient pas au genre.option_unknown: Une clé d’options que la déclaration ne prend pas.kind,output,messageetmatchn’existent plus.option_invalid: Une option hors de sa forme.declared_twice: Un nom déclaré deux fois.
watch.custom
watch.custom déclare une surveillance que le code juge lui-même, avec watch.raise, pour les cas qu’aucun autre genre ne couvre. Elle n’a pas d’output. Ses réglages, que l’administrateur change sur la sonde, se lisent dans le code avec watch.setting.
Les réglages se déclarent sous settings, un array(…) de paires : la clé est le nom du réglage, la valeur un array(…) de paires aux clés label, form, unit et default.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un segment : minuscules, chiffres, ., _, -, 1 à 64 caractères | oui | L’identifiant de la surveillance. C’est par lui qu’une sonde retrouve ce qu’elle a coché, d’une version du collecteur à l’autre. |
$title | un texte non vide | oui | Le nom que l’administrateur lit. |
'help' | un texte non vide | oui | Ce que fait la surveillance, en une phrase : rien d’autre ne la décrit. |
'settings' | un array(…) de paires, nom du réglage => son array(…) | non (aucun réglage) | Les réglages que l’auteur déclare. |
'label' | un texte non vide | oui, dans chaque réglage | Ce que l’administrateur lit devant la case. |
'form' | number, duration (une durée en temps), names (une liste) ou text | oui, dans chaque réglage | La forme de la saisie. |
'unit' | un texte non vide, pour number seulement | non (aucune) | L’unité affichée. |
'default' | une valeur de sa forme | non (vide) | La valeur que l’auteur propose. |
'enabled' | true ou false | non (true) | Cochée d’office sur une sonde neuve. false convient à une surveillance qui demande un réglage avant de servir. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | Une déclaration ne rend pas de valeur. |
| Les levées du code | un niveau et la phrase de watch.raise | Le code appelle watch.raise. La phrase est celle que le code a écrite, telle quelle. |
Exemples
Un débit négocié sous le débit attendu, que l’administrateur règle sur la sonde.
watch.custom('speed-degraded', 'Débit négocié dégradé', array(
'help' => "Alerte quand le débit négocié est sous le débit attendu ; critique quand l'interface est en half-duplex.",
'settings' => array(
'expected' => array('label' => 'Débit attendu', 'form' => 'number', 'unit' => 'Mbit/s', 'default' => 1000),
),
)); Un agrégat dégradé, avec un seul réglage.
watch.custom('bond-degraded', 'Agrégat dégradé', array(
'help' => "Alerte quand un membre d'un agrégat tombe ; critique quand il n'en reste qu'un nombre donné.",
'settings' => array(
'remaining' => array('label' => "Critique s'il n'en reste que", 'form' => 'number', 'default' => 1),
),
)); Fautes signalées par le master
option_missing: Une option obligatoire absente :helpd’uncustom, oulabeletformd’un réglage.option_invalid: Une option hors de sa forme, avec le chemin de la clé (settings.expected.form).option_unknown: Une clé qui n’est ni une option commune ni un réglage connu.declared_twice: Un nom de surveillance déclaré deux fois.
watch.setting
watch.setting lit, dans le code, un réglage d’une surveillance custom tel que la sonde le porte, c’est-à-dire tel que l’administrateur l’a laissé ou changé.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un texte écrit en clair | oui | L’identifiant d’une surveillance custom déclarée. |
$setting | un texte écrit en clair | oui | Le nom d’un de ses réglages. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La valeur du réglage | un nombre pour number, un nombre de secondes pour duration, une liste pour names, un texte pour text | Le réglage a une valeur. |
'' | texte vide | Le réglage est vide. |
Exemples
Lire un débit attendu, et ne comparer que s’il est renseigné.
$expected = watch.setting('speed-degraded', 'expected');
if ($expected != '' && $speed < $expected) {
watch.raise('speed-degraded', 'warning', $name . ' négocié à ' . $speed . ' Mbit/s', $name);
} Fautes signalées par le master
watch_unknown: Une surveillance qui n’est pas déclarée.watch_not_custom: Une surveillance d’un autre genre quecustom.watch_setting_unknown: Un réglage que la surveillance ne déclare pas.argument_not_literal: Un identifiant ou un réglage qui n’est pas écrit en clair.
watch.raise
watch.raise lève une surveillance custom à un niveau, avec une phrase. La levée se rattache à une instance quand le code en donne une.
Une levée d’une surveillance que la sonde ne coche pas, ou d’une instance hors de la sélection, est ignorée. Pour un custom levé deux fois sur la même instance, le plus grave l’emporte, et le premier à gravité égale.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$id | un texte écrit en clair | oui | L’identifiant d’une surveillance custom déclarée. |
$state | warning ou critical, écrit en clair | oui | Le niveau levé. |
$message | un texte | oui | La phrase qui dit pourquoi. |
$instance | un texte | non (aucune) | L’instance que la levée concerne. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | watch.raise ne rend pas de valeur. |
| Un arrêt, état MISCONFIGURED | — | Le message contient un secret. |
Exemples
Lever un avertissement sur une interface.
watch.raise('speed-degraded', 'warning', $name . ' négocié à ' . $speed . ' Mbit/s', $name); Lever le niveau critique pour un half-duplex.
if ($f['duplex'] == 'half') {
watch.raise('speed-degraded', 'critical', $name . ' en half-duplex', $name);
} Fautes signalées par le master
watch_unknown: Une surveillance qui n’est pas déclarée.watch_not_custom: Une surveillance d’un autre genre quecustom.watch_state_invalid: Un état hors dewarningetcritical.secret_written: Un secret visible à la lecture passé àwatch.raise.
Les protocoles
Une fonction s’écrit domaine.méthode, en anglais, sans aucun blanc autour du point. Le premier argument d’une fonction est toujours ce sur quoi elle agit. Un appel de protocole prend en arguments positionnels ce sur quoi il agit, et ses détails en arguments nommés, tous facultatifs. Un nombre d’arguments positionnels hors de ceux que la fonction prend est une faute (argument_count).
ssh, snmp, tls, winrm, icmp et tcp joignent l’adresse de l’hôte, host:address ; http joint l’adresse que l’appel écrit ; google.token, le serveur de jetons de Google ; ntp et dns interrogent leur serveur, jamais l’hôte. Chacun lit ses accès dans les seules variables standard de son protocole que le collecteur déclare avec need. La connexion se règle dans l’arbre, jamais dans le code : le port, le délai, la clé d’hôte SSH, le profil TLS et l’empreinte d’un certificat sont des variables que l’administrateur pose sur un dossier, un hôte ou une sonde. L’appel dit seulement ce que la requête demande à la cible. Seules les fonctions tls prennent leurs réglages en arguments, puisqu’elles testent ce qu’un serveur accepte.
Un appel qui échoue arrête le collecteur, dans l’état que donne la table des échecs. Pour décider vous-même, demandez-le à l’appel avec errors=$err. Un code HTTP 500 est une réponse, qui se rend comme une valeur.
Les arguments nommés : nom=valeur
Un argument nommé s’écrit nom=valeur, dans la liste des arguments d’un appel, après ses arguments positionnels, dans l’ordre que vous voulez : http.get($url, headers=array('Accept' => 'application/json'), errors=$err). Les arguments positionnels disent ce sur quoi l’appel agit : l’adresse, la commande, l’OID. Les arguments nommés en disent les détails, et tous sont facultatifs.
Seules les fonctions de protocole en prennent, chacune les siens ; les outils, vos fonctions et les déclarations n’en prennent aucun. Il n’y a qu’une forme : un détail ne se passe jamais en positionnel, et http.get($url, $headers) est refusé.
| Fonction | Arguments nommés |
|---|---|
ssh.run | arguments=, errors= |
winrm.run | errors= |
snmp.get, snmp.walk, snmp.table, snmp.date | errors= |
http.get, http.delete | headers=, user=, password=, errors= |
http.post, http.put | headers=, user=, password=, public=, errors= |
tls.inspect | name=, authorities=, preamble=, errors= |
tls.try | name=, preamble=, errors= |
ntp.time, icmp.ping, dns.resolve, tcp.connect, google.token | errors= |
Dans une liste d’arguments, un nom suivi du seul = ouvre toujours un argument nommé ; un argument écrit $a == 1 reste une comparaison. Hors d’une liste d’arguments, = ne fait qu’une affectation.
Une valeur écrite en clair se juge dès la validation. Une valeur calculée se juge à l’exécution, et la même faute arrête alors le collecteur sur l’état MISCONFIGURED.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
nom | l’un des noms que la fonction prend, une seule fois par appel | oui | Le détail que l’argument donne. |
valeur | une expression, dans la forme que le nom demande | oui | La valeur du détail. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Ce que rend l’appel | celle de la fonction | Un argument nommé ne change pas ce que rend l’appel. errors= remplit en plus la variable qu’il nomme. |
Exemples
Un en-tête, puis l’échec rattrapé, après l’adresse.
$answer = http.get($url, headers=array('Accept' => 'application/json'), errors=$err); Les arguments nommés vont dans l’ordre que vous voulez : ces deux appels font la même requête.
$first = http.get($url, user=$user, password=$password);
$second = http.get($url, password=$password, user=$user); Les arguments d’une commande SSH, chacun séparé et protégé.
$units = ssh.run('systemctl is-active', arguments=array('nginx', 'sshd')); Fautes signalées par le master
argument_count: Un nombre d’arguments positionnels hors de ceux que la fonction prend. L’ancienne formehttp.get($url, $headers)en est un.named_argument_unknown: Un nom que la fonction ne prend pas :timeout=surhttp.get, ou n’importe quel nom sur un outil.named_argument_twice: Le même nom deux fois dans un appel.positional_after_named: Un argument positionnel placé après un argument nommé.named_argument_missing:user=sanspassword=, ou l’inverse : ils vont ensemble.named_argument_invalid: Une valeur écrite en clair hors de sa forme :arguments=qui n’est pas une liste,headers=qui n’est pas unarray(…)de paires, un en-têteAuthorizationà côté deuser=, un compte qui contient:.errors_not_variable:errors=suivi d’autre chose qu’une variable seule :errors='x',errors=$e['k'].
errors= : rattraper l’échec d’un appel
Par défaut, un appel de protocole qui échoue arrête le collecteur, dans l’état que la table ci-dessous donne. Le message de la sonde porte le code, le texte et les détails de l’échec, et sa ligne. Un collecteur qui n’a rien demandé ne reçoit donc jamais un résultat vide : un snmp.table en échec ne rend pas une table vide qu’un foreach traverserait sans rien rendre.
Pour décider vous-même, demandez-le à l’appel avec errors=$err, une variable que vous nommez. L’erreur n’est pas mêlée au résultat : l’appel rend ce qu’il rend toujours, et remplit la variable, qu’il réussisse ou non, d’un tableau de trois clés, code, text et details. Sur un échec qu’il rattrape, l’appel rend '' et le collecteur continue. Testez l’échec par $err['code'] != ''.
errors= ne vaut que pour son appel : il n’y a ni try ni catch, et le reste du code se lit comme toujours. Il vaut affectation de la variable, qu’il remplace entière à chaque appel. Un collecteur qui l’écrit a choisi de tester l’échec : lire $answer['status'] d’un appel en échec, qui a rendu '', arrête le collecteur sur l’état MISCONFIGURED.
Certains échecs ne se rattrapent jamais et arrêtent toujours le collecteur : un refus de la vérification de la connexion (le profil TLS, l’empreinte d’un certificat, la clé d’hôte SSH), que l’arbre règle et que le code ne touche pas ; une faute du code ou de la configuration constatée avant que rien ne parte, comme un secret envoyé vers une adresse http://, un poller sans droit d’envoyer de l’ICMP, ou une clé de compte de service Google illisible ; un plafond du poller, une réponse trop grosse comprise ; une erreur d’exécution.
La table des échecs :
| Code | Quand | details | Appels | État sans errors= | Rattrapé par errors= |
|---|---|---|---|---|---|
timeout | La cible ne répond pas dans le délai de son protocole. En SNMP v2c, une communauté fausse se voit ainsi : l’agent se tait. | seconds | tous, sauf icmp.ping et tcp.connect, pour qui le silence est une réponse | UNREACHABLE | oui |
connection_refused | La cible refuse la connexion : aucun service sur ce port. | — | tous, sauf icmp.ping et tcp.connect, pour qui le refus est une réponse | UNREACHABLE | oui |
host_unknown | Le nom de l’adresse ne se résout pas ; pour dns.resolve, celui de son serveur, le nom demandé rendant toujours une réponse (NXDOMAIN). | — | tous | UNREACHABLE | oui |
network_error | Toute autre panne entre le poller et la cible : aucune route, une connexion coupée, une réponse que le protocole ne lit pas. | — | tous | UNREACHABLE | oui |
access_denied | La cible refuse l’accès : un compte SSH refusé, un utilisateur ou un mot de passe SNMP v3 refusé, un OID que l’agent interdit, un compte que le service WinRM refuse, une clé ou une portée que le serveur de jetons de Google refuse. | — | ssh.run, snmp.*, winrm.run, google.token | MISCONFIGURED | oui |
snmp_not_found | L’agent n’a pas cet OID. | — | snmp.get, snmp.date | MISCONFIGURED | oui |
snmp_date_invalid | La valeur n’est pas un instant : pas une chaîne de 11 octets dont chaque champ tient dans les bornes de la RFC 2579 (une autre syntaxe, une autre longueur, un mois 13). Une chaîne de 8 octets, sans son décalage à UTC, en est une aussi : l’instant ne se devine pas. | — | snmp.date | MISCONFIGURED | oui |
snmp_error | L’agent répond par une autre erreur. | status : son nom (genErr, tooBig…) | snmp.* | UNREACHABLE | oui |
ntp_answer_invalid | Le serveur de temps répond sans donner une heure sûre : un refus (kiss-of-death, strate 0), un serveur qui se dit non synchronisé (strate 16, ou indicateur de saut à 3), une réponse qui n’est pas celle d’un serveur à cette requête. | — | ntp.time | UNREACHABLE | oui |
icmp_not_permitted | Le poller n’a pas le droit d’envoyer de l’ICMP, constaté avant que rien ne parte : une faute de la configuration du poller, que l’auteur ne corrige pas. | — | icmp.ping | MISCONFIGURED | non |
ssh_handshake_failed | La poignée de main SSH échoue : aucun algorithme commun, ou le serveur ferme. | — | ssh.run | UNREACHABLE | oui |
winrm_error | Le service WinRM refuse la requête par une faute WS-Management, hors d’un compte refusé : un interpréteur qu’il n’ouvre pas, un quota atteint. | fault : le code de la faute, tel que le service l’écrit | winrm.run | UNREACHABLE | oui |
tls_handshake_failed | La poignée de main TLS échoue sans qu’un refus du profil l’explique : le serveur ne parle pas TLS sur ce port, ou rien que le poller connaisse. Pour tls.try, un serveur qui refuse la poignée donne une réponse, pas un échec. | alert | http.* en https://, tls.*, winrm.run, google.token | UNREACHABLE | oui |
tls_version_refused, tls_suite_refused, tls_certificate_expired, tls_certificate_not_yet_valid, tls_certificate_name_mismatch, tls_certificate_untrusted, tls_certificate_invalid | Les refus du profil TLS de la sonde ; pour google.token, du profil « Standard ». | leurs paramètres | http.* en https://, winrm.run, google.token | MISCONFIGURED | non |
fingerprint_mismatch | L’empreinte présentée, d’une clé d’hôte SSH ou d’un certificat, n’est pas celle qu’épingle la variable de son protocole (protocol:ssh:fingerprint, protocol:http:fingerprint, protocol:winrm:fingerprint). | expected, found | ssh.run, http.* en https://, winrm.run | MISCONFIGURED | non |
fingerprint_changed | L’empreinte présentée n’est plus celle que la sonde a retenue pour cet hôte et ce port, et aucune mise à jour ne la remplace. | expected, found | ssh.run, http.* en https://, winrm.run | MISCONFIGURED | non |
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
errors=$err | une variable seule | non (l’échec arrête le collecteur) | La variable que l’appel remplit, qu’il réussisse ou non. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
$err['code'] | texte | '' quand l’appel réussit ; sinon le code de l’échec, l’un de ceux de la table. |
$err['text'] | texte | '' quand l’appel réussit ; sinon le texte de l’échec, en anglais, tel que la bibliothèque du protocole le donne. Il se montre ; pour décider, lisez le code. |
$err['details'] | tableau | array() quand l’appel réussit ; sinon les détails que la table donne à son code. |
'', rendu par l’appel | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Un site qui ne répond pas est hors service : le collecteur le dit critique, plutôt que de laisser la sonde injoignable.
$answer = http.get($url, errors=$err);
if ($err['code'] == 'connection_refused' || $err['code'] == 'timeout') {
fail('critical', 'Site hors service', $err['text']);
}
if ($err['code'] != '') {
fail('unreachable', 'Site injoignable', $err['text']);
}
value('code', $answer['status']); Un OID que l’agent n’a pas, remplacé par un texte.
$name = snmp.get('1.3.6.1.2.1.1.5.0', errors=$err);
if ($err['code'] == 'snmp_not_found') {
$name = 'inconnu';
} Fautes signalées par le master
errors_not_variable:errors=suivi d’autre chose qu’une variable seule.named_argument_twice:errors=écrit deux fois dans un appel.
ssh.run
ssh.run lance une commande sur la cible, par SSH, et rend sa sortie, ses messages d’erreur et son code de sortie. L’empreinte de la clé d’hôte (protocol:ssh:fingerprint) est vérifiée avant l’envoi de tout identifiant.
Ce que la commande fait sur la cible est au jugement de celui qui écrit le collecteur. banshee lit les cibles ; la relecture du diff sur le poller est la barrière.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$command | un texte | oui | La commande à lancer. |
arguments= | une liste de textes | non (aucun) | Les arguments de la commande. Chacun part séparé et protégé, jamais collé dans la commande. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La sortie, les erreurs et le code de sortie | array('output' => texte, 'errors' => texte, 'exit' => nombre) | La commande s’est exécutée, quel que soit son code de sortie. |
| Un arrêt, état UNREACHABLE | — | Pas de réponse de la cible, ou une poignée de main SSH qui échoue : timeout, connection_refused, host_unknown, network_error, ssh_handshake_failed. |
| Un arrêt, état MISCONFIGURED | — | Accès refusés (access_denied), ou une empreinte qui n’est pas celle attendue (fingerprint_mismatch, fingerprint_changed, jamais rattrapées). |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Lire les compteurs de processeur d’un Linux.
need('protocol:ssh');
$stat = ssh.run('grep ^cpu /proc/stat'); Vérifier le code de sortie avant de lire la sortie.
$df = ssh.run('df -P -k');
if ($df['exit'] != 0) {
fail('unreachable', 'df a échoué', $df['errors']);
} Passer un argument à part de la commande.
$load = ssh.run('cat', arguments=array('/proc/loadavg')); winrm.run
winrm.run lance un script PowerShell sur la cible, par WinRM, et rend sa sortie, ses messages d’erreur et son code de sortie, de la même façon que ssh.run. WinRM lance PowerShell lui-même : le script s’écrit tel quel, sans powershell -Command autour.
WinRM ne passe qu’en HTTPS, au port de protocol:winrm:port (5986 par défaut). La connexion suit le profil TLS de la sonde, comme une requête https://, et le certificat est jugé, ou son empreinte épinglée dans protocol:winrm:fingerprint vérifiée, avant l’envoi de tout identifiant. Le compte est celui de protocol:winrm:user et protocol:winrm:password, par NTLM : le mot de passe ne part jamais, seule une réponse calculée avec lui.
L’appel demande la famille need('protocol:winrm'). Ce que le script fait sur la cible est laissé au jugement de qui écrit le collecteur, comme pour une commande SSH.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$script | un texte | oui | Le script PowerShell à lancer. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La sortie, les erreurs et le code de sortie | array('output' => texte, 'errors' => texte, 'exit' => nombre) | Le script a tourné, quel que soit son code de sortie. |
| Un arrêt, état UNREACHABLE | — | Aucune réponse de la cible (timeout, connection_refused, host_unknown, network_error), une poignée de main TLS qui échoue (tls_handshake_failed), ou une faute du service (winrm_error). |
| Un arrêt, état MISCONFIGURED | — | Un compte refusé (access_denied), un refus du profil TLS, ou une empreinte qui n’est pas celle attendue (fingerprint_mismatch, fingerprint_changed) : ces deux derniers genres ne se rattrapent jamais. |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Lire la date d’un Windows.
need('protocol:winrm');
$date = winrm.run('Get-Date -Format o'); Vérifier le code de sortie avant de lire la sortie.
$read = winrm.run('Get-Service -Name Spooler | Select-Object -ExpandProperty Status');
if ($read['exit'] != 0) {
fail('unreachable', 'PowerShell a échoué', $read['errors']);
} Fautes signalées par le master
need_missing: Un appel sansneed('protocol:winrm')dans l’en-tête.named_argument_unknown:arguments=, quewinrm.runne prend pas : écrivez les valeurs dans le script.
snmp.get
snmp.get lit un OID, l’adresse d’une information dans un équipement, et rend sa valeur. L’OID s’écrit entre apostrophes : sans elles, 1.3.6.1.2.1.1.5.0 est un nombre mal formé.
Une chaîne d’octets se rend en texte quand ses octets sont un texte imprimable. Sinon, binaire comme une adresse MAC ou écrite dans un autre encodage qu’UTF-8, elle se rend hex: suivi de ses octets en hexadécimal minuscule : hex:001a2b3c4d5e. Une valeur qui commence par hex: est toujours de l’hexadécimal : un texte imprimable qui commence ainsi s’écrit lui aussi en hexadécimal. Une chaîne binaire dont chaque octet se trouve imprimable se rend en texte, et hex.encode en rend les octets.
La lecture est seule : il n’existe pas de snmp.set.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$oid | un texte | oui | L’OID à lire. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La valeur lue | la valeur de l’OID | L’équipement répond. |
| Un arrêt, état UNREACHABLE | — | Pas de réponse de la cible (timeout, connection_refused, host_unknown, network_error), ou une autre erreur de l’agent (snmp_error). |
| Un arrêt, état MISCONFIGURED | — | Accès refusés (access_denied), ou un OID que l’agent n’a pas (snmp_not_found). |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Lire le nom d’un équipement.
need('protocol:snmp');
value('system-name', snmp.get('1.3.6.1.2.1.1.5.0')); Lire la durée depuis le démarrage, en centièmes de seconde, et la convertir en jours.
value('uptime', number.round(snmp.get('1.3.6.1.2.1.1.3.0') / 8640000, 1)); Lire une adresse MAC, toujours en hexadécimal.
$mac = snmp.get('1.3.6.1.2.1.2.2.1.6.1');
if (text.like($mac, 'hex:*')) {
$parts = text.split($mac, ':');
$mac = $parts[1];
} else {
$mac = hex.encode($mac);
} Fautes signalées par le master
function_unknown: Une fonction qui n’existe pas :snmp.set.
snmp.walk
snmp.walk lit toute une branche de l’arbre SNMP et rend ses valeurs dans un tableau, rangées sous la fin de leur OID.
Chaque valeur suit la règle de snmp.get : une chaîne d’octets qui n’est pas un texte imprimable se rend hex: et son hexadécimal.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$oid | un texte | oui | L’OID de la branche à lire. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Les valeurs de la branche | array(suffixe => valeur) | L’équipement répond. Une branche vide est une réponse : array(). |
| Un arrêt, état UNREACHABLE | — | Pas de réponse de la cible (timeout, connection_refused, host_unknown, network_error), une autre erreur de l’agent (snmp_error), ou une table trop longue. |
| Un arrêt, état MISCONFIGURED | — | Accès refusés (access_denied). |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Lire les noms de toutes les interfaces et parcourir le résultat.
$names = snmp.walk('1.3.6.1.2.1.31.1.1.1.1');
foreach ($names as $index => $name) {
// $index est le suffixe de l'OID, $name sa valeur.
} snmp.table
snmp.table lit plusieurs colonnes d’un équipement et les rapproche par leur index, pour que chaque ligne rassemble ce qui concerne le même objet. C’est le plus court chemin pour lire, par exemple, le nom, la vitesse et l’état de chaque interface.
Chaque valeur suit la règle de snmp.get : une chaîne d’octets qui n’est pas un texte imprimable se rend hex: et son hexadécimal.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$columns | un array(colonne => oid, …) | oui | Les colonnes à lire : le nom que vous donnez à chacune, et son OID. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Les lignes de la table | array(index => array(colonne => valeur)) | Une ligne par index présent dans au moins une colonne. Une colonne absente pour un index n’est pas dans sa ligne. |
| Un arrêt, état UNREACHABLE | — | Pas de réponse de la cible (timeout, connection_refused, host_unknown, network_error), une autre erreur de l’agent (snmp_error), ou une table trop longue. |
| Un arrêt, état MISCONFIGURED | — | Accès refusés (access_denied). |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. Sans errors=, un échec ne rend jamais une table vide. |
Exemples
Lire le nom, la vitesse et l’état de chaque interface.
$interfaces = snmp.table(array(
'name' => '1.3.6.1.2.1.31.1.1.1.1',
'speed' => '1.3.6.1.2.1.31.1.1.1.15',
'status' => '1.3.6.1.2.1.2.2.1.8',
)); Rendre une valeur par interface, nommée par la colonne name.
foreach ($interfaces as $index => $row) {
value('status', $row['status'], $row['name']);
value('speed', $row['speed'], $row['name']);
} snmp.date
snmp.date lit, comme snmp.get, un OID de syntaxe DateAndTime (RFC 2579), comme l’heure système d’un hôte, et la ramène à UTC par le décalage que la valeur porte. Elle rend un instant, en secondes depuis le 1er janvier 1970 UTC, au dixième : la forme de time.now, pour que les deux se soustraient.
Une valeur de 8 octets, sans décalage à UTC, est un échec (snmp_date_invalid) : la RFC la dit à l’heure locale de l’agent, sans dire laquelle, et la prendre pour UTC donnerait un instant faux de tout le fuseau, sans bruit.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$oid | un texte | oui | L’OID à lire, de syntaxe DateAndTime. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| L’instant | un nombre, en secondes depuis le 1er janvier 1970 UTC, au dixième | L’équipement répond par un DateAndTime de 11 octets. |
| Un arrêt, état UNREACHABLE | — | Aucune réponse de la cible (timeout, connection_refused, host_unknown, network_error), ou une autre erreur de l’agent (snmp_error). |
| Un arrêt, état MISCONFIGURED | — | Des accès refusés (access_denied), un OID que l’agent n’a pas (snmp_not_found), ou une valeur qui n’est pas un instant (snmp_date_invalid). |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
L’heure système d’un hôte, hrSystemDate.
need('protocol:snmp');
$date = snmp.date('1.3.6.1.2.1.25.1.2.0'); Fautes signalées par le master
argument_count:snmp.date(), sans OID.
http.get
http.get envoie une requête GET et rend le code de réponse, les en-têtes, le corps et le temps de réponse. Seules les adresses http:// et https:// sont permises, et aucune redirection n’est suivie : une réponse 3xx se rend telle quelle, et l’adresse où elle renvoie se lit dans headers, sous location.
Une connexion https:// suit le profil TLS de la sonde, que l’administrateur règle dans l’arbre : ses versions, ses suites et le jugement du certificat, ou l’empreinte épinglée (protocol:http:fingerprint). Une connexion que le profil refuse arrête le collecteur. Un code 500 est une réponse, pas un arrêt.
L’appel demande la famille need('protocol:http'), qui lui apporte le délai, l’empreinte, le User-Agent et le profil TLS de la sonde : sans elle, c’est une faute (need_missing).
Les en-têtes (headers=) partent tels que vous les écrivez. Le type d’un corps est l’en-tête Content-Type que vous écrivez. Un nom ou une valeur hors de la forme d’un en-tête, comme un saut de ligne dans une valeur, arrête le collecteur.
Le User-Agent est la valeur de protocol:http:user-agent de la sonde, banshee/ suivi de la version du poller sans valeur ; un en-tête User-Agent écrit dans l’appel l’emporte. Un en-tête Host écrit dans l’appel est le site que la requête demande, pour un serveur à plusieurs sites joint par son adresse IP : il ne change ni l’adresse jointe, ni le nom que la poignée TLS annonce et juge, qui sont ceux de l’adresse ou de protocol:tls:server-name.
user= et password= envoient un compte en Basic, dans l’en-tête Authorization que http compose. L’un ne va pas sans l’autre, jamais avec un en-tête Authorization écrit dans headers=, et le compte ne contient pas :. Un user= qui vaut '' n’envoie aucun compte : un collecteur dont le compte est facultatif écrit l’appel une seule fois.
http n’ajoute aucun accès de lui-même : un compte ou un jeton ne part que si l’appel l’écrit. La réponse d’une requête dont le corps portait un secret est secrète, sauf son code et son temps ; un secret passé dans un en-tête ne rend pas, à lui seul, la réponse secrète. Mais toute partie d’une réponse qui contient un secret de la sonde, son texte, son base64 ou son encodage d’adresse, est secrète, quoi que la requête ait porté : voir secret.mark.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$url | un texte, commençant par http:// ou https:// | oui | L’adresse à interroger. |
headers= | array(nom => valeur) | non (aucun) | Les en-têtes de la requête. |
user= | un texte sans : | non (aucun compte), avec password= | Le compte envoyé en Basic. '' n’envoie aucun compte. |
password= | un texte | non (aucun compte), avec user= | Le mot de passe de ce compte. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La réponse | array('status' => nombre, 'headers' => array(nom => valeur), 'body' => texte, 'time' => nombre) | Le serveur répond, quel que soit son code. Les noms d’en-têtes sont en minuscules, un en-tête répété est joint par , , le temps est en millisecondes. |
| Un arrêt, état UNREACHABLE | — | Pas de réponse de la cible (timeout, connection_refused, host_unknown, network_error), une poignée de main TLS qui échoue (tls_handshake_failed), ou une réponse trop grosse. |
| Un arrêt, état MISCONFIGURED | — | Le profil TLS de la sonde refuse la connexion (jamais rattrapé), un secret part dans une requête http://, ou un en-tête est hors de sa forme. |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Demander une page et en lire le code et le temps.
need('protocol:http');
$answer = http.get('https://www.example/');
value('code', $answer['status']);
value('response-time', $answer['time']); Envoyer un jeton dans un en-tête.
need('protocol:http');
$token = need('protocol:http:token');
$answer = http.get($url, headers=array('Authorization' => 'Bearer ' . $token)); Envoyer un compte facultatif : sans compte posé sur la sonde, la requête part sans.
need('protocol:http');
$user = need('protocol:http:user', 'optional');
$password = need('protocol:http:password', 'optional');
$answer = http.get($url, user=$user, password=$password); Lire l’adresse où le site renvoie.
need('protocol:http');
$answer = http.get($url);
if ($answer['status'] == 301) {
$target = $answer['headers']['location'];
} Fautes signalées par le master
need_missing: Un appel sansneed('protocol:http')dans l’en-tête.named_argument_missing:user=sanspassword=, ou l’inverse.named_argument_invalid: Un en-têteAuthorizationà côté deuser=, quelle que soit sa casse, un compte qui contient:, ouheaders=qui n’est pas unarray(…)de paires.
http.post
http.post envoie une requête POST, dont le corps est un texte, et rend la même réponse que http.get. Les mêmes règles s’appliquent : http:// et https:// seulement, aucune redirection suivie, aucun accès ajouté par http, la famille need('protocol:http') demandée.
Ce que la requête fait sur la cible est au jugement de celui qui écrit le collecteur. Il existe quatre méthodes HTTP, et aucune autre : http.get, http.post, http.put et http.delete.
La réponse d’une requête dont le corps porte un secret est secrète. Certaines API ne prennent leur clé que dans le corps, et ne la rendent pas : public=true déclare alors que la réponse ne porte aucun jeton, et elle se lit comme une autre. Ce qui contient un secret de la sonde reste secret malgré la déclaration. Déclarer sans jeton la réponse d’un login expose le jeton qu’elle rend : c’est votre jugement, et la documentation du collecteur dit pourquoi la réponse n’en porte pas.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$url | un texte, commençant par http:// ou https:// | oui | L’adresse à interroger. |
$body | un texte | oui | Le corps de la requête. |
headers=, user=, password=, errors= | comme pour http.get | non | Comme pour http.get. |
public= | true ou false, écrit en clair | non (false) | Déclare que la réponse d’un corps qui porte un secret ne porte aucun jeton. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La réponse | array('status' => nombre, 'headers' => array(nom => valeur), 'body' => texte, 'time' => nombre) | Comme pour http.get. |
| Un arrêt, état UNREACHABLE ou MISCONFIGURED | — | Comme pour http.get. |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Se connecter à une API avec un compte, et lire le jeton rendu.
$body = json.write(array('username' => $user, 'password' => $password));
$answer = http.post($base . '/api/v1/login', $body, headers=array('Content-Type' => 'application/json'));
$session = json.read($answer['body']); Lire une API qui ne prend sa clé que dans le corps, et dont la réponse ne porte aucun jeton.
need('protocol:http');
$key = need('protocol:http:token');
$answer = http.post('https://api.example/info', json.write(array('key' => $key)),
headers=array('Content-Type' => 'application/json'), public=true);
$info = json.read($answer['body']); Fautes signalées par le master
need_missing: Un appel sansneed('protocol:http')dans l’en-tête.named_argument_invalid:public=qui n’est pastrueoufalseécrit en clair, une valeur calculée comprise.
http.put
http.put envoie une requête PUT, dont le corps est un texte, et rend la même réponse que http.get. Les mêmes règles s’appliquent : http:// et https:// seulement, aucune redirection suivie, aucun accès ajouté par http, la famille need('protocol:http') demandée.
Ce que la requête fait sur la cible est au jugement de celui qui écrit le collecteur, comme pour http.post. Certaines API ouvrent une session par un PUT, et la ferment par un http.delete.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$url | un texte, commençant par http:// ou https:// | oui | L’adresse à interroger. |
$body | un texte | oui | Le corps de la requête. |
headers=, user=, password=, errors= | comme pour http.get | non | Comme pour http.get. |
public= | comme pour http.post | non (false) | Comme pour http.post. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La réponse | array('status' => nombre, 'headers' => array(nom => valeur), 'body' => texte, 'time' => nombre) | Comme pour http.get. |
| Un arrêt, état UNREACHABLE ou MISCONFIGURED | — | Comme pour http.get. |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Ouvrir une session, et lire le jeton rendu.
$body = json.write(array('username' => $user, 'password' => $password));
$answer = http.put($base . '/api/session', $body, headers=array('Content-Type' => 'application/json'));
$session = json.read($answer['body']); Fautes signalées par le master
need_missing: Un appel sansneed('protocol:http')dans l’en-tête.argument_count:http.put($url), sans corps.
http.delete
http.delete envoie une requête DELETE, sans corps, et rend la même réponse que http.get. Les mêmes règles s’appliquent : http:// et https:// seulement, aucune redirection suivie, aucun accès ajouté par http, la famille need('protocol:http') demandée.
Ce que la requête fait sur la cible est au jugement de celui qui écrit le collecteur, comme pour http.post. Elle sert d’abord à fermer la session qu’un collecteur a ouverte, pour qu’un passage ne laisse rien derrière lui sur la cible.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$url | un texte, commençant par http:// ou https:// | oui | L’adresse à interroger. |
headers=, user=, password=, errors= | comme pour http.get | non | Comme pour http.get. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La réponse | array('status' => nombre, 'headers' => array(nom => valeur), 'body' => texte, 'time' => nombre) | Comme pour http.get. |
| Un arrêt, état UNREACHABLE ou MISCONFIGURED | — | Comme pour http.get. |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Fermer la session ouverte par le collecteur, sans l’arrêter si la fermeture échoue.
$closed = http.delete($base . '/api/session', headers=array('Authorization' => 'Bearer ' . $session['token']), errors=$err); Fautes signalées par le master
need_missing: Un appel sansneed('protocol:http')dans l’en-tête.argument_count:http.delete($url, $body): une requête DELETE n’a pas de corps.
tls.inspect
tls.inspect fait une poignée de main TLS vers l’adresse de l’hôte, host:address, au port donné, sans rien envoyer d’autre. Elle propose tout ce que le poller parle, lit le certificat présenté et le juge sans jamais refuser : elle rend ce qu’elle a trouvé.
Elle ignore le profil TLS hérité : elle ne lit aucune variable protocol:tls, et ses arguments disent ce qu’elle essaie. Un texte vide vaut un argument absent, pour que le collecteur écrive l’appel une seule fois, quel que soit le réglage de la sonde.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$port | un entier de 1 à 65 535 | oui | Le port à joindre. |
name= | un texte | non (le nom de host:address, ou aucun pour une adresse IP) | Le nom attendu sur le certificat, aussi annoncé au serveur. |
authorities= | un texte de blocs PEM | non (aucune) | Des autorités ajoutées à celles du système. |
preamble= | rdp | non (aucun) | Pour le Bureau à distance, qui ne commence pas par TLS : la demande de connexion RDP part d’abord, puis la poignée de main. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Ce que la poignée a trouvé | array('version', 'suite', 'suite_group', 'trusted', 'name_matches', 'chain', 'untrusted_reason', 'certificates') | La poignée aboutit. version : 1.0 à 1.3 ; suite_group : strong, acceptable, weak ou tls13 ; trusted et name_matches : true ou false ; chain : complete ou incomplete ; untrusted_reason : '', expired, not_yet_valid, incomplete_chain, unknown_authority ou insecure_signature ; certificates : la chaîne présentée, le certificat du serveur d’abord. |
| Chaque certificat | array('subject', 'issuer', 'names', 'not_before', 'not_after', 'days_left', 'self_issued', 'key', 'key_bits', 'signature', 'fingerprint') | Dans certificates. days_left est décimal, négatif une fois le certificat expiré ; key vaut rsa, ecdsa ou ed25519 ; fingerprint commence par sha256:. |
| Un arrêt, état UNREACHABLE | — | Le port ne répond pas, le serveur ne parle pas TLS, ou la poignée échoue (tls_handshake_failed). |
| Un arrêt, état MISCONFIGURED | — | Un argument hors de sa forme, jamais rattrapé. |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Lire le certificat d’un site et les jours qui lui restent.
need('host:address');
$found = tls.inspect(443);
$days = $found['certificates'][0]['days_left']; Un nom attendu et le Bureau à distance, l’échec rattrapé.
$found = tls.inspect(3389, name='web.example', preamble='rdp', errors=$err); Fautes signalées par le master
named_argument_unknown: Un nom que la fonction ne prend pas.named_argument_invalid: Une valeur écrite en clair hors de sa forme :preamble='ssh'.argument_count:tls.inspect(), sans port.
tls.try
tls.try fait une poignée de main qui ne propose que cette version et, si vous la nommez, que cette suite : elle dit si le serveur les accepte. Elle ne juge pas le certificat. Un refus du serveur est une réponse, pas un échec : c’est ce que la sonde cherche.
Comme tls.inspect, elle ignore le profil TLS hérité, et un texte vide vaut un argument absent.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$port | un entier de 1 à 65 535 | oui | Le port à joindre. |
$version | 1.0, 1.1, 1.2 ou 1.3 | oui | La seule version proposée. |
$suite | le nom d’une suite permise à cette version, ou '' | non (toutes les suites de la version) | La seule suite proposée. Jamais avec 1.3. |
name=, preamble=, errors= | comme pour tls.inspect | non | Comme pour tls.inspect ; authorities= n’existe pas ici. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La réponse du serveur | array('accepted' => booléen, 'version' => texte, 'suite' => texte, 'alert' => texte) | accepted vrai quand la poignée aboutit, avec la version et la suite négociées ; faux quand le serveur la refuse, avec le nom de l’alerte ('' sans alerte), et version et suite vides. |
| Un arrêt, état UNREACHABLE | — | Le port ne répond pas. |
| Un arrêt, état MISCONFIGURED | — | Un argument hors de sa forme, une suite avec la version 1.3 comprise. |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Savoir si le serveur accepte encore TLS 1.0.
need('host:address');
$try = tls.try(443, '1.0');
if ($try['accepted']) {
fail('critical', 'TLS 1.0 accepté', 'Le serveur accepte TLS 1.0.');
} Une suite faible sous TLS 1.2.
$try = tls.try(443, '1.2', 'TLS_RSA_WITH_RC4_128_SHA'); Fautes signalées par le master
tls_version_invalid: Une version écrite en clair hors de1.0,1.1,1.2et1.3:tls.try(443, '1.4').tls_suite_invalid: Une suite écrite en clair hors de la table des suites, que la version écrite ne permet pas, ou avec la version1.3:tls.try(443, '1.2', 'TLS_FOO'),tls.try(443, '1.3', 'TLS_RSA_WITH_RC4_128_SHA').argument_count:tls.try(443), sans version.
ntp.time
ntp.time demande l’heure au serveur de temps de protocol:ntp:server (pool.ntp.org sans valeur), par une requête NTP client, port 123, et la rend telle que le serveur l’a donnée à sa réponse, l’aller-retour compensé comme NTP le fait. Comparée à une heure lue sur un équipement, elle dit de combien son horloge s’écarte.
La requête est une lecture et ne porte aucun accès. L’appel ne joint jamais l’hôte : il n’interroge que le serveur de temps. Il demande la famille need('protocol:ntp'), qui apporte le serveur et son délai.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| L’heure du serveur | un nombre, en secondes depuis le 1er janvier 1970 UTC, au millième | Le serveur répond par une heure sûre. |
| Un arrêt, état UNREACHABLE | — | Aucune réponse du serveur (timeout, host_unknown, network_error), ou une réponse sans heure sûre (ntp_answer_invalid). |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
L’écart de l’horloge d’un Windows au serveur de temps.
need('protocol:snmp');
need('protocol:ntp');
$date = snmp.date('1.3.6.1.2.1.25.1.2.0');
$server = ntp.time();
$offset = $date - $server; Fautes signalées par le master
need_missing: Un appel sansneed('protocol:ntp')dans l’en-tête.argument_count:ntp.time(1): l’appel ne prend aucun argument positionnel.
icmp.ping
icmp.ping envoie des demandes d’écho ICMP à l’adresse de l’hôte, host:address, en IPv4 ou en IPv6, et compte les réponses. Combien partent (protocol:icmp:count, 5 par défaut), combien de temps chacune est attendue (protocol:icmp:timeout, 2 secondes) et à quel écart elles partent (protocol:icmp:interval, 200 millisecondes) sont des réglages de l’arbre, qu’apporte la famille need('protocol:icmp').
Aucune réponse est une réponse, pas un échec : received à 0 et loss à 100. C’est le cas que la sonde surveille. Une réponse arrivée après son délai compte perdue. La requête ne demande rien à l’hôte que sa réponse.
Le poller doit avoir le droit d’envoyer de l’ICMP. Sans ce droit, l’appel arrête le collecteur sur l’état MISCONFIGURED (icmp_not_permitted), et errors= ne le rattrape pas.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le compte des réponses | array('sent' => nombre, 'received' => nombre, 'loss' => nombre, 'rtt_min' => nombre, 'rtt_avg' => nombre, 'rtt_max' => nombre, 'address' => texte) | Toujours, réponses ou non : les demandes envoyées et les réponses reçues, la perte en pourcentage, les temps de réponse en millisecondes ('' sans réponse), et l’adresse jointe. |
| Un arrêt, état UNREACHABLE | — | Un nom qui ne se résout pas (host_unknown), ou une autre panne du côté du poller (network_error). |
| Un arrêt, état MISCONFIGURED | — | Le poller n’a pas le droit d’envoyer de l’ICMP (icmp_not_permitted, jamais rattrapé). |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Un hôte qui ne répond à aucun écho est tombé.
need('protocol:icmp');
$ping = icmp.ping();
if ($ping['received'] == 0) {
fail('critical', 'Hôte tombé', 'Aucune réponse de ' . $ping['address']);
}
value('loss', $ping['loss']); Fautes signalées par le master
need_missing: Un appel sansneed('protocol:icmp')dans l’en-tête.argument_count:icmp.ping(5): le nombre d’échos est un réglage de l’arbre, pas un argument.
dns.resolve
dns.resolve demande à un serveur DNS un nom et un type d’enregistrement, et rend les enregistrements de ce type, le code de la réponse, le plus petit TTL et le temps de la requête. Le serveur est celui de protocol:dns:server, port 53 ; sans lui, le résolveur du système du poller. L’appel ne joint jamais l’hôte. Il demande la famille need('protocol:dns'), qui apporte le serveur et son délai.
Un nom qui n’existe pas est une réponse, pas un échec : rcode dit NXDOMAIN, et answers est vide. De même pour tout autre code du serveur, SERVFAIL ou REFUSED.
Chaque enregistrement est un texte : une adresse pour A et AAAA ; un nom pour CNAME, NS et PTR ; la préférence, une espace et le nom pour MX (10 mail.example) ; les chaînes jointes pour TXT ; les sept champs séparés par une espace pour SOA. Un nom s’écrit en minuscules, sans son point final. Pour PTR, le nom peut être une adresse IP, que l’appel écrit en nom inverse.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$name | un texte | oui | Le nom à résoudre ; pour PTR, une adresse IP ou un nom inverse. |
$type | A, AAAA, CNAME, MX, TXT, NS, SOA ou PTR, en majuscules | oui | Le type d’enregistrement demandé. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La réponse du serveur | array('answers' => liste de textes, 'rcode' => texte, 'ttl' => nombre, 'ms' => nombre) | Le serveur répond, quel que soit son code : les enregistrements du type demandé, dans l’ordre du serveur ; le code de la réponse (NOERROR, NXDOMAIN, SERVFAIL…) ; le plus petit TTL, en secondes, '' sans enregistrement ; le temps de la requête, en millisecondes. |
| Un arrêt, état UNREACHABLE | — | Le serveur ne répond pas (timeout), refuse la requête (connection_refused), ou ne se joint pas (host_unknown, network_error). |
| Un arrêt, état MISCONFIGURED | — | Un type calculé hors des huit. |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Savoir si un nom se résout.
need('protocol:dns');
$found = dns.resolve('www.example', 'A');
$resolved = 'no';
if ($found['rcode'] == 'NOERROR' && list.count($found['answers']) > 0) {
$resolved = 'yes';
} Les serveurs de messagerie d’un domaine.
$mail = dns.resolve('example', 'MX'); Fautes signalées par le master
need_missing: Un appel sansneed('protocol:dns')dans l’en-tête.dns_type_invalid: Un type écrit en clair hors des huit, ou en minuscules :dns.resolve('www.example', 'ANY'),dns.resolve('www.example', 'a').argument_count:dns.resolve('www.example'), sans type.
tcp.connect
tcp.connect ouvre une connexion TCP vers l’adresse de l’hôte, host:address, sur un port, et la referme aussitôt, sans rien envoyer : le service derrière le port ne reçoit aucune requête. Elle dit si le port accepte une connexion, et le temps de son ouverture.
Un port fermé ou filtré est une réponse, pas un échec : open est faux quand l’hôte refuse la connexion, quand rien ne répond dans protocol:tcp:timeout (5 secondes par défaut), ou quand un routeur dit l’hôte injoignable. L’appel demande la famille need('protocol:tcp').
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$port | un entier de 1 à 65 535 | oui | Le port à ouvrir. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| L’état du port | array('open' => booléen, 'ms' => nombre) | Toujours, ouvert ou non : ms est le temps de l’ouverture, en millisecondes, '' quand le port est fermé. |
| Un arrêt, état UNREACHABLE | — | Un nom qui ne se résout pas (host_unknown), ou une autre panne du côté du poller (network_error). |
| Un arrêt, état MISCONFIGURED | — | Un port hors de 1 à 65 535. |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Savoir si SSH écoute.
need('protocol:tcp');
$ssh = tcp.connect(22);
if (!$ssh['open']) {
fail('critical', 'SSH fermé', 'Le port 22 refuse la connexion.');
} Fautes signalées par le master
need_missing: Un appel sansneed('protocol:tcp')dans l’en-tête.argument_count:tcp.connect(), sans port.
Les fournisseurs cloud
Une fonction par fournisseur, qui signe une requête comme il l’exige ou obtient son jeton : aws, ovh, google. Chacune lit les clés de sa famille, déclarée avec need. Une clé secrète ne part jamais : seule la signature part, ou le jeton obtenu avec elle.
Une requête signée part par http.*, avec la méthode, l’adresse et le corps que la signature a reçus, écrits à l’identique : un octet de différence fait refuser la signature par le fournisseur, une réponse d’erreur que le collecteur lit. L’heure de la signature est celle du poller, au moment de l’appel : une horloge fausse fait refuser la requête.
aws.sign
aws.sign signe une requête pour AWS, par la Signature Version 4 (AWS4-HMAC-SHA256), avec les clés de protocol:aws. Elle n’envoie rien : elle rend les en-têtes à passer à headers= de l’appel http.* qui envoie la requête.
Elle rend les en-têtes de $headers, puis Authorization et X-Amz-Date ; X-Amz-Security-Token quand protocol:aws:session-token a une valeur ; X-Amz-Content-Sha256 pour le service s3, qui l’exige. Authorization et X-Amz-Security-Token sont secrets : ils ne vont que dans un appel de protocole ou dans le cache, et un appel http:// qui les porte arrête le collecteur.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$method | GET, POST, PUT ou DELETE, en majuscules | oui | La méthode de la requête. |
$url | une adresse https:// ou http:// entière | oui | L’adresse de la requête, sa requête comprise. |
$headers | un array(nom => valeur), la forme de headers= | oui | Les en-têtes que la requête porte, array() pour aucun. Ni Authorization ni un en-tête X-Amz-… que la fonction compose. |
$body | un texte | oui | Le corps de la requête, '' sans corps. |
$region | un texte non vide, sans / | oui | La région : us-east-1. |
$service | un texte non vide, sans / | oui | Le service : ec2, monitoring, s3. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Les en-têtes de la requête | array(nom => valeur) | Toujours : ceux de $headers, et ceux que la fonction compose. |
| Un arrêt, état MISCONFIGURED | — | Une méthode hors des quatre, une adresse qui n’en est pas une, des en-têtes hors de leur forme, une région ou un service vide. |
Exemples
Une requête signée vers CloudWatch, dans la région de la sonde.
need('protocol:http');
need('protocol:aws');
$region = variable('aws:region', 'text', array('label' => 'Région', 'help' => 'La région AWS, us-east-1 par exemple.'));
$url = 'https://monitoring.' . $region . '.amazonaws.com/?Action=ListMetrics&Version=2010-08-01';
$answer = http.get($url, headers=aws.sign('GET', $url, array('Accept' => 'application/json'), '', $region, 'monitoring')); Fautes signalées par le master
need_missing: Un appel sansneed('protocol:aws')dans l’en-tête.argument_count: Un nombre d’arguments autre que six.named_argument_unknown: Un argument nommé :aws.signn’en prend aucun, pas mêmeerrors=.
ovh.sign
ovh.sign signe une requête pour l’API d’OVHcloud, avec les clés de protocol:ovh. Elle n’envoie rien : elle rend les en-têtes X-Ovh-* à passer à headers=.
La signature est $1$ suivi de l’empreinte SHA-1 du secret d’application, de la clé consommateur, de la méthode, de l’adresse, du corps et de l’horodatage, joints par + : c’est celle qu’OVHcloud impose. X-Ovh-Consumer et X-Ovh-Signature sont secrets.
L’adresse de l’API, protocol:ovh:endpoint, se lit par son propre need : les clés d’une application ne valent que sur l’API où elles ont été créées.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$method | GET, POST, PUT ou DELETE, en majuscules | oui | La méthode de la requête. |
$url | une adresse https:// ou http:// entière | oui | L’adresse de la requête, telle que l’appel http.* l’écrira, sa requête comprise. |
$body | un texte | oui | Le corps de la requête, '' sans corps. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Les en-têtes de la signature | array('X-Ovh-Application' => …, 'X-Ovh-Consumer' => …, 'X-Ovh-Timestamp' => …, 'X-Ovh-Signature' => …) | Toujours. |
| Un arrêt, état MISCONFIGURED | — | Une méthode hors des quatre, ou une adresse qui n’en est pas une. |
Exemples
Les factures du compte.
need('protocol:http');
need('protocol:ovh');
$api = need('protocol:ovh:endpoint');
$url = $api . '/me/bill';
$answer = http.get($url, headers=ovh.sign('GET', $url, '')); Fautes signalées par le master
need_missing: Un appel sansneed('protocol:ovh')dans l’en-tête.argument_count: Un nombre d’arguments autre que trois.named_argument_unknown: Un argument nommé :ovh.signn’en prend aucun.
google.token
google.token demande un jeton d’accès au serveur de jetons de Google, pour le compte de service dont protocol:google:service-account-key porte la clé : une assertion signée de la clé privée, échangée contre un jeton. C’est la seule requête qu’elle envoie, et toujours vers ce serveur, dont le certificat est jugé par le profil « Standard » : le profil TLS de la sonde vaut pour sa cible, pas pour Google.
Le jeton vaut une heure. Gardez-le dans le cache pour moins, et relisez-le de là. Il est secret.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$scope | un texte non vide | oui | Une ou plusieurs portées, séparées par une espace. |
errors= | une variable seule | non (l’échec arrête le collecteur) | Rattrape l’échec de l’appel : voir errors=. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le jeton d’accès | texte, secret | Google a accepté la clé et la portée. |
| Un arrêt, état MISCONFIGURED | — | Google refuse la clé ou la portée (access_denied) ; une clé illisible ou une portée vide, que errors= ne rattrape pas. |
| Un arrêt, état UNREACHABLE | — | Le serveur ne répond pas dans les 10 secondes (timeout), ou répond autre chose qu’un jeton (network_error). |
'' | texte vide | L’appel a échoué et errors= a rattrapé l’échec. |
Exemples
Un jeton gardé dans le cache, puis une requête vers une API de Google.
need('protocol:http');
need('protocol:google');
if (cache.has('token')) {
$token = cache.get('token');
} else {
$token = google.token('https://www.googleapis.com/auth/monitoring.read');
cache.set('token', $token, 3000);
}
$answer = http.get($url, headers=array('Authorization' => 'Bearer ' . $token)); Fautes signalées par le master
need_missing: Un appel sansneed('protocol:google')dans l’en-tête.argument_count:google.token(), sans portée.named_argument_unknown: Un argument nommé autre queerrors=.
Les outils
Des fonctions de traitement, sans aucune sortie vers l’extérieur : elles travaillent sur des valeurs, du temps ou le cache de la sonde. Dans l’ordre : json, xml, x509, text, number, list, counter, time, cache, secret, puis les encodages url, base64, hex et hash.
json.read
json.read transforme un texte JSON en valeur. Les objets et les listes deviennent des tableaux.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte JSON à lire. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La valeur écrite par le texte | tableau, texte, nombre ou booléen | Le texte est du JSON. |
| Un arrêt, état UNREACHABLE | — | Le texte n’est pas du JSON. |
Exemples
Lire l’état déclaré dans le corps d’une réponse.
$health = list.get(json.read($answer['body']), 'status', 'absent'); Lire une liste de tâches.
$list = json.read($answer['body']);
foreach ($list['jobs'] as $job) {
value('result', $job['last_result'], $job['name']);
} json.write
json.write transforme une valeur en texte JSON, par exemple pour le corps d’une requête.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$value | texte, nombre, booléen ou tableau | oui | La valeur à écrire. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte JSON de la valeur | texte | Toujours. |
Exemples
Écrire le corps d’une demande de connexion.
$body = json.write(array('username' => $user, 'password' => $password)); xml.read
xml.read transforme un texte XML en valeur. Chaque élément est rangé dans une liste sous son nom, même seul, la racine comprise : xml.read('<status code="200">ok</status>') vaut array('status' => array(array('@code' => '200', '#text' => 'ok'))), et se lit $r['status'][0]['@code']. Un foreach sur des éléments compte donc juste, qu’il y en ait un ou plusieurs.
Un élément sans attribut ni enfant vaut son texte : <name>web1</name> vaut 'web1', <name/> vaut '', que list.is distingue d’un tableau. Les autres sont des tableaux : chaque attribut sous @ suivi de son nom, le texte sous #text quand il n’est pas vide, et sous le nom de chaque enfant la liste des enfants de ce nom. Le texte perd ses blancs de tête et de fin, et chaque valeur lue est un texte.
Un nom s’écrit tel que le document l’écrit, préfixe compris (atom:entry) : aucun espace de noms n’est résolu, et xmlns est un attribut comme un autre. La déclaration <?xml …?>, les commentaires et la DTD ne comptent pas. C’est une lecture, sans fichier ni réseau : aucune entité n’est chargée, et seules les cinq entités de XML (<, >, &, ', ") et les références de caractère se lisent.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte XML à lire. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La racine, dans une liste sous son nom | tableau | Le texte est du XML bien formé. |
| Un arrêt, état UNREACHABLE | — | Le texte n’est pas du XML bien formé, ou il porte une autre entité que les cinq de XML. |
Exemples
Lire le jeton d’une session.
$logon = xml.read($answer['body']);
$session = $logon['LogonResponse'][0]['X-API-Session'][0]; Lire les entrées d’un flux, une ou plusieurs, ou aucune.
$feed = xml.read($answer['body']);
foreach (list.get($feed['feed'][0], 'entry', array()) as $entry) {
value('state', $entry['content'][0]['State'][0], $entry['id'][0]);
} xml.escape
xml.escape écrit un texte pour qu’il tienne dans un corps XML : &, <, >, " et ' deviennent &, <, >, " et ', et la tabulation et les sauts de ligne des références de caractère. Le texte tient alors tel quel dans le texte d’un élément comme dans la valeur d’un attribut.
Passez par lui chaque texte que vous placez dans un corps XML : collé par la seule concaténation, un & ou un < dans un mot de passe casserait le corps, sans faute. xml.escape d’un secret reste un secret.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte à écrire. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte écrit pour XML | texte | Le texte ne porte que des caractères que XML admet. |
| Un arrêt, état MISCONFIGURED | — | Le texte porte un caractère de contrôle autre que la tabulation et les sauts de ligne, que XML n’admet pas. |
Exemples
Écrire le corps d’une ouverture de session.
$body = '<LogonRequest><UserID>' . xml.escape($user) . '</UserID><Password>' . xml.escape($password) . '</Password></LogonRequest>';
$answer = http.put($base . '/rest/api/web/Logon', $body, headers=array('Content-Type' => 'application/xml')); Fautes signalées par le master
secret_written: Un secret visible à la lecture passé àvalueà traversxml.escape.
x509.crl
x509.crl lit une liste de révocation X.509, d’ordinaire récupérée par http.get à son point de distribution, et rend ce qu’elle dit d’elle-même : sa date de publication, la date où la suivante est promise, son émetteur et le nombre de certificats qu’elle révoque. Une liste dont la date suivante est passée fait refuser par les clients chaque certificat de l’autorité : c’est ce qu’on surveille.
Le texte est la liste en PEM (-----BEGIN X509 CRL-----) ou en DER. La signature de la liste n’est pas vérifiée. C’est une lecture, sans fichier ni réseau.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$der_or_pem | un texte | oui | La liste, en PEM ou en DER. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Ce que dit la liste | array('this_update' => nombre, 'next_update' => nombre, 'issuer' => texte, 'entries' => nombre) | Le texte est une liste de révocation. Les dates en secondes depuis le 1er janvier 1970 UTC ; next_update vaut '' quand la liste ne le dit pas. |
| Un arrêt, état UNREACHABLE | — | Le texte n’est pas une liste de révocation : un certificat, une page d’erreur, une liste tronquée. |
Exemples
Le nombre de jours avant que la liste d’une autorité n’expire.
need('protocol:http');
$answer = http.get('http://pki.example/CertEnroll/root.crl');
$crl = x509.crl($answer['body']);
value('days-left', number.round(($crl['next_update'] - time.now()) / 86400, 1)); Fautes signalées par le master
argument_count:x509.crl(), sans liste.
text.trim
text.trim retire les blancs au début et à la fin d’un texte.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte à nettoyer. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte sans ses blancs de tête et de fin | texte | Toujours. |
Exemples
Nettoyer la sortie d’une commande.
$name = text.trim($host['output']); text.lower
text.lower met un texte en minuscules, pour comparer sans se soucier de la casse.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte à convertir. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte en minuscules | texte | Toujours. |
Exemples
Comparer un état sans tenir compte de la casse.
if (text.lower($state) == 'up') {
$up = $up + 1;
} text.length
text.length compte les caractères d’un texte, et non ses octets : text.length('é') vaut 1.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte à mesurer. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le nombre de caractères | nombre | Toujours. |
Exemples
Compter les caractères d’un nom.
$size = text.length($name); text.contains
text.contains dit si un texte contient un morceau donné.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte dans lequel chercher. |
$part | un texte | oui | Le morceau cherché. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
true ou false | booléen | true si le morceau est dans le texte. |
Exemples
Chercher un mot dans une page.
if ($word != '' && !text.contains($answer['body'], $word)) {
fail('critical', 'Mot absent', 'La page ne contient pas le mot ' . $word . '.');
} text.split
text.split coupe un texte à chaque séparateur et rend la liste des morceaux.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte à couper. |
$separator | un texte | oui | Ce qui sépare deux morceaux. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La liste des morceaux | tableau | Toujours. |
Exemples
Séparer les valeurs d’une liste écrite avec des virgules.
$parts = text.split('a,b,c', ','); text.join
text.join assemble les éléments d’un tableau en un texte, avec un séparateur.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$array | un tableau | oui | Les éléments à joindre. |
$separator | un texte | oui | Ce qui se place entre deux éléments. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Les éléments joints par le séparateur | texte | Toujours. |
Exemples
Assembler une liste de fichiers dans une commande.
$sys = ssh.run('cd /sys/class/net && grep -s -H . */' . text.join($files, ' */')); text.words
text.words découpe un texte en mots, séparés par des blancs.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte à découper. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La liste des mots | tableau | Toujours. |
Exemples
Découper une ligne de /proc/stat en colonnes.
$f = text.words($line);
$idle = $f[4] + $f[5]; text.lines
text.lines découpe un texte en lignes, sans les lignes vides.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte à découper. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La liste des lignes non vides | tableau | Toujours. Chaque ligne est rendue sans ses blancs de tête et de fin. |
Exemples
Parcourir la sortie d’une commande ligne par ligne.
foreach (text.lines($units['output']) as $line) {
$m = text.match($line, '([^ ]+)\.service +[^ ]+ +([^ ]+)');
} text.match
text.match cherche un motif dans un texte et rend les parties qui correspondent. Le motif est une expression régulière, dans la syntaxe de Go (RE2), qui s’exécute en temps linéaire : elle ne peut pas s’emballer.
Les parties sont numérotées : 0 pour tout ce qui correspond, puis 1, 2… pour chaque groupe entre parenthèses. Écrit en clair, le motif est jugé dès l’enregistrement.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte dans lequel chercher. |
$pattern | un texte | oui | Le motif, une expression régulière de Go. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Les groupes de la première correspondance | tableau | Le motif correspond. L’élément 0 est tout ce qui correspond, 1, 2… sont les groupes. |
array() | tableau vide | Rien ne correspond. |
Exemples
Séparer le nom d’une interface, un fichier et sa valeur dans une ligne eth0/mtu:1500.
$m = text.match($line, '^([^/]+)/([^:]+):(.*)$');
$read[$m[1]][$m[2]] = $m[3]; Fautes signalées par le master
pattern_invalid: Un motif écrit en clair qui n’est pas une expression régulière de Go.
text.is_number
text.is_number dit si un texte est l’écriture d’un nombre : un - facultatif, des chiffres, et facultativement un point suivi de chiffres.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte à examiner. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
true ou false | booléen | true si le texte est l’écriture d’un nombre (200, -3, 0.52). |
Exemples
Ne calculer que sur ce qui est un nombre.
if (text.is_number($f[2])) {
$used = $f[2] * 1024;
} text.like
text.like compare un texte entier à un motif simple, celui qu’un administrateur tape sans expression régulière. C’est aussi le motif d’une sélection (per).
Dans le motif, * vaut une suite de caractères, vide comprise, et ? un caractère. Tout autre caractère vaut lui-même, majuscules et minuscules distinctes.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | Le texte à comparer. |
$pattern | un texte | oui | Le motif, avec * et ?. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
true ou false | booléen | true si le texte entier suit le motif. |
Exemples
text.like('docker0', 'docker*') est vrai.
if (text.like($name, 'docker*')) {
continue;
} number.round
number.round arrondit un nombre à l’entier, ou à un nombre de décimales donné.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$n | un nombre | oui | Le nombre à arrondir. |
$decimals | un entier | non (arrondi à l’entier) | Le nombre de décimales à garder. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le nombre arrondi | nombre | Toujours. |
Exemples
Arrondir un débit à l’entier.
value('traffic-in', number.round($in), $name); Garder deux décimales.
value('packets', number.round($packets, 2), $name); list.count
list.count compte les éléments d’un tableau.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$array | un tableau | oui | Le tableau à compter. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le nombre d’éléments | nombre | Toujours. |
Exemples
Compter les membres d’un agrégat.
value('bond-members', list.count($members), $name); list.has
list.has dit si une clé existe dans un tableau.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$array | un tableau | oui | Le tableau à examiner. |
$key | un texte ou un entier | oui | La clé cherchée. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
true ou false | booléen | true si la clé existe. |
Exemples
Tester une clé avant de s’en servir.
if (list.has($f, 'duplex')) {
value('duplex', $f['duplex'], $name);
} list.get
list.get lit une case d’un tableau quand la clé peut manquer, et rend une valeur de remplacement si elle manque. Lire directement une clé absente arrête le collecteur ; list.get l’évite.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$array | un tableau | oui | Le tableau à lire. |
$key | un texte ou un entier | oui | La clé cherchée. |
$default | une valeur | oui | Ce que l’appel rend quand la clé n’existe pas. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| L’élément sous la clé | la valeur de la case | La clé existe. |
$default | la valeur donnée | La clé n’existe pas. |
Exemples
Lire une case qui manque pour une interface tombée.
$speed = list.get($f, 'speed', 0); Compter avec une valeur de départ.
$address_count[$words[1]] = list.get($address_count, $words[1], 0) + 1; list.add
list.add rend le tableau augmenté d’une valeur. La valeur est rangée sous la clé qui suit la plus grande clé entière du tableau (0 s’il n’en a pas), comme le faisait $a[] = $x en PHP.
Un tableau est une valeur : list.add ne change pas le tableau reçu, elle en rend un nouveau. Rangez le résultat.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$array | un tableau | oui | Le tableau à compléter. |
$value | une valeur | oui | Ce qu’il faut ajouter. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le tableau augmenté | tableau | Toujours. |
Exemples
Ajouter un élément à une liste.
$names = array();
$names = list.add($names, 'eth0');
$names = list.add($names, 'eth1'); list.is
list.is dit si une valeur est un tableau. Elle distingue un élément XML vide, <name/>, lu comme le texte '', d’un élément qui a des enfants, lu comme un tableau ; ou un null JSON, lu '', d’un objet.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$value | une valeur | oui | La valeur à examiner. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
true ou false | booléen | true si la valeur est un tableau ; false pour un texte, un nombre ou un booléen. |
Exemples
Compter les éléments d’un ensemble qui peut revenir vide, <itemSet/>.
$answer = xml.read($r['body']);
$set = $answer['DescribeResponse'][0]['itemSet'][0];
$count = 0;
if (list.is($set)) {
$count = list.count(list.get($set, 'item', array()));
}
value('items', $count); counter.rate
counter.rate calcule le débit par seconde d’un compteur : la différence avec le relevé du passage précédent, divisée par le temps écoulé entre les deux. C’est le cas courant d’une interface, d’un disque ou d’un processeur, dont le compteur ne fait que croître.
La fonction garde le relevé de ce passage (la valeur et l’heure) pour le suivant. Ses relevés sont gardés par le poller avec le cache de la sonde, à part de ses 32 clés, un par nom et par instance.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$name | un texte écrit en clair, de la forme d’une clé du cache | oui | Le nom du compteur. |
$counter | un nombre, ou l’écriture d’un nombre | oui | La valeur du compteur à ce passage. |
$instance | un texte | non (aucune) | L’instance que le relevé concerne, pour garder un relevé par instance. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le débit par seconde | nombre | Il y a un relevé précédent, pas plus vieux que trois fois l’intervalle de la sonde, et le compteur n’est pas revenu en arrière. |
'' | texte vide | Au premier relevé ; quand le relevé précédent est trop vieux ; quand le compteur est revenu en arrière (équipement redémarré, compteur qui déborde). Le relevé neuf sert au passage suivant. |
| Un arrêt, état MISCONFIGURED | — | La fonction est appelée deux fois pour le même nom et la même instance dans un passage ; ou un secret lui est passé. |
| Un arrêt, état UNREACHABLE | — | $counter est un texte qui n’est pas l’écriture d’un nombre. |
Exemples
Le débit entrant d’une interface en bits par seconde, rien au premier passage.
$in = counter.rate('in', $f['statistics/rx_bytes'] * 8, $name); Sans instance, pour un seul compteur.
$in = counter.rate('in', $current['in'] * 8);
if ($in == '') {
skip('Premier relevé : le débit viendra au prochain passage');
} Fautes signalées par le master
counter_name_invalid: Un nom de compteur hors de la forme d’une clé du cache.argument_not_literal: Un nom qui n’est pas écrit en clair.secret_written: Un secret visible à la lecture passé àcounter.rate.
time.now
time.now rend l’heure, en secondes, au millième.
Paramètres
time.now ne prend aucun paramètre.
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| L’heure | nombre, en secondes, au millième | Toujours. |
Exemples
Garder l’heure d’un relevé dans le cache.
cache.set('last-run', time.now(), 3600); time.parse
time.parse lit une date écrite en texte, et rend l’instant qu’elle dit, en secondes depuis le 1er janvier 1970 UTC, au millième : la forme de time.now, pour que les deux se soustraient.
Trois formats existent, nommés en minuscules : rfc3339 (2026-10-27T13:30:15Z, 2026-10-27T15:30:15.25+02:00), la forme des API ; iso8601, la même, qui accepte aussi le décalage +0200 ou +02 et la fraction après une virgule ; rfc1123 (Tue, 27 Oct 2026 13:30:15 GMT), la date d’HTTP et du courrier, que portent les en-têtes date et last-modified.
Le décalage à UTC est toujours exigé : sans lui, l’instant dépend d’un fuseau que le texte ne dit pas, et le deviner le rendrait faux de tout le fuseau. Pour l’heure locale d’un serveur, ajoutez-lui le décalage que vous connaissez, par exemple celui de date +%z. Une date d’une autre forme se découpe par text.match et se réécrit dans l’un des trois formats.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte | oui | La date à lire, entière, sans blanc de tête ni de fin. |
$format | rfc3339, iso8601 ou rfc1123 | oui | Le format dans lequel la date est écrite. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| L’instant | nombre, en secondes depuis le 1er janvier 1970 UTC, au millième | Le texte suit son format, chaque champ dans les bornes du calendrier. |
| Un arrêt, état UNREACHABLE | — | Le texte ne suit pas son format, n’a pas de décalage, ou porte une date qui n’existe pas (un 30 février). |
| Un arrêt, état MISCONFIGURED | — | Un format calculé hors des trois. |
Exemples
L’âge, en heures, d’une sauvegarde datée par une API.
$age = (time.now() - time.parse($job['lastRun'], 'rfc3339')) / 3600; Une heure locale, à laquelle on ajoute le décalage du serveur.
$zone = ssh.run('date +%z');
$when = time.parse($archive['time'] . text.trim($zone['output']), 'iso8601'); Fautes signalées par le master
time_format_invalid: Un format écrit en clair hors des trois, ou en majuscules :time.parse($t, 'RFC3339'),time.parse($t, 'yyyy-mm-dd').argument_count:time.parse($t), sans format.
time.format
time.format écrit un instant, en secondes depuis le 1er janvier 1970 UTC (la forme de time.now), dans l’un des trois formats de time.parse, toujours en UTC : le contraire de time.parse, pour écrire une date dans l’adresse ou le corps d’une requête.
rfc3339 et iso8601 écrivent 2026-10-27T13:30:15Z, avec la fraction au millième quand l’instant n’est pas une seconde ronde (2026-10-27T13:30:15.25Z) ; rfc1123 écrit la date d’HTTP, Tue, 27 Oct 2026 13:30:15 GMT, sans fraction. Pour une seconde ronde, passez number.round($seconds). Une autre forme se tire de celle-ci par text.split.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$seconds | un nombre | oui | L’instant, en secondes depuis le 1er janvier 1970 UTC. |
$format | rfc3339, iso8601 ou rfc1123 | oui | Le format dans lequel l’écrire. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La date | texte, en UTC | L’instant est un nombre, entre les années 0000 et 9999. |
| Un arrêt, état UNREACHABLE | — | L’instant n’est pas un nombre, ou tombe hors des années 0000 à 9999. |
| Un arrêt, état MISCONFIGURED | — | Un format calculé hors des trois. |
Exemples
Le début d’une fenêtre de trente minutes, pour une API qui la demande en UTC.
$start = time.format(number.round(time.now() - 1800), 'rfc3339');
$query = url.query(array('timespan' => $start . '/PT30M')); La date du jour, sans l’heure.
$parts = text.split(time.format(time.now(), 'rfc3339'), 'T');
$day = $parts[0]; Fautes signalées par le master
time_format_invalid: Un format écrit en clair hors des trois, ou en majuscules :time.format($t, 'RFC1123').argument_count:time.format($t), sans format.
time.wait
time.wait attend un nombre de secondes avant de continuer, dans la durée permise au collecteur. Au-delà de cette durée, le collecteur s’arrête.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$seconds | un nombre | oui | Le temps à attendre, en secondes. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | time.wait ne rend pas de valeur. |
| Un arrêt, état UNREACHABLE | — | La durée permise au passage est dépassée. |
Exemples
Attendre deux secondes.
time.wait(2); cache.set
Le cache est une petite mémoire que le poller garde pour chaque sonde, d’un passage à l’autre. Il sert à garder un jeton ou tout relevé que le collecteur veut retrouver. Chaque clé a une durée de vie : une valeur qui n’est pas reposée avant sa fin disparaît.
cache.set pose une clé pour une durée, en remplaçant sa valeur et sa durée d’avant. L’écriture vaut dès l’appel, quelle que soit la fin du passage. Le cache traverse un redémarrage du poller et s’efface quand la sonde est supprimée ou change de collecteur ou de version. Le master ne le lit jamais.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$key | un texte : 1 à 64 caractères parmi a-z, 0-9, ., _, - | oui | La clé. 32 clés au plus par sonde. |
$value | texte, nombre ou tableau, 16 384 caractères au plus écrit comme json.write l’écrirait | oui | La valeur à garder. Un secret posé dans le cache y est chiffré et revient secret. |
$seconds | un entier de 1 à 604 800 (sept jours) | oui | La durée de vie. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | cache.set ne rend pas de valeur. |
| Un arrêt, état MISCONFIGURED | — | Une borne du cache est dépassée. |
Exemples
Garder un jeton cinquante minutes.
cache.set('token', $session['access_token'], 3000); Fautes signalées par le master
cache_key_invalid: Une clé écrite en clair hors de sa forme.cache_lifetime_invalid: Une durée de vie écrite en clair hors de ses bornes.
cache.get
cache.get rend la valeur gardée sous une clé. Une clé absente ou expirée arrête le collecteur : testez-la d’abord avec cache.has.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$key | un texte | oui | La clé à lire. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La valeur gardée | texte, nombre ou tableau | La clé existe et n’a pas expiré. |
| Un arrêt du collecteur | — | La clé est absente ou expirée. |
Exemples
Relire un jeton gardé, après avoir vérifié qu’il existe.
if (cache.has('token')) {
$token = cache.get('token');
} Fautes signalées par le master
cache_key_invalid: Une clé écrite en clair hors de sa forme.
cache.has
cache.has dit si une clé est dans le cache. Une clé expirée n’y est plus.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$key | un texte | oui | La clé à chercher. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
true ou false | booléen | true si la clé est là. |
Exemples
Se connecter seulement quand aucun jeton n’est gardé.
if (cache.has('token')) {
$token = cache.get('token');
} else {
$token = login($base, $user, $password);
} Fautes signalées par le master
cache_key_invalid: Une clé écrite en clair hors de sa forme.
cache.delete
cache.delete retire une clé du cache. Retirer une clé qui n’y est pas n’est pas une faute.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$key | un texte | oui | La clé à retirer. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Rien | — | cache.delete ne rend pas de valeur. |
Exemples
Oublier un jeton refusé.
if ($answer['status'] == 401) {
cache.delete('token');
} Fautes signalées par le master
cache_key_invalid: Une clé écrite en clair hors de sa forme.
secret.mark
secret.mark marque une valeur comme secrète. Sont secrets : la valeur d’une variable secrète, une valeur passée par secret.mark, une valeur secrète relue du cache, tout ce qui est calculé à partir d’un secret ('Bearer ' . $token l’est, comme un encodage, une empreinte ou une signature d’un secret), et la réponse d’une requête dont le corps portait un secret, sauf son code et son temps, à moins que l’appel la déclare sans jeton (public=true, voir http.post). Le résultat d’une comparaison ne l’est pas.
Toute partie d’une réponse qui contient un secret de la sonde est secrète aussi, quel que soit l’appel et quoi que la requête ait porté, public=true compris : un jeton qu’une cible recopie dans sa réponse ne passe jamais dans une valeur. Les secrets de la sonde sont les valeurs secrètes non vides que le collecteur tient au moment de l’appel : ses variables secrètes, et tout ce qu’il a marqué, relu du cache ou tiré d’un secret, comme le jeton d’un login. La communauté SNMP v2c n’est pas cherchée : elle circule en clair par nature, et public rendrait secret l’alias d’interface public-lan. Chacun est cherché tel quel, en base64, en base64 d’adresse et passé par url.encode, et le compte d’un user= en base64 sous la forme user:password. Devient secret l’élément de la réponse qui le contient : le corps ou les en-têtes d’une réponse HTTP, la sortie d’une commande, une valeur d’un snmp.walk. Un secret repris autrement, en hexadécimal ou en partie, n’est pas vu.
Un secret ne va que dans une fonction de protocole (un en-tête, un corps, un argument SSH) ou dans le cache. Passé à value, fail, skip, watch.raise ou counter.rate, il arrête le collecteur. Aucun secret ne part vers une cible dont l’identité n’est pas jugée : une requête http:// qui en porte un arrête le collecteur.
C’est une garde contre l’accident, pas contre un auteur décidé à tricher : contre lui, la barrière reste la relecture du diff sur le poller.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$value | une valeur | oui | La valeur à marquer. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La même valeur, marquée secrète | celle de $value | Toujours. |
| Un arrêt, état MISCONFIGURED | — | Un secret est écrit dans une valeur, un message ou un compteur, ou envoyé par http://. |
Exemples
Marquer un jeton lu ailleurs avant de le placer dans un en-tête.
$token = secret.mark($raw_token);
$answer = http.get($url, headers=array('Authorization' => 'Bearer ' . $token)); Fautes signalées par le master
secret_written: Un secret visible à la lecture passé àvalue,fail,skip,watch.raiseoucounter.rate.
url.encode
url.encode écrit un texte pour qu’il tienne dans une adresse ou dans un corps de formulaire (RFC 3986). Les lettres ASCII, les chiffres et -, ., _, ~ restent tels quels ; chaque autre octet s’écrit % et deux chiffres hexadécimaux majuscules, l’espace compris (%20).
Un paramètre d’adresse s’écrit par url.encode ou url.query, jamais par la seule concaténation : un texte qui porte &, =, + ou une espace casserait l’adresse sans faute. L’encodage d’un secret reste un secret.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte, ou un nombre, qui vaut son écriture | oui | Le texte à écrire. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte encodé | texte | Toujours. url.encode('a b&c=d') vaut a%20b%26c%3Dd. |
Exemples
Passer une requête PromQL dans l’adresse.
need('protocol:http');
$answer = http.get('https://prometheus.example/api/v1/query?query=' . url.encode('up{job="node"}')); Fautes signalées par le master
argument_count:url.encode(), sans texte.
url.query
url.query écrit un tableau en paramètres : chaque élément devient clé=valeur, la clé et la valeur passées par url.encode, joints par &. C’est la forme d’un corps de formulaire et de la fin d’une adresse.
Les paramètres sont toujours rangés par clé encodée, octet par octet, sans option : une requête signée l’exige, et un serveur qui lit un formulaire les lit par leur nom. Deux paramètres du même nom (a=1&a=2) ne s’écrivent pas par url.query. Un tableau qui porte un secret donne un secret.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$array | array(clé => valeur), chaque valeur un texte ou un nombre | oui | Les paramètres à écrire. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Les paramètres joints | texte | Toujours ; '' pour un tableau vide. |
| Un arrêt, état MISCONFIGURED | — | L’argument n’est pas un tableau, ou une valeur n’est ni un texte ni un nombre. |
Exemples
Demander un jeton OAuth2 par le flux « client credentials », le corps écrit en formulaire.
need('protocol:http');
$id = variable('oauth:client-id', 'text', array('label' => 'Identifiant du client', 'help' => 'L’identifiant de l’application.'));
$secret = variable('oauth:client-secret', 'text', array('label' => 'Secret du client', 'help' => 'Le secret de l’application.', 'secret' => true));
$body = url.query(array('grant_type' => 'client_credentials', 'client_id' => $id, 'client_secret' => $secret, 'scope' => 'https://graph.example/.default'));
$answer = http.post('https://login.example/oauth2/token', $body, headers=array('Content-Type' => 'application/x-www-form-urlencoded')); Fautes signalées par le master
argument_count:url.query(array('a' => 1), '&'): un seul argument.secret_written: Un secret écrit dans le tableau passé àvalue:value('x', url.query(array('k' => $password))).
base64.encode
base64.encode écrit les octets UTF-8 d’un texte en base64, avec l’alphabet standard et son remplissage = (RFC 4648, section 4). L’encodage d’un secret reste un secret : il se lit en une ligne.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte, ou un nombre, qui vaut son écriture | oui | Le texte à encoder. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte en base64 | texte | Toujours. base64.encode('banshee') vaut YmFuc2hlZQ==. |
Exemples
Écrire soi-même l’en-tête Authorization: Basic, ici celui qu’un serveur OAuth2 demande au client (RFC 6749, section 2.3.1) : user= refuse un compte qui contient :.
need('protocol:http');
$id = variable('oauth:client-id', 'text', array('label' => 'Identifiant du client', 'help' => 'L’identifiant de l’application.'));
$secret = variable('oauth:client-secret', 'text', array('label' => 'Secret du client', 'help' => 'Le secret de l’application.', 'secret' => true));
$basic = base64.encode(url.encode($id) . ':' . url.encode($secret));
$answer = http.post('https://login.example/oauth2/token', url.query(array('grant_type' => 'client_credentials')), headers=array('Authorization' => 'Basic ' . $basic, 'Content-Type' => 'application/x-www-form-urlencoded')); Fautes signalées par le master
argument_count:base64.encode('a', 'b'): un seul argument.secret_written: L’encodage d’un secret passé àvalue:value('x', base64.encode($password)).
base64.decode
base64.decode rend le texte qu’un base64 standard écrit. Les sauts de ligne y sont ignorés. Le décodage d’un secret reste un secret.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte en base64 standard, remplissage compris | oui | Le texte à décoder. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte décodé | texte | Le texte est du base64. base64.decode('YmFuc2hlZQ==') vaut banshee. |
| Un arrêt, état UNREACHABLE | — | Le texte n’est pas du base64 : un caractère hors de l’alphabet, un remplissage absent ou faux. |
Exemples
Lire une valeur que Consul rend en base64.
need('protocol:http');
$answer = http.get('https://consul.example:8501/v1/kv/app/mode');
$entries = json.read($answer['body']);
$mode = base64.decode($entries[0]['Value']); Fautes signalées par le master
argument_count:base64.decode(), sans texte.
base64.url_encode
base64.url_encode écrit les octets UTF-8 d’un texte en base64 pour une adresse : - et _ remplacent + et /, sans remplissage (RFC 4648, section 5). C’est la forme des morceaux d’un jeton JWT. L’encodage d’un secret reste un secret.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte, ou un nombre, qui vaut son écriture | oui | Le texte à encoder. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte en base64 pour une adresse | texte | Toujours. base64.url_encode('???') vaut Pz8_, base64.url_encode('banshee') vaut YmFuc2hlZQ. |
Exemples
Encoder un texte pour un paramètre d’adresse.
$e = base64.url_encode('banshee'); Fautes signalées par le master
argument_count:base64.url_encode(), sans texte.secret_written: L’encodage d’un secret passé àvalue:value('x', 'h=' . base64.url_encode($password)).
base64.url_decode
base64.url_decode rend le texte qu’un base64 pour adresse écrit, avec ou sans son remplissage = ; un remplissage présent doit être complet. Les sauts de ligne y sont ignorés. Le décodage d’un secret reste un secret : la charge d’un jeton secret l’est aussi, et ne se compare qu’à une autre valeur.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte en base64 pour adresse | oui | Le texte à décoder. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte décodé | texte | Le texte est du base64 pour adresse. base64.url_decode('Pz8_') vaut ???. |
| Un arrêt, état UNREACHABLE | — | Le texte n’est pas de cette forme : un + ou un /, un remplissage incomplet. |
Exemples
Lire la charge d’un jeton JWT, son deuxième morceau, et le renouveler cinq minutes avant qu’il expire.
$parts = text.split($jwt, '.');
$claims = json.read(base64.url_decode($parts[1]));
if ($claims['exp'] < time.now() + 300) {
$renew = true;
} Fautes signalées par le master
argument_count:base64.url_decode('a', 'b'): un seul argument.
hex.encode
hex.encode écrit les octets UTF-8 d’un texte en hexadécimal minuscule, deux chiffres par octet. L’encodage d’un secret reste un secret.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte, ou un nombre, qui vaut son écriture | oui | Le texte à encoder. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte en hexadécimal | texte | Toujours. hex.encode('banshee') vaut 62616e73686565. |
Exemples
Encoder un texte, puis le relire.
$e = hex.encode('banshee');
$d = hex.decode($e); Fautes signalées par le master
argument_count:hex.encode(), sans texte.
hex.decode
hex.decode rend le texte qu’un hexadécimal écrit, ses chiffres en minuscules ou en majuscules. Le décodage d’un secret reste un secret.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un nombre pair de chiffres 0-9, a-f, A-F | oui | Le texte à décoder. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| Le texte décodé | texte | Le texte est de l’hexadécimal. hex.decode('62616E73686565') vaut banshee. |
| Un arrêt, état UNREACHABLE | — | Un nombre impair de chiffres, ou un caractère hors de 0-9, a-f, A-F. |
Exemples
Relire un texte écrit en hexadécimal.
$d = hex.decode('62616E73686565'); Fautes signalées par le master
argument_count:hex.decode('61', '62'): un seul argument.
hash.sha256
hash.sha256 rend l’empreinte SHA-256 des octets UTF-8 d’un texte. Seules des empreintes sûres existent : ni MD5, ni SHA-1.
L’empreinte d’un secret reste un secret : celle d’un secret court se retrouve par essais. Elle peut se comparer à une autre valeur.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte, ou un nombre, qui vaut son écriture | oui | Le texte à résumer. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| L’empreinte | texte, 64 chiffres hexadécimaux minuscules | Toujours. hash.sha256('') vaut e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855. |
Exemples
Savoir si une page a changé, en comparant son empreinte à celle attendue.
need('protocol:http');
$answer = http.get('https://www.example/');
if (hash.sha256($answer['body']) != $known) {
fail('warning', 'Page modifiée', 'Le contenu de la page a changé.');
} Fautes signalées par le master
function_unknown:hash.md5('a')ethash.sha1('a').argument_count:hash.sha256(), sans texte.secret_written: L’empreinte d’un secret passée àvalue:value('x', hash.sha256($password)).
hash.hmac_sha256
hash.hmac_sha256 rend la signature HMAC-SHA-256 (RFC 2104) d’un texte sous une clé : le texte d’abord, la clé ensuite.
La clé est d’ordinaire un secret, qui vient d’une variable secrète et ne s’écrit jamais en clair dans le code. La signature d’un texte secret, ou sous une clé secrète, reste un secret.
Paramètres
| Nom | Forme | Obligatoire (défaut) | Rôle |
|---|---|---|---|
$text | un texte, ou un nombre, qui vaut son écriture | oui | Le texte à signer. |
$key | un texte | oui | La clé de la signature. |
Retours
| Ce qui est rendu | Forme | Dans quel cas |
|---|---|---|
| La signature | texte, 64 chiffres hexadécimaux minuscules | Toujours. hash.hmac_sha256('what do ya want for nothing?', 'Jefe') vaut 5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843 (RFC 4231, cas 2). |
Exemples
Signer l’heure d’une requête sous une clé partagée, et passer l’heure et la signature en paramètres.
need('protocol:http');
$key = variable('api:signing-key', 'text', array('label' => 'Clé de signature', 'help' => 'La clé partagée avec l’API.', 'secret' => true));
$stamp = number.round(time.now());
$signature = hash.hmac_sha256($stamp, $key);
$answer = http.get('https://api.example/status?' . url.query(array('ts' => $stamp, 'signature' => $signature))); Fautes signalées par le master
argument_count:hash.hmac_sha256('a'), sans clé.secret_written: La signature sous une clé secrète passée àvalue:value('x', hash.hmac_sha256('t', $key)).