Rezolvăm probleme practice în Zabbix folosind JavaScript

Rezolvăm probleme practice în Zabbix folosind JavaScript
Tihon Uskov, inginer echipa de integrare Zabbix

Zabbix este o platformă personalizabilă care este folosită pentru a monitoriza orice tip de date. De la cele mai vechi versiuni de Zabbix, administratorii de monitorizare au avut capacitatea de a rula diverse scripturi prin Acţiuni pentru verificări asupra nodurilor rețelei țintă. În același timp, lansarea scripturilor a dus la o serie de dificultăți, inclusiv necesitatea de a susține scripturi, livrarea acestora către nodurile de comunicare și proxy-uri, precum și suportul pentru diferite versiuni.

JavaScript pentru Zabbix

În aprilie 2019, Zabbix 4.2 a fost introdus cu preprocesare JavaScript. Mulți oameni s-au încântat de ideea de a abandona scripturile care preiau date undeva, le digeră și le furnizează într-un format pe care îl înțelege Zabbix și efectuează verificări simple care vor primi date care nu sunt gata pentru stocare și procesare de către Zabbix și apoi procesați acest flux de date folosind instrumentele Zabbix și JavaScript. Împreună cu descoperirea la nivel scăzut și elementele dependente care au apărut în Zabbix 3.4, am obținut un concept destul de flexibil pentru sortarea și gestionarea datelor primite.

În Zabbix 4.4, ca o continuare logică a preprocesării în JavaScript, a apărut o nouă metodă de notificare - Webhook, care poate fi folosită pentru a integra cu ușurință notificările Zabbix cu aplicații terțe.

JavaScript și Duktapes

De ce au fost alese JavaScript și Duktape? Au fost luate în considerare diferite opțiuni pentru limbi și motoare:

  • Lua - Lua 5.1
  • Lua - LuaJIT
  • Javascript - Duktape
  • Javascript - JerryScript
  • Python încorporat
  • Perl încorporat

Principalele criterii de selecție au fost prevalența, ușurința de integrare a motorului în produs, consumul redus de resurse și performanța generală a motorului și siguranța introducerii codului în acest limbaj în monitorizare. Pe baza combinației de indicatori, JavaScript a câștigat pe motorul Duktape.

Rezolvăm probleme practice în Zabbix folosind JavaScript

Criterii de selecție și testare a performanței

Caracteristicile Duktape:

— Standard ECMAScript E5/E5.1
— module Zabbix pentru Duktape:

  • Zabbix.log() - vă permite să scrieți mesaje cu diferite niveluri de detaliu direct în jurnalul Zabbix Server, ceea ce face posibilă corelarea erorilor, de exemplu, într-un Webhook, cu starea serverului.
  • CurlHttpRequest() - vă permite să faceți solicitări HTTP către rețea, pe care se bazează utilizarea Webhook.
  • atob() și btoa() - vă permite să codificați și să decodați șiruri în format Base64.

NOTĂ. Duktape respectă standardele ACME. Zabbix folosește versiunea 2015 a scenariului. Modificările ulterioare sunt minore, deci pot fi ignorate..

Magia JavaScript

Toată magia JavaScript-ului constă în tastarea dinamică și turnarea tipurilor: șir, numeric și boolean.

Aceasta înseamnă că nu este necesar să declarați în prealabil ce tip ar trebui să returneze variabila o valoare.

În operațiile matematice, valorile returnate de operatorii de funcție sunt convertite în numere. Excepția de la astfel de operațiuni este adăugarea, deoarece dacă cel puțin unul dintre termeni este un șir, conversia șirului se aplică tuturor termenilor.

NOTĂ. Metodele responsabile pentru astfel de conversii sunt de obicei implementate în prototipurile părinte ale obiectului, valoarea и toString. valoarea apelat în timpul conversiei numerice și întotdeauna înaintea metodei toString. Metodă valoarea trebuie să returneze valorile primitive, altfel rezultatul său este ignorat.

O metodă este apelată pe un obiect valoarea. Dacă nu este găsită sau nu returnează o valoare primitivă, metoda este apelată toString. Dacă metoda toString nu a fost găsit, căutând valoarea în prototipul obiectului și totul se repetă până când procesarea valorii este finalizată și toate valorile din expresie sunt turnate la același tip. Dacă obiectul implementează o metodă toString, care returnează o valoare primitivă, apoi este cea care este folosită pentru conversia șirurilor. Cu toate acestea, rezultatul aplicării acestei metode nu este neapărat un șir.

De exemplu, dacă pentru pentru obiect 'objeste definită metoda toString,

`var obj = { toString() { return "200" }}` 

metodă toString returnează exact un șir, iar când adăugăm un șir cu un număr, obținem un șir lipit:

`obj + 1 // '2001'` 

`obj + 'a' // ‘200a'`

Dar dacă rescrii toString, astfel încât metoda să returneze un număr, atunci când obiectul este adăugat, se va efectua o operație matematică cu conversie numerică și se va obține rezultatul adunării matematice.

`var obj = { toString() { return 200 }}` 

`obj + 1 // '2001'`

În acest caz, dacă efectuăm adunarea cu un șir, se efectuează o conversie de șir și obținem un șir lipit.

`obj + 'a' // ‘200a'`

Acesta este motivul unui număr mare de greșeli ale utilizatorilor JavaScript începători.

Metoda toString puteți scrie o funcție care va crește valoarea curentă a obiectului cu 1.

Rezolvăm probleme practice în Zabbix folosind JavaScript
Executarea scriptului, cu condiția ca variabila să fie egală cu 3 și, de asemenea, egală cu 4.

În comparație cu o distribuție (==), metoda este executată de fiecare dată toString cu functie de crestere a valorii. În consecință, cu fiecare comparație ulterioară, valoarea crește. Acest lucru poate fi evitat prin utilizarea comparației non-cast (===).

Rezolvăm probleme practice în Zabbix folosind JavaScript
Comparație fără tip turnare

NOTĂ. Nu folosiți inutil Comparația de distribuție.

Pentru scripturile complexe, cum ar fi Webhook-urile cu logică complexă, care necesită comparație cu tipul de turnare, se recomandă prescrierea verificărilor pentru valorile care returnează variabile și gestionează inconsecvențele și erorile.

Webhook Media

La sfârșitul anului 2019 și începutul anului 2020, echipa de integrare Zabbix a dezvoltat în mod activ webhook-uri și integrări standard care vin cu distribuția Zabbix.

Rezolvăm probleme practice în Zabbix folosind JavaScript
Link la documentație

preprocesare

  • Apariția preprocesării în JavaScript a făcut posibilă abandonarea majorității scripturilor externe, iar în prezent în Zabbix puteți obține orice valoare și o puteți converti într-o valoare complet diferită.
  • Preprocesarea în Zabbix este implementată de codul JavaScript, care, atunci când este compilat în bytecode, este convertit într-o funcție care ia o singură valoare ca parametru valoare ca șir (un șir poate conține atât o cifră, cât și un număr).
  • Deoarece ieșirea este o funcție, la sfârșitul scriptului este necesar reveni.
  • Este posibil să utilizați macrocomenzi personalizate în cod.
  • Resursele pot fi limitate nu numai la nivel de sistem de operare, ci și programatic. Pasului de preprocesare i se alocă maximum 10 megaocteți de memorie RAM și o limită de timp de rulare de 10 secunde.

Rezolvăm probleme practice în Zabbix folosind JavaScript

NOTĂ. Valoarea de timeout de 10 secunde este destul de mare, deoarece colectarea condiționată a mii de elemente de date într-o secundă conform unui scenariu de preprocesare destul de „greu” poate încetini Zabbix. Prin urmare, nu este recomandat să utilizați preprocesarea pentru a executa script-uri JavaScript cu drepturi depline prin așa-numitele elemente de date umbră (articole fictive), care sunt rulate doar pentru a efectua preprocesare..

Puteți verifica codul prin testul de preprocesare sau folosind utilitarul zabbix_js:

`zabbix_js -s *script-file -p *input-param* [-l log-level] [-t timeout]`

`zabbix_js -s script-file -i input-file [-l log-level] [-t timeout]`

`zabbix_js -h`

`zabbix_js -V`

Sarcini practice

Sarcină 1

Înlocuiți elementul calculat cu preprocesare.

Condiție: Obțineți temperatura în Fahrenheit de la senzor pentru a o stoca în Celsius.

Anterior, am crea un articol care colectează temperatura în grade Fahrenheit. După aceea, un alt element de date (calculat) care ar converti Fahrenheit în Celsius folosind o formulă.

Probleme:

  • Este necesar să duplicați elementele de date și să stocați toate valorile în baza de date.
  • Trebuie să fiți de acord asupra intervalelor pentru elementul de date „părinte” care este calculat și utilizat în formulă și pentru elementul de date calculat. În caz contrar, elementul calculat poate intra într-o stare neacceptată sau poate calcula o valoare anterioară, ceea ce va afecta fiabilitatea rezultatelor monitorizării.

O soluție a fost să se îndepărteze de intervalele flexibile de verificare în favoarea intervalelor fixe pentru a se asigura că elementul calculat este evaluat după elementul care primește datele (în cazul nostru, temperatura în grade Fahrenheit).

Dar dacă, de exemplu, folosim șablonul pentru a verifica un număr mare de dispozitive, iar verificarea este efectuată o dată la 30 de secunde, Zabbix „hack” timp de 29 de secunde, iar în ultima secundă începe să verifice și să calculeze. Acest lucru creează o coadă și afectează performanța. Prin urmare, se recomandă utilizarea intervalelor fixe doar dacă este cu adevărat necesar.

În această problemă, soluția optimă este o preprocesare JavaScript pe o linie care convertește grade Fahrenheit în grade Celsius:

`return (value - 32) * 5 / 9;`

Este rapid și ușor, nu trebuie să creați elemente de date inutile și să păstrați un istoric asupra lor și puteți utiliza, de asemenea, intervale flexibile pentru verificări.

Rezolvăm probleme practice în Zabbix folosind JavaScript

`return (parseInt(value) + parseInt("{$EXAMPLE.MACRO}"));`

Dar, dacă într-o situație ipotetică este necesară adăugarea elementului de date primit, de exemplu, cu orice constantă definită în macro, trebuie să se țină cont de faptul că parametrul valoare se extinde într-un șir. Într-o operație de adăugare de șiruri, două șiruri sunt pur și simplu combinate într-unul singur.

Rezolvăm probleme practice în Zabbix folosind JavaScript

`return (value + "{$EXAMPLE.MACRO}");`

Pentru a obține rezultatul unei operații matematice, este necesar să convertiți tipurile de valori obținute într-un format numeric. Pentru aceasta puteți folosi funcția parseInt(), care produce un număr întreg, o funcție parseFloat(), care produce o zecimală sau o funcție număr, care returnează un număr întreg sau zecimal.

Sarcina 2

Obțineți timpul în secunde până la sfârșitul certificatului.

Condiție: un serviciu emite o dată de expirare a certificatului în formatul „12 februarie 12:33:56 2022 GMT”.

În ECMAScript5 data.parse() acceptă o dată în format ISO 8601 (AAAA-LL-ZZAH:mm:ss.sssZ). Este necesar să-i aruncați un șir în formatul MMM DD AAAA HH:mm:ss ZZ

problemă: Valoarea lunii este exprimată ca text, nu ca număr. Datele în acest format nu sunt acceptate de Duktape.

Exemplu de soluție:

  • În primul rând, este declarată o variabilă care ia o valoare (întregul script este o declarație de variabile care sunt enumerate separate prin virgule).

  • În prima linie primim data în parametru valoare și separați-l cu spații folosind metoda împărţi. Astfel, obținem o matrice, în care fiecare element al matricei, începând cu indicele 0, corespunde unui element dată înainte și după un spațiu. împărțit(0) - luna, împărțit(1) - număr, împărțit(2) - un șir cu timpul, etc. După aceea, fiecare element al datei poate fi accesat prin index în matrice.

`var split = value.split(' '),`

  • Fiecare lună (în ordine cronologică) corespunde indexului poziției sale în matrice (de la 0 la 11). Pentru a converti o valoare text într-o valoare numerică, se adaugă una la indexul lunii (deoarece lunile sunt numerotate începând cu 1). În acest caz, expresia cu adăugarea unuia este luată între paranteze, deoarece altfel se va obține un șir, nu un număr. La final facem felie() - tăiați matricea de la sfârșit pentru a lăsa doar două caractere (ceea ce este important pentru luni de zile cu un număr din două cifre).

`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),`

  • Formăm un șir în format ISO din valorile obținute prin adăugarea obișnuită de șiruri în ordinea corespunzătoare.

`ISOdate = split[3] + '-' + month_index + '-' + split[1] + 'T' + split[2],`

Datele în formatul rezultat sunt numărul de secunde din 1970 până la un moment dat în viitor. Este aproape imposibil să utilizați datele în formatul primit în declanșatoare, deoarece Zabbix vă permite să operați numai cu macrocomenzi {Data} и {Timp}, care returnează data și ora într-un format ușor de utilizat.

  • Apoi putem obține data curentă în JavaScript în format Unix Timestamp și o putem scădea din data de expirare a certificatului rezultată pentru a obține numărul de milisecunde de acum până la expirarea certificatului.

`now = Date.now();`

  • Împărțim valoarea primită la o mie pentru a obține secunde în Zabbix.

`return parseInt((Date.parse(ISOdate) - now) / 1000);`

În declanșator, puteți specifica expresia „ultimul' urmat de un set de cifre care corespunde numărului de secunde din perioada la care doriți să răspundeți, de exemplu, în săptămâni. Astfel, declanșatorul va anunța că certificatul expiră într-o săptămână.

NOTĂ. Acordați atenție utilizării parseInt() în funcțiune revenipentru a converti numărul fracționar rezultat din împărțirea milisecundelor într-un număr întreg. De asemenea, puteți utiliza parseFloat() și stocați date fracționale.

Urmăriți raportul

Sursa: www.habr.com

Adauga un comentariu