This is a translation of the original English documentation page. Help us make it better.

4 Prétraitement JavaScript

Aperçu

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

Prétraitement JavaScript

Le prétraitement JavaScript est effectué en invoquant la fonction JavaScript avec un paramètre unique '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 Fahrenheit en Celsius, l'utilisateur doit saisir :

return (value - 32) * 5 / 9

dans les paramètres de prétraitement JavaScript, qui seront enveloppés dans une fonction JavaScript par serveur :

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

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

  • renvoyer une valeur indéfinie entraînera une erreur
  • renvoyer une valeur nulle entraînera la suppression de la valeur d'entrée, un peu comme le prétraitement 'Supprimer la valeur' sur l'action 'Personnalisé en cas d'échec'.

Les erreurs peuvent être renvoyées en initiant des valeurs/objets (normalement soit des chaînes ou soit des objets Error).

Par exemple:

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

Chaque script a un délai d'exécution de 10 secondes (selon le script le délai d'attente peut prendre plus de temps à se déclencher ); le dépasser va retourner une erreur. Une limite de tas de 64 Mo 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 une prochaine fois. Toute modification des étapes de prétraitement de l'élément entraînera la réinitialisation et la recompilation ultérieure du script mis en cache.

Des échecs d'exécution consécutifs (3 d'affilée) entraîneront que le moteur sera réinitialisé pour atténuer la possibilité qu'un script casse l'environnement d'exécution pour les prochains scripts (cette action est enregistrée avec DebugLevel à 4 et supérieur).

Le prétraitement JavaScript est implémenté avec le moteur JavaScript Duktape (https://duktape.org/).

Voir aussi : Objets JavaScript supplémentaires et fonctions globales

Utiliser des macros dans des scripts

Il est possible d'utiliser des macros utilisateur dans le code JavaScript. Si un script contient des macros utilisateur, ces macros sont résolues par le serveur/proxy avant l'exécution d'étapes de prétraitement spécifiques. Notez que lors du test des étapes de prétraitement dans l'interface Web, les valeurs de macro ne seront pas extraites 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 une valeur de macro {$THRESHOLD}, la valeur de seuil (si présente) sera renvoyée à la place :

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

Examples

The following examples illustrate how you can use JavaScript preprocessing. Each example contains a brief description, a function body for JavaScript preprocessing parameters, and the preprocessing step result (value accepted by the function → value returned by the function).

Example 1: Convert number (scientific notation to integer)

Convert a number from scientific notation to an integer.

return (Number(value))

Result: 2.62128e+07 → 26212800

Example 2: Convert number (binary to decimal)

Convert a binary number to a decimal number.

return(parseInt(value,2))

Result: 11010010 → 210

Example 3: Round a number

Round a number to 2 digits.

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

Result: 18.2345 → 18.23

Example 4: Count letters in a string

Count the number of letters in a string.

return (value.length)

Result: "zabbix" → 6

Example 5: Get time remaining

Get the remaining time (in seconds) until the expiration date of a certificate.

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);

Result: Feb 12 12:33:56 2022 GMT → 44380233

Example 6: Modify JSON (remove properties)

Modify a JSON data structure by removing any properties with the key "data_size" or "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)

Value accepted by the function:

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

Value returned by the function:

[
           {
               "table_name":"history"
           },
           {
               "table_name":"history_log"
           }
       ]
Example 7: Convert Apache status to JSON

Convert the value received from a web.page.get Zabbix agent item (e.g., web.page.get[http://127.0.0.1:80/server-status?auto]) to a JSON object.

// Convert Apache status to JSON
       
       // Split the value into substrings and put these substrings into an array
       var lines = value.split('\n');
       
       // Create an empty object "output"
       var output = {};
       
       // Create an object "workers" with predefined properties
       var workers = {
           '_': 0, 'S': 0, 'R': 0, 'W': 0,
           'K': 0, 'D': 0, 'C': 0, 'L': 0,
           'G': 0, 'I': 0, '.': 0
       };
       
       // Add the substrings from the "lines" array to the "output" object as properties (key-value pairs)
       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]);
           }
       }
       
       // Multiversion metrics
       output.ServerUptimeSeconds = output.ServerUptimeSeconds || output.Uptime;
       output.ServerVersion = output.ServerVersion || output.Server;
       
       // Parse "Scoreboard" property to get the worker count
       if (typeof output.Scoreboard === 'string') {
           for (var i = 0; i < output.Scoreboard.length; i++) {
               var char = output.Scoreboard[i];
       
               workers[char]++;
           }
       }
       
       // Add worker data to the "output" object
       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['.']
       };
       
       // Return JSON string
       return JSON.stringify(output);

Value accepted by the function:

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__..............................................................................................................................................

Value returned by the function:

{
           "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
           }
       }