Rješavamo praktične probleme u Zabbixu koristeći JavaScript

Rješavamo praktične probleme u Zabbixu koristeći JavaScript
Tihon Uskov, inženjer Zabbix integracijskog tima

Zabbix je prilagodljiva platforma koja se koristi za praćenje bilo koje vrste podataka. Od najranijih verzija Zabbixa, administratori za praćenje imali su mogućnost pokretanja raznih skripti putem Akcije za provjere ciljnih mrežnih čvorova. U isto vrijeme, pokretanje skripti dovelo je do brojnih poteškoća, uključujući potrebu za podrškom za skripte, njihovu isporuku komunikacijskim čvorovima i proxyjima, kao i podršku za različite verzije.

JavaScript za Zabbix

U travnju 2019. predstavljen je Zabbix 4.2 s predprocesiranjem JavaScripta. Mnogi su se ljudi oduševili idejom napuštanja pisanja skripti koje negdje uzimaju podatke, probavljaju ih i daju u formatu koji Zabbix razumije, te izvode jednostavne provjere koje će primati podatke koji nisu spremni za pohranu i obradu od strane Zabbixa, i zatim obradite ovaj tok podataka koristeći Zabbix i JavaScript alate. U kombinaciji s otkrivanjem niske razine i ovisnim stavkama koje su se pojavile u Zabbixu 3.4, dobili smo prilično fleksibilan koncept sortiranja i upravljanja primljenim podacima.

U Zabbixu 4.4, kao logičan nastavak predprocesiranja u JavaScriptu, pojavila se nova metoda obavijesti - Webhook, pomoću koje je moguće jednostavno integrirati Zabbix obavijesti s aplikacijama trećih strana.

JavaScript i Duktapes

Zašto su odabrani JavaScript i Duktape? Razmotrene su različite opcije za jezike i motore:

  • Lua - Lua 5.1
  • Lua - LuaJIT
  • Javascript - Duktape
  • Javascript - JerryScript
  • Ugrađeni Python
  • Ugrađeni Perl

Glavni kriteriji odabira bili su rasprostranjenost, jednostavnost integracije motora u proizvod, niska potrošnja resursa i ukupna izvedba motora te sigurnost uvođenja koda na ovom jeziku u praćenje. Na temelju kombinacije pokazatelja, JavaScript je pobijedio na Duktape motoru.

Rješavamo praktične probleme u Zabbixu koristeći JavaScript

Kriteriji odabira i testiranje učinkovitosti

Značajke Duktapea:

— Standardno ECMAScript E5/E5.1
- Zabbix moduli za Duktape:

  • Zabbix.log() - omogućuje pisanje poruka s različitim razinama detalja izravno u zapisnik Zabbix poslužitelja, što omogućuje povezivanje pogrešaka, na primjer, u Webhooku, sa stanjem poslužitelja.
  • CurlHttpRequest() - omogućuje vam postavljanje HTTP zahtjeva prema mreži, na čemu se temelji korištenje Webhooka.
  • atob() i btoa() - omogućuje kodiranje i dekodiranje nizova u Base64 formatu.

NAPOMENA. Duktape je u skladu s ACME standardima. Zabbix koristi verziju skripte iz 2015. Naknadne promjene su manje, pa se mogu zanemariti..

JavaScript magija

Sva magija JavaScripta leži u dinamičkom tipkanju i pretvaranju tipa: string, numerički i booleov.

To znači da nije potrebno unaprijed deklarirati koju vrstu varijabla treba vratiti vrijednost.

U matematičkim operacijama, vrijednosti koje vraćaju funkcijski operatori pretvaraju se u brojeve. Iznimka od takvih operacija je zbrajanje, jer ako je barem jedan od pojmova niz, konverzija niza se primjenjuje na sve pojmove.

NAPOMENA. Metode odgovorne za takve transformacije obično su implementirane u roditeljske prototipove objekta, vrijednost и toString. vrijednost poziva se tijekom numeričke konverzije i uvijek prije metode toString. Metoda vrijednost mora vratiti primitivne vrijednosti, inače se njegov rezultat zanemaruje.

Metoda se poziva na objektu vrijednost. Ako se ne pronađe ili ne vrati primitivnu vrijednost, metoda se poziva toString. Ako se metoda toString nije pronađeno, tražim vrijednost u prototipu objekta, i sve se ponavlja dok se ne završi obrada vrijednosti i sve vrijednosti u izrazu se pretvore u isti tip. Ako objekt implementira metodu toString, koji vraća primitivnu vrijednost, onda se on koristi za pretvorbu niza. Međutim, rezultat primjene ove metode nije nužno niz.

Na primjer, ako za za objekt 'obj' metoda je definirana toString,

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

način toString vraća točno niz, a zbrajanjem niza s brojem dobivamo slijepljeni niz:

`obj + 1 // '2001'` 

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

Ali ako prepišete toString, tako da metoda vraća broj, kada se objekt doda, izvršit će se matematička operacija s numeričkom konverzijom i dobit će se rezultat matematičkog zbrajanja.

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

`obj + 1 // '2001'`

U ovom slučaju, ako izvodimo zbrajanje s nizom, vrši se konverzija niza, te dobivamo zalijepljeni niz.

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

To je razlog velikog broja pogrešaka početnika u JavaScriptu.

Metoda toString možete napisati funkciju koja će povećati trenutnu vrijednost objekta za 1.

Rješavamo praktične probleme u Zabbixu koristeći JavaScript
Izvršenje skripte pod uvjetom da je varijabla jednaka 3, a također je jednaka 4.

U usporedbi s cast (==), metoda se izvršava svaki put toString s funkcijom povećanja vrijednosti. Sukladno tome, svakom sljedećom usporedbom vrijednost raste. To se može izbjeći korištenjem ne-cast usporedbe (===).

Rješavamo praktične probleme u Zabbixu koristeći JavaScript
Usporedba bez određivanja tipa

NAPOMENA. Ne koristite usporedbu glumaca bez potrebe.

Za složene skripte, kao što su Webhookovi sa složenom logikom, koje zahtijevaju usporedbu s pretvaranjem tipa, preporučuje se unaprijed napisati provjere za vrijednosti koje vraćaju varijable i obrađuju nedosljednosti i pogreške.

Webhook mediji

Krajem 2019. i početkom 2020. Zabbix integracijski tim aktivno je razvijao Webhookove i integracije izvan okvira koje dolaze sa Zabbix distribucijom.

Rješavamo praktične probleme u Zabbixu koristeći JavaScript
Poveznica za dokumentacija

predobrada

  • Pojava predprocesiranja u JavaScriptu omogućila je napuštanje većine vanjskih skripti, a trenutno u Zabbixu možete dobiti bilo koju vrijednost i pretvoriti je u potpuno drugu vrijednost.
  • Predprocesiranje u Zabbixu implementira JavaScript kod, koji se, kada se kompajlira u bajt kod, pretvara u funkciju koja uzima jednu vrijednost kao parametar vrijednost kao niz (string može sadržavati i znamenku i broj).
  • Budući da je izlaz funkcija, na kraju skripte je potrebno povratak.
  • U kodu je moguće koristiti prilagođene makronaredbe.
  • Resursi se mogu ograničiti ne samo na razini operativnog sustava, već i programski. Koraku pretprocesiranja dodijeljeno je najviše 10 megabajta RAM-a i ograničenje vremena izvođenja od 10 sekundi.

Rješavamo praktične probleme u Zabbixu koristeći JavaScript

NAPOMENA. Vrijednost vremenskog ograničenja od 10 sekundi je dosta, jer prikupljanje uvjetnih tisuća stavki podataka u 1 sekundi prema prilično "teškom" scenariju pretprocesiranja može usporiti Zabbix. Stoga se ne preporučuje korištenje pretprocesiranja za izvršavanje potpunih JavaScript skripti kroz takozvane elemente podataka u sjeni (dummy stavke), koji se pokreću samo za izvođenje predprocesiranja.

Možete provjeriti svoj kod putem testa pretprocesiranja ili pomoću uslužnog programa 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`

Praktični zadaci

Zadatak 1

Zamijenite izračunatu stavku pretprocesiranjem.

Stanje: Uzmite temperaturu u Fahrenheitima od senzora za pohranjivanje u Celzijusima.

Prije bismo stvorili stavku koja prikuplja temperaturu u stupnjevima Fahrenheita. Nakon toga, još jedna podatkovna stavka (izračunata) koja bi pretvorila Fahrenheite u Celzijuse pomoću formule.

Problemi:

  • Potrebno je duplicirati elemente podataka i pohraniti sve vrijednosti u bazu podataka.
  • Morate dogovoriti intervale za "roditeljsku" podatkovnu stavku koja se izračunava i koristi u formuli, te za izračunatu podatkovnu stavku. U suprotnom, izračunata stavka može prijeći u nepodržano stanje ili izračunati prethodnu vrijednost, što će utjecati na pouzdanost rezultata praćenja.

Jedno je rješenje bilo odmaknuti se od fleksibilnih intervala provjere u korist fiksnih intervala kako bi se osiguralo da se izračunata stavka procjenjuje nakon stavke koja prima podatke (u našem slučaju, temperatura u stupnjevima Fahrenheita).

Ali ako npr. koristimo predložak za provjeru velikog broja uređaja, a provjera se vrši jednom svakih 30 sekundi, Zabbix “hakira” 29 sekundi, a zadnje sekunde počinje provjeravati i računati. To stvara red čekanja i utječe na performanse. Stoga se preporuča koristiti fiksne intervale samo ako je to stvarno potrebno.

U ovom problemu, optimalno rješenje je predobrada JavaScripta u jednom retku koja pretvara stupnjeve Fahrenheita u stupnjeve Celzija:

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

Brzo je i jednostavno, ne morate stvarati nepotrebne stavke podataka i voditi povijest o njima, a možete koristiti i fleksibilne intervale za provjere.

Rješavamo praktične probleme u Zabbixu koristeći JavaScript

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

Ali, ako je u hipotetskoj situaciji potrebno dodati primljeni podatkovni element, na primjer, s bilo kojom konstantom definiranom u makronaredbi, mora se uzeti u obzir da parametar vrijednost proširuje u niz. U operaciji dodavanja niza, dva niza se jednostavno kombiniraju u jedan.

Rješavamo praktične probleme u Zabbixu koristeći JavaScript

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

Da biste dobili rezultat matematičke operacije, potrebno je pretvoriti vrste dobivenih vrijednosti u numerički format. Za to možete koristiti funkciju parseInt(), koji proizvodi cijeli broj, funkciju parseFloat(), koji daje decimalu ili funkciju broj, koji vraća cijeli ili decimalni broj.

Zadatak 2

Dobijte vrijeme u sekundama do kraja certifikata.

Stanje: usluga izdaje datum isteka certifikata u formatu "Feb 12 12:33:56 2022 GMT".

U ECMAScriptu5 date.parse() prihvaća datum u formatu ISO 8601 (GGGG-MM-DDTHH:mm:ss.sssZ). Na njega je potrebno cast string u formatu MMM DD GGGG HH:mm:ss ZZ

problem: Vrijednost mjeseca izražena je kao tekst, a ne kao broj. Duktape ne prihvaća podatke u ovom formatu.

Primjer rješenja:

  • Prije svega, deklarira se varijabla koja uzima vrijednost (cijela skripta je deklaracija varijabli koje su navedene odvojene zarezima).

  • U prvom redu dobivamo datum u parametru vrijednost i odvojite ga razmacima pomoću metode Split. Tako dobivamo niz, gdje svaki element niza, počevši od indeksa 0, odgovara jednom elementu datuma ispred i iza razmaka. podijeliti (0) - mjesec, podijeliti (1) - broj, podijeliti (2) - niz s vremenom itd. Nakon toga, svakom elementu datuma se može pristupiti indeksom u nizu.

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

  • Svaki mjesec (kronološkim redom) odgovara indeksu svoje pozicije u nizu (od 0 do 11). Za pretvaranje tekstualne vrijednosti u numeričku vrijednost, jedan se dodaje indeksu mjeseca (jer su mjeseci numerirani počevši od 1). U ovom slučaju izraz s dodatkom jedan uzima se u zagradu jer će se inače dobiti niz, a ne broj. Na kraju radimo kriška() - izrezati niz s kraja tako da ostanu samo dva znaka (što je važno za mjesece s dvoznamenkastim brojem).

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

  • Od dobivenih vrijednosti uobičajenim zbrajanjem nizova odgovarajućim redoslijedom formiramo string u ISO formatu.

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

Podaci u rezultirajućem formatu predstavljaju broj sekundi od 1970. do neke točke u budućnosti. Gotovo je nemoguće koristiti podatke u primljenom formatu u okidačima, jer Zabbix omogućuje rad samo s makronaredbama {Datum} и {Vrijeme}, koji vraćaju datum i vrijeme u jednostavnom formatu.

  • Zatim možemo dobiti trenutni datum u JavaScriptu u formatu Unix Timestamp i oduzeti ga od rezultirajućeg datuma isteka certifikata da bismo dobili broj milisekundi od sada do isteka certifikata.

`now = Date.now();`

  • Dobivenu vrijednost podijelimo s tisuću da bismo dobili sekunde u Zabbixu.

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

U okidaču možete navesti izraz 'posljednji' nakon čega slijedi skup znamenki koji odgovara broju sekundi u razdoblju na koje želite odgovoriti, na primjer, u tjednima. Dakle, okidač će obavijestiti da certifikat ističe za tjedan dana.

NAPOMENA. Obratite pozornost na uporabu parseInt() u funkciji povratakpretvoriti razlomački broj dobiven dijeljenjem milisekundi u cijeli broj. Također možete koristiti parseFloat() i pohranjuju frakcijske podatke.

Pogledajte izvještaj

Izvor: www.habr.com

Dodajte komentar