4 Preprocessament de JavaScript

Vista general

Aquesta secció proveeix detalls del pretractrament per a JavaScript.

Preprocessament de JavaScript

El preprocessament de JavaScript es realitza invocant la funció JavaScript amb un únic paràmetre "valor" i un cos de funció subministrat per l'usuari. El resultat de la passa de preprocessament és el valor que retorna aquesta funció, per exemple, per fer una conversió de Fahrenheit a Celsius, l'usuari introduiria:

return (value - 32) * 5 / 9

als paràmetres de preprocessament de JavaScript, que s'embolcallen en una funció JavaScript per servidor:

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

El paràmetre d'entrada 'valor' sempre es passa com a cadena. El valor de retorn es converteix automàticament a una cadena mitjançant el mètode ToString() (si falla, l'error es retorna com a valor de cadena), amb algunes excepcions:

  • retornar un valor no definit donarà lloc a un error
  • retornar un valor nul farà que el valor d'entrada s'esborri, de la mateixa manera que el preprocessament 'Esborra el valor' a l'acció 'Personalitzar en cas d'error'.

Els errors es poden retornar iniciant valors/objectes (normalment cadenes o objectes d'error).

Per exemple:

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

Cada script té un temps d'espera d'execució de 10 segons (depenent de l'script, el temps d'espera pot trigar més a activar-se); superar-lo retornarà un error. S'aplica un límit d'emmagatzematge dinàmic de 512 Mo (abans de Zabbix 6.4.4 era de 64 megaoctets).

El bytecode de la passa de preprocessament de JavaScript s'emmagatzema a la memòria cau i es reutilitza la propera vegada que s'aplica el pas. Qualsevol canvi als passos de preprocessament de l'element farà que l'script desat a la memòria cau es restableixi i es torni a compilar posteriorment.

Els errors d'execució consecutius (3 de seguits) faran que el motor es restableixi per esmorteir la possibilitat que un script trenqui l'entorn d'execució per als scripts posteriors (aquesta acció es registra amb DebugLevel a 4 i posteriors).

El preprocessament de JavaScript s'implementa amb el motor JavaScript de Duktape (https://duktape.org/).

Veieu també: Objectes JavaScript addicionals i funcions globals

Emprar macros als scripts

És possible emprar macros d'usuari al codi JavaScript. Si un script conté macros d'usuari, aquestes macros les resol el servidor/proxy abans de realitzar passes específiques de preprocessament. Tingueu en compte que quan proveu les passes de preprocessament a la interfície web, els valors de macro no s'extreuran i caldrà introduir-los manualment.

El context s'ignora quan se substitueix una macro pel seu valor. El valor de la macro s'insereix tal com és al codi, no és possible afegir una escapada addicional abans de col·locar el valor al codi JavaScript. Tingueu en compte que això pot provocar errors de JavaScript en alguns casos.

A l'exemple següent, si el valor rebut supera un valor de macro {$THRESHOLD}, es retornarà el valor de llindar (si és present):

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

Exemples

Els exemples següents il·lustren com podeu emprar el preprocessament de JavaScript.

Cada exemple conté una breu descripció, un cos de la funció per als paràmetres de preprocessament de JavaScript i el resultat de la passa de preprocessament: valor retornat per la funció.

Exemple 1: Convertir un nombre (notació científica a enter)

Converteix el nombre "2.62128e+07" de notació científica a enter.

return (Number(value))

Valor retornat per la funció: 26212800.

Exemple 2: Converteix un nombre (binari a decimal)

Converteix el nombre binari "11010010" a un nombre decimal.

return(parseInt(value,2))

Valor retornat per la funció: 210.

Exemple 3: Arrodonir un nombre

Arrodoneix el nombre "18.2345" a 2 dígits.

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

Valor retornat per la funció: 18.23.

Exemple 4: Comptar lletres d'una cadena

compta el nombre de lletres de la cadena "Zabbix".

return (value.length)

Valor retornat per la funció: 6.

Example 5: Obtindre el temps restant

Obté el temps restant (en segons) fins la data d'expiració del certificat (Feb 12 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);

Valor retornat per la funció: 44380233.

Example 6: Esborrar les propietats JSON

Modifica l'estructura de dades JSON esborrant qualsevol propietat amb la clau "data_size" o "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"
           }
       ]

Valor retornat per la funció:

[
           {
               "table_name":"history"
           },
           {
               "table_name":"history_log"
           }
       ]
Exemple 7: Convertir l'estat Apache a JSON

Converteix el valor rebut d'un element d'agent Zabbix web.page.get (p. ex., web.page.get[http://127.0.0.1 :80/server-status?auto]) a un objecte JSON.

// Converteix l'estat Apache a JSON
       
       // Divideix el valor en subcadenes i posa aquestes subcadenes en una matriu
       var lines = value.split('\n');
       
       // Crea un objecte buit "output"
       var output = {};
       
       // Crea un objecte "workers" amb les propietats predefinides
       var workers = {
           '_': 0, 'S': 0, 'R': 0, 'W': 0,
           'K': 0, 'D': 0, 'C': 0, 'L': 0,
           'G': 0, 'I': 0, '.': 0
       };
       
       // Afegiu les subcadenes de la matriu "línies" a l'objecte "sortida" com a propietats (parelles clau-valor)
       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 multiversió
       output.ServerUptimeSeconds = output.ServerUptimeSeconds || output.Uptime;
       output.ServerVersion = output.ServerVersion || output.Server;
       
       // Analitza la propietat "Tauler de marcador" per obtindre el recompte de treballadors
       if (typeof output.Scoreboard === 'string') {
           for (var i = 0; i < output.Scoreboard.length; i++) {
               var char = output.Scoreboard[i];
       
               workers[char]++;
           }
       }
       
       // Afegeix informació del treballador a l'objecte "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['.']
       };
       
       // Retorna una cadena JSON
       return JSON.stringify(output);

Valor acceptat per la funció:

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

Valor retornat per la funció:

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