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. Wynik kroku wstępnego przetwarzania jest wartością zwracaną 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 10-sekundowy limit czasu wykonania (w zależności od skryptu wyzwolenie limitu może nastąpić później); jego przekroczenie spowoduje zwrócenie błędu. Wymuszany jest 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 pozycja spowodują zresetowanie buforowanego skryptu i jego późniejszą rekompilację.

Kolejne niepowodzenia w czasie wykonywania (3 z rzędu) spowodują ponowne zainicjowanie silnika, aby ograniczyć możliwość, że jeden skrypt zakłóci środowisko wykonawcze kolejnych 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 pozycja.

Zobacz też: Additional JavaScript objects and global functions

Używanie makr w skryptach

Możliwe jest używanie makr użytkownika (a także makr LLD w kontekście wykrywania niskiego poziomu) w kodzie JavaScript. Jeśli skrypt zawiera makra użytkownika, makra te są rozwiązywane przez serwer/proxy przed wykonaniem określonych kroków preprocessing. Należy pamiętać, że podczas testowania kroków preprocessing w frontend wartości makr nie będą pobierane i trzeba je wprowadzić ręcznie.

Kontekst jest ignorowany, gdy makro jest zastępowane swoją wartością. Wartość makra jest wstawiana do kodu w niezmienionej postaci; nie ma możliwości dodania dodatkowego escaping 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 odebrana wartość przekracza wartość makra {$THRESHOLD}, zamiast niej 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
    }
}