Pre-elaborazione JavaScript

Panoramica

Questa sezione fornisce dettagli sulla pre-elaborazione tramite JavaScript.

Non utilizzare assegnazioni non dichiarate nel JavaScript di pre-elaborazione. Usa var per dichiarare le variabili locali.

Preprocessing JavaScript

La preprocessing JavaScript viene eseguita richiamando una funzione JavaScript con un singolo parametro 'value' e un corpo di funzione fornito dall'utente. Il risultato del passaggio di preprocessing è il valore restituito da questa funzione; ad esempio, per eseguire la conversione da Fahrenheit a Celsius, inserisci:

return (value - 32)  * 5 / 9

nei parametri di preprocessing JavaScript, che verranno racchiusi in una funzione JavaScript da server:

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

Il parametro di input 'value' viene sempre passato come stringa. Il valore restituito viene automaticamente convertito in stringa tramite il metodo toString() (se l'operazione fallisce, l'errore viene restituito come valore stringa), con alcune eccezioni:

  • la restituzione del valore undefined genererà un errore;
  • la restituzione del valore null farà sì che il valore di input venga scartato, in modo simile alla preprocessing 'Discard value' nell'azione 'Custom on fail'.

Gli errori possono essere restituiti lanciando valori/oggetti (normalmente stringhe oppure oggetti Error).

Ad esempio:

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

Ogni script ha un timeout di esecuzione di 10 secondi (a seconda dello script, potrebbe volerci più tempo prima che il timeout venga attivato); il superamento di questo limite restituirà un errore. Viene imposto un limite di heap di 512 megabyte.

Il bytecode del passaggio di preprocessing JavaScript viene memorizzato nella cache e riutilizzato quando il passaggio viene applicato la volta successiva. Qualsiasi modifica ai passaggi di preprocessing dell'item causerà il reset dello script memorizzato nella cache e la sua ricompilazione in un secondo momento.

Errori di runtime consecutivi (3 di fila) causeranno la reinizializzazione del motore per mitigare la possibilità che uno script comprometta l'ambiente di esecuzione per gli script successivi (questa azione viene registrata con DebugLevel 4 e superiore).

La preprocessing JavaScript è implementata con il motore JavaScript Duktape.

Le definizioni dei metodi degli oggetti JavaScript integrati non possono essere ridefinite negli script di preprocessing dell'item.

Vedi anche: Additional JavaScript objects and global functions

Utilizzo delle macro negli script

È possibile utilizzare le macro utente (così come le macro LLD nel contesto del low-level discovery) nel codice JavaScript. Se uno script contiene macro utente, queste macro vengono risolte da server/proxy prima dell'esecuzione di specifici passaggi di preprocessing. Si noti che durante il test dei passaggi di preprocessing nel frontend, i valori delle macro non verranno recuperati e dovranno essere inseriti manualmente.

Il contesto viene ignorato quando una macro viene sostituita con il suo valore. Il valore della macro viene inserito nel codice così com'è; non è possibile aggiungere un escaping aggiuntivo prima di inserire il valore nel codice JavaScript. Si tenga presente che in alcuni casi ciò può causare errori JavaScript.

Nell'esempio seguente, se il valore ricevuto supera il valore della macro {$THRESHOLD}, verrà restituito invece il valore di soglia (se presente):

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

Esempi

I seguenti esempi illustrano come è possibile utilizzare il preprocessing JavaScript.

Ogni esempio contiene una breve descrizione, il corpo di una funzione per i parametri di preprocessing JavaScript e il risultato del passaggio di preprocessing, ovvero il valore restituito dalla funzione.

Esempio 1: Convertire un numero (notazione scientifica in intero)

Convertire il numero "2.62128e+07" dalla notazione scientifica a un intero.

return (Number(value))

Valore restituito dalla funzione: 26212800.

Esempio 2: Convertire un numero (da binario a decimale)

Convertire il numero binario "11010010" in un numero decimale.

return(parseInt(value,2))

Valore restituito dalla funzione: 210.

Esempio 3: Arrotondare un numero

Arrotonda il numero "18.2345" a 2 cifre.

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

Valore restituito dalla funzione: 18.23.

Esempio 4: contare le lettere in una stringa

Conta il numero di lettere nella stringa "Zabbix".

return (value.length)

Valore restituito dalla funzione: 6.

Esempio 5: Ottenere il tempo rimanente

Ottieni il tempo rimanente (in secondi) fino alla data di scadenza di un certificato (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);

Valore restituito dalla funzione: 44380233.

Esempio 6: Rimuovere proprietà JSON

Modificare la struttura dei dati JSON rimuovendo tutte le proprietà con la chiave "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)

Valore accettato dalla funzione:

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

Valore restituito dalla funzione:

[
    {
        "table_name":"history"
    },
    {
        "table_name":"history_log"
    }
]
Esempio 7: Convertire lo stato di Apache in JSON

Convertire il valore ricevuto da un item Zabbix agent web.page.get (ad esempio, web.page.get[http://127.0.0.1:80/server-status?auto]) in un oggetto JSON.

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

Valore accettato dalla funzione:

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

Valore restituito dalla funzione:

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