5 Wstępne przetwarzanie JavaScript

Przegląd

Ta sekcja zawiera szczegółowe informacje dotyczące preprocessingu za pomocą JavaScript.

Nie używaj niezadeklarowanych przypisań w JavaScript używanym do preprocessingu. Użyj var, aby deklarować zmienne lokalne.

Wstępne przetwarzanie JavaScript

Wstępne przetwarzanie JavaScript jest wykonywane przez wywołanie funkcji JavaScript z jednym parametrem 'value' oraz treścią funkcji dostarczoną przez użytkownika. Wynikiem kroku wstępnego przetwarzania jest wartość zwrócona przez tę funkcję, na przykład aby wykonać konwersję z Fahrenheita na Celsjusza, wpisz:

return (value - 32)  * 5 / 9

w parametrach wstępnego przetwarzania JavaScript, które zostaną opakowane przez serwer w funkcję JavaScript:

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

Parametr wejściowy 'value' jest zawsze przekazywany jako ciąg znaków. Wartość zwracana jest automatycznie przekształcana do ciągu znaków za pomocą metody toString() (jeśli się to nie powiedzie, błąd jest zwracany jako wartość ciągu znaków), z kilkoma wyjątkami:

  • zwrócenie wartości undefined spowoduje błąd;
  • zwrócenie wartości null spowoduje odrzucenie wartości wejściowej, podobnie jak w przypadku wstępnego przetwarzania 'Discard value' dla akcji 'Custom on fail'.

Błędy mogą być zwracane przez zgłaszanie wartości/obiektów (zwykle ciągów znaków lub obiektów Error).

Na przykład:

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

Każdy skrypt ma limit wykonania wynoszący 10 sekund (w zależności od skryptu wyzwolenie limitu może potrwać dłużej); jego przekroczenie spowoduje zwrócenie błędu. Obowiązuje limit sterty wynoszący 512 megabajtów.

Kod bajtowy kroku wstępnego przetwarzania JavaScript jest buforowany i ponownie używany przy następnym zastosowaniu kroku. Wszelkie zmiany w krokach wstępnego przetwarzania pozycji spowodują zresetowanie buforowanego skryptu i jego późniejszą rekompilację.

Kolejne błędy wykonania w czasie działania (3 z rzędu) spowodują ponowne zainicjalizowanie silnika, aby ograniczyć możliwość, że jeden skrypt uszkodzi środowisko wykonawcze dla następnych skryptów (ta akcja jest rejestrowana przy DebugLevel 4 i wyższym).

Wstępne przetwarzanie JavaScript jest zaimplementowane przy użyciu silnika JavaScript Duktape.

Wbudowanych definicji metod obiektów JavaScript nie można redefiniować w skryptach wstępnego przetwarzania pozycji.

Zobacz także: Additional JavaScript objects and global functions

Używanie makr w skryptach

Można używać makr użytkownika (a także makr LLD w kontekście wykrywania niskiego poziomu) w kodzie JavaScript. Jeśli skrypt zawiera makra, są one rozwiązywane przez serwer/proxy przed wykonaniem określonych kroków przetwarzania wstępnego. Należy pamiętać, że podczas testowania kroków przetwarzania wstępnego w frontendzie wartości makr nie zostaną pobrane i trzeba je wprowadzić ręcznie.

Kontekst jest ignorowany, gdy makro zostaje zastąpione swoją wartością. Wartość makra jest wstawiana do kodu bez zmian; nie jest możliwe dodanie dodatkowego escapowania przed umieszczeniem wartości w kodzie JavaScript. Należy pamiętać, że w niektórych przypadkach może to powodować błędy JavaScript.

W poniższym przykładzie, jeśli otrzymana wartość przekracza wartość makra {$THRESHOLD}, zostanie zwrócona wartość progu (jeśli jest obecna):

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

Przykłady

Poniższe przykłady ilustrują, jak można używać preprocessingu JavaScript.

Każdy przykład zawiera krótki opis, treść funkcji dla parametrów preprocessingu JavaScript oraz wynik kroku preprocessingu — wartość zwracaną przez funkcję.

Przykład 1: Konwersja liczby (notacja naukowa na liczbę całkowitą)

Przekonwertuj liczbę „2.62128e+07” z notacji naukowej na liczbę całkowitą.

return (Number(value))

Wartość zwrócona przez funkcję: 26212800.

Przykład 2: Konwersja liczby (z systemu binarnego na dziesiętny)

Przekonwertuj liczbę binarną „11010010” na liczbę dziesiętną.

return(parseInt(value,2))

Wartość zwrócona przez funkcję: 210.

Przykład 3: Zaokrąglanie liczby

Zaokrąglij liczbę „18.2345” do 2 cyfr.

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

Wartość zwrócona przez funkcję: 18.23.

Przykład 4: Zliczanie liter w ciągu znaków

Policz liczbę liter w ciągu znaków „Zabbix”.

return (value.length)

Wartość zwrócona przez funkcję: 6.

Przykład 5: Pobierz pozostały czas

Pobierz pozostały czas (w sekundach) do daty wygaśnięcia certyfikatu (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);

Wartość zwracana przez funkcję: 44380233.

Przykład 6: Usuń właściwości JSON

Zmodyfikuj strukturę danych JSON, usuwając wszystkie właściwości z kluczem "data_size" lub "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)

Wartość przyjmowana przez funkcję:

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

Wartość zwracana przez funkcję:

[
    {
        "table_name":"history"
    },
    {
        "table_name":"history_log"
    }
]
Przykład 7: Konwersja statusu Apache do formatu JSON

Przekonwertuj wartość otrzymaną z pozycji Zabbix agent web.page.get (np. web.page.get[http://127.0.0.1:80/server-status?auto]) na obiekt JSON.

// Konwersja statusu Apache do formatu JSON

// Podziel wartość na podciągi i umieść te podciągi w tablicy
var lines = value.split('\n');

// Utwórz pusty obiekt "output"
var output = {};

// Utwórz obiekt "workers" ze wstępnie zdefiniowanymi właściwościami
var workers = {
    '_': 0, 'S': 0, 'R': 0, 'W': 0,
    'K': 0, 'D': 0, 'C': 0, 'L': 0,
    'G': 0, 'I': 0, '.': 0
};

// Dodaj podciągi z tablicy "lines" do obiektu "output" jako właściwości (pary klucz-wartość)
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]);
    }
}

// Metryki dla wielu wersji
output.ServerUptimeSeconds = output.ServerUptimeSeconds || output.Uptime;
output.ServerVersion = output.ServerVersion || output.Server;

// Przeanalizuj właściwość "Scoreboard", aby uzyskać liczbę workerów
if (typeof output.Scoreboard === 'string') {
    for (var i = 0; i < output.Scoreboard.length; i++) {
        var char = output.Scoreboard[i];

        workers[char]++;
    }
}

// Dodaj dane workerów do obiektu "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['.']
};

// Zwróć ciąg JSON
return JSON.stringify(output);

Wartość akceptowana przez funkcję:

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

Wartość zwracana przez funkcję:

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