5 Prétraitement JavaScript

Vue d’ensemble

Cette section fournit des détails sur le prétraitement par JavaScript.

N’utilisez pas d’affectations non déclarées dans le JavaScript de prétraitement. Utilisez var pour déclarer les variables locales.

Prétraitement JavaScript

Le prétraitement JavaScript est effectué en appelant une fonction JavaScript avec un seul paramètre, « value », et un corps de fonction fourni par l'utilisateur. Le résultat de l'étape de prétraitement est la valeur renvoyée par cette fonction. Par exemple, pour effectuer une conversion de Fahrenheit en Celsius, saisissez :

return (value - 32)  * 5 / 9

dans les paramètres de prétraitement JavaScript ; le serveur l'encapsulera dans une fonction JavaScript :

function (value)
{
   return (value - 32) * 5 / 9
}

Le paramètre d'entrée « value » est toujours transmis sous forme de chaîne. La valeur de retour est automatiquement convertie en chaîne via la méthode toString() (si cela échoue, l'erreur est alors renvoyée sous forme de valeur de chaîne), avec quelques exceptions :

  • le renvoi de la valeur undefined entraînera une erreur ;
  • le renvoi de la valeur null entraînera l'abandon de la valeur d'entrée, de manière similaire au prétraitement « Discard value » dans l'action « Custom on fail ».

Les erreurs peuvent être renvoyées en lançant des valeurs/objets (généralement des chaînes ou des objets Error).

Par exemple :

if (value == 0)
    throw "Zero input value"
return 1/value

Chaque script dispose d'un délai maximal d'exécution de 10 secondes (selon le script, le déclenchement du délai peut prendre plus de temps) ; si ce délai est dépassé, une erreur sera renvoyée. Une limite de tas de 512 mégaoctets est appliquée.

Le bytecode de l'étape de prétraitement JavaScript est mis en cache et réutilisé lorsque l'étape est appliquée la fois suivante. Toute modification des étapes de prétraitement de l'élément entraînera la réinitialisation du script mis en cache et sa recompilation ultérieure.

Des échecs d'exécution consécutifs (3 d'affilée) entraîneront la réinitialisation du moteur afin de réduire le risque qu'un script perturbe l'environnement d'exécution des scripts suivants (cette action est journalisée avec DebugLevel 4 et supérieur).

Le prétraitement JavaScript est implémenté avec le moteur JavaScript Duktape.

Voir aussi : Objets JavaScript supplémentaires et fonctions globales

Utilisation des macros dans les scripts

Il est possible d'utiliser des macros utilisateur (ainsi que des macros LLD dans le contexte de la découverte de bas niveau) dans le code JavaScript. Si un script contient des macros utilisateur, ces macros sont résolues par le serveur/proxy avant l'exécution des étapes de prétraitement spécifiques. Notez que lors du test des étapes de prétraitement dans le frontend, les valeurs des macros ne seront pas récupérées et devront être saisies manuellement.

Le contexte est ignoré lorsqu'une macro est remplacée par sa valeur. La valeur de la macro est insérée telle quelle dans le code, il n'est pas possible d'ajouter un échappement supplémentaire avant de placer la valeur dans le code JavaScript. Veuillez noter que cela peut provoquer des erreurs JavaScript dans certains cas.

Dans l'exemple ci-dessous, si la valeur reçue dépasse la valeur de la macro {$THRESHOLD}, la valeur du seuil (si elle est présente) sera renvoyée à la place :

var threshold = '{$THRESHOLD}';
return (!isNaN(threshold) && value > threshold) ? threshold : value;

Exemples

Les exemples suivants illustrent comment vous pouvez utiliser le prétraitement JavaScript.

Chaque exemple contient une brève description, un corps de fonction pour les paramètres de prétraitement JavaScript, ainsi que le résultat de l’étape de prétraitement : la valeur renvoyée par la fonction.

Exemple 1 : Convertir un nombre (notation scientifique en entier)

Convertissez le nombre « 2.62128e+07 » de la notation scientifique en entier.

return (Number(value))

Valeur renvoyée par la fonction : 26212800.

Exemple 2 : Convertir un nombre (binaire en décimal)

Convertissez le nombre binaire « 11010010 » en nombre décimal.

return(parseInt(value,2))

Valeur renvoyée par la fonction : 210.

Exemple 3 : Arrondir un nombre

Arrondissez le nombre « 18.2345 » à 2 chiffres.

return(Math.round(value* 100) / 100)

Valeur renvoyée par la fonction : 18.23.

Exemple 4 : Compter les lettres dans une chaîne

Comptez le nombre de lettres dans la chaîne « Zabbix ».

return (value.length)

Valeur renvoyée par la fonction : 6.

Exemple 5 : Obtenir le temps restant

Obtenez le temps restant (en secondes) jusqu’à la date d’expiration d’un certificat (12 févr. 12:33:56 2022 GMT).

var split = value.split(' '),
    MONTHS_LIST = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
    month_index = ('0' + (MONTHS_LIST.indexOf(split[0]) + 1)).slice(-2),
    ISOdate = split[3] + '-' + month_index + '-' + split[1] + 'T' + split[2],
    now = Date.now();

return parseInt((Date.parse(ISOdate) - now) / 1000);

Valeur renvoyée par la fonction : 44380233.

Exemple 6 : Supprimer des propriétés JSON

Modifiez la structure des données JSON en supprimant toutes les propriétés dont la clé est "data_size" ou "index_size".

var obj=JSON.parse(value);

for (i = 0; i < Object.keys(obj).length; i++) {
    delete obj[i]["data_size"];
    delete obj[i]["index_size"];
}

return JSON.stringify(obj)

Valeur acceptée par la fonction :

[
    {
        "table_name":"history",
        "data_size":"326.05",
        "index_size":"174.34"
    },
    {
        "table_name":"history_log",
        "data_size":"6.02",
        "index_size":"3.45"
    }
]

Valeur renvoyée par la fonction :

[
    {
        "table_name":"history"
    },
    {
        "table_name":"history_log"
    }
]
Exemple 7 : Convertir le statut Apache en JSON

Convertissez la valeur reçue d’un élément d’agent Zabbix web.page.get (par exemple, web.page.get[http://127.0.0.1:80/server-status?auto]) en objet JSON.

// Convertir le statut Apache en JSON

// Diviser la valeur en sous-chaînes et placer ces sous-chaînes dans un tableau
var lines = value.split('\n');

// Créer un objet vide "output"
var output = {};

// Créer un objet "workers" avec des propriétés prédéfinies
var workers = {
    '_': 0, 'S': 0, 'R': 0, 'W': 0,
    'K': 0, 'D': 0, 'C': 0, 'L': 0,
    'G': 0, 'I': 0, '.': 0
};

// Ajouter les sous-chaînes du tableau "lines" à l'objet "output" en tant que propriétés (paires clé-valeur)
for (var i = 0; i < lines.length; i++) {
    var line = lines[i].match(/([A-z0-9 ]+): (.*)/);

    if (line !== null) {
        output[line[1]] = isNaN(line[2]) ? line[2] : Number(line[2]);
    }
}

// Métriques multiversion
output.ServerUptimeSeconds = output.ServerUptimeSeconds || output.Uptime;
output.ServerVersion = output.ServerVersion || output.Server;

// Analyser la propriété "Scoreboard" pour obtenir le nombre de workers
if (typeof output.Scoreboard === 'string') {
    for (var i = 0; i < output.Scoreboard.length; i++) {
        var char = output.Scoreboard[i];

        workers[char]++;
    }
}

// Ajouter les données des workers à l'objet "output"
output.Workers = {
    waiting: workers['_'], starting: workers['S'], reading: workers['R'],
    sending: workers['W'], keepalive: workers['K'], dnslookup: workers['D'],
    closing: workers['C'], logging: workers['L'], finishing: workers['G'],
    cleanup: workers['I'], slot: workers['.']
};

// Renvoyer la chaîne JSON
return JSON.stringify(output);

Valeur acceptée par la fonction :

HTTP/1.1 200 OK
Date: Mon, 27 Mar 2023 11:08:39 GMT
Server: Apache/2.4.52 (Ubuntu)
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 405
Content-Type: text/plain; charset=ISO-8859-1

127.0.0.1
ServerVersion: Apache/2.4.52 (Ubuntu)
ServerMPM: prefork
Server Built: 2023-03-08T17:32:01
CurrentTime: Monday, 27-Mar-2023 14:08:39 EEST
RestartTime: Monday, 27-Mar-2023 12:19:59 EEST
ParentServerConfigGeneration: 1
ParentServerMPMGeneration: 0
ServerUptimeSeconds: 6520
ServerUptime: 1 hour 48 minutes 40 seconds
Load1: 0.56
Load5: 0.33
Load15: 0.28
Total Accesses: 2476
Total kBytes: 8370
Total Duration: 52718
CPUUser: 8.16
CPUSystem: 3.44
CPUChildrenUser: 0
CPUChildrenSystem: 0
CPULoad: .177914
Uptime: 6520
ReqPerSec: .379755
BytesPerSec: 3461.58
BytesPerReq: 3461.58
DurationPerReq: 21.2916
BusyWorkers: 2
IdleWorkers: 6
Scoreboard: ____KW__..............................................................................................................................................

Valeur renvoyée par la fonction :

{
    "Date": "Mon, 27 Mar 2023 11:08:39 GMT",
    "Server": "Apache/2.4.52 (Ubuntu)",
    "Vary": "Accept-Encoding",
    "Encoding": "gzip",
    "Length": 405,
    "Type": "text/plain; charset=ISO-8859-1",
    "ServerVersion": "Apache/2.4.52 (Ubuntu)",
    "ServerMPM": "prefork",
    "Server Built": "2023-03-08T17:32:01",
    "CurrentTime": "Monday, 27-Mar-2023 14:08:39 EEST",
    "RestartTime": "Monday, 27-Mar-2023 12:19:59 EEST",
    "ParentServerConfigGeneration": 1,
    "ParentServerMPMGeneration": 0,
    "ServerUptimeSeconds": 6520,
    "ServerUptime": "1 hour 48 minutes 40 seconds",
    "Load1": 0.56,
    "Load5": 0.33,
    "Load15": 0.28,
    "Total Accesses": 2476,
    "Total kBytes": 8370,
    "Total Duration": 52718,
    "CPUUser": 8.16,
    "CPUSystem": 3.44,
    "CPUChildrenUser": 0,
    "CPUChildrenSystem": 0,
    "CPULoad": 0.177914,
    "Uptime": 6520,
    "ReqPerSec": 0.379755,
    "BytesPerSec": 1314.55,
    "BytesPerReq": 3461.58,
    "DurationPerReq": 21.2916,
    "BusyWorkers": 2,
    "IdleWorkers": 6,
    "Scoreboard": "____KW__..............................................................................................................................................",
    "Workers": {
        "waiting": 6,
        "starting": 0,
        "reading": 0,
        "sending": 1,
        "keepalive": 1,
        "dnslookup": 0,
        "closing": 0,
        "logging": 0,
        "finishing": 0,
        "cleanup": 0,
        "slot": 142
    }
}