4 JavaScript voorverwerking

Overzicht

Deze sectie geeft details over het voorbewerken met JavaScript.

JavaScript-voorverwerking

JavaScript-voorverwerking wordt uitgevoerd door een JavaScript-functie aan te roepen met een enkele parameter 'value' en de door de gebruiker geleverde functiebody. Het resultaat van de voorverwerking is de waarde die wordt geretourneerd door deze functie. Bijvoorbeeld, om de conversie van Fahrenheit naar Celsius uit te voeren, moet de gebruiker invoeren:

return (value - 32) * 5 / 9;

Deze code zal door de server worden ingepakt in een JavaScript-functie:

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

De invoerparameter 'value' wordt altijd doorgegeven als een tekenreeks. De geretourneerde waarde wordt automatisch omgezet naar een tekenreeks via de ToString() methode (als dit mislukt, wordt de fout als een tekenreekswaarde geretourneerd), met enkele uitzonderingen:

  • Het retourneren van een ongedefinieerde waarde resulteert in een fout.
  • Het retourneren van een null-waarde zorgt ervoor dat de invoerwaarde wordt verwijderd, vergelijkbaar met de voorverwerkingsoptie 'Waarde verwerpen' bij de actie 'Aangepast bij fout'.

Fouten kunnen worden geretourneerd door waarden/objecten te gooien (meestal strings of Error-objecten).

Bijvoorbeeld:

if (value == 0)
           throw "Invoerwaarde is nul";
       return 1/value;

Elk script heeft een time-out voor uitvoering van 10 seconden (afhankelijk van het script kan het langer duren voordat de time-out wordt geactiveerd). Als deze wordt overschreden, wordt een fout geretourneerd. Er geldt een limiet van 512 megabyte voor het geheugengebruik (64 megabyte voor Zabbix 6.4.4).

De bytecode van de JavaScript-voorverwerking wordt gecachet en opnieuw gebruikt wanneer de stap de volgende keer wordt toegepast. Elke wijziging in de voorverwerking van het item zal ervoor zorgen dat het gecachte script wordt gereset en later opnieuw wordt gecompileerd.

Aaneengesloten fouten tijdens de runtime (3 keer op rij) zullen ertoe leiden dat de engine opnieuw wordt geïnitialiseerd om het risico te verminderen dat één script de uitvoeringsomgeving voor de volgende scripts verbreekt (deze actie wordt gelogd met DebugLevel 4 en hoger).

JavaScript-voorverwerking wordt geïmplementeerd met de Duktape JavaScript-engine (https://duktape.org/).

Zie ook: Aanvullende JavaScript-objecten en globale functies

Het gebruik van macro's in scripts

Het is mogelijk om gebruikersmacro's te gebruiken in JavaScript-code. Als een script gebruikersmacro's bevat, worden deze macro's door de server/proxy opgelost voordat specifieke voorverwerkingsstappen worden uitgevoerd. Houd er rekening mee dat bij het testen van voorverwerkingsstappen in de frontend macrowaarden niet automatisch worden opgehaald en handmatig moeten worden ingevoerd.

De context wordt genegeerd wanneer een macro wordt vervangen door zijn waarde. De macrowaarde wordt letterlijk in de code ingevoegd, het is niet mogelijk om extra ontsnappingssequenties toe te voegen voordat de waarde in de JavaScript-code wordt geplaatst. Houd er rekening mee dat dit in sommige gevallen JavaScript-fouten kan veroorzaken.

In het onderstaande voorbeeld, als de ontvangen waarde hoger is dan een {$THRESHOLD} macrowaarde, wordt in plaats daarvan de drempelwaarde (indien aanwezig) geretourneerd:

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

Voorbeelden

De volgende voorbeelden illustreren hoe je JavaScript-voorverwerking kunt gebruiken.

Elk voorbeeld bevat een korte beschrijving, een functieblok voor JavaScript-voorverwerkingsparameters en het resultaat van de voorverwerkingsstap - de waarde die door de functie wordt geretourneerd.

Voorbeeld 1: Converteer een getal (wetenschappelijke notatie naar geheel getal)

Converteer het getal "2.62128e+07" van wetenschappelijke notatie naar een geheel getal.

return (Number(value))

Waarde die door de functie wordt geretourneerd: 26212800.

Voorbeeld 2: Converteer een getal (binair naar decimaal)

Converteer het binaire getal "11010010" naar een decimaal getal.

return(parseInt(value,2))

Waarde die door de functie wordt geretourneerd: 210.

Voorbeeld 3: Een getal afronden

Rond het getal "18,2345" af op 2 decimalen.

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

Waarde die door de functie wordt geretourneerd: 18,23.

Voorbeeld 4: Aantal letters tellen in een string

Tel het aantal letters in de string "Zabbix".

return (value.length)

Waarde die door de functie wordt geretourneerd: 6.

Voorbeeld 5: Resttijd berekenen

Bereken de resterende tijd (in seconden) tot de vervaldatum van een certificaat (12 februari 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);

Waarde die door de functie wordt geretourneerd: 44380233.

Voorbeeld 6: JSON-eigenschappen verwijderen

Wijzig de JSON-datastructuur door eigenschappen met de sleutel "data_size" of "index_size" te verwijderen.

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)

Waarde die door de functie wordt geaccepteerd:

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

Waarde die door de functie wordt geretourneerd:

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