Mēs risinām praktiskas problēmas Zabbix, izmantojot JavaScript

Mēs risinām praktiskas problēmas Zabbix, izmantojot JavaScript
Tihons Uskovs, Zabbix integrācijas komandas inženieris

Zabbix ir pielāgojama platforma, ko izmanto, lai uzraudzÄ«tu jebkāda veida datus. KopÅ” senākajām Zabbix versijām uzraudzÄ«bas administratoriem ir bijusi iespēja palaist dažādus skriptus, izmantojot Iespējas mērÄ·a tÄ«kla mezglu pārbaudēm. Tajā paŔā laikā skriptu palaiÅ”ana radÄ«ja vairākas grÅ«tÄ«bas, tostarp nepiecieÅ”amÄ«bu atbalstÄ«t skriptus, to piegādi saziņas mezgliem un starpniekserveriem, kā arÄ« dažādu versiju atbalstu.

JavaScript priekÅ” Zabbix

2019. gada aprÄ«lÄ« tika ieviests Zabbix 4.2 ar JavaScript priekÅ”apstrādi. Daudzus cilvēkus sajÅ«smināja ideja atteikties no tādu skriptu rakstÄ«Å”anas, kas kaut kur aiznes datus, sagremo tos un nodroÅ”ina Zabbix saprotamā formātā un veic vienkārÅ”as pārbaudes, kas saņems datus, kas nav gatavi Zabbix glabāŔanai un apstrādei, un pēc tam apstrādājiet Å”o datu straumi, izmantojot Zabbix un JavaScript rÄ«kus. SaistÄ«bā ar zema lÄ«meņa atklāŔanas un atkarÄ«giem vienumiem, kas parādÄ«jās Zabbix 3.4, mēs ieguvām diezgan elastÄ«gu saņemto datu kārtoÅ”anas un pārvaldÄ«bas koncepciju.

Zabbix 4.4 versijā kā loÄ£isks JavaScript priekÅ”apstrādes turpinājums ir parādÄ«jusies jauna paziņoÅ”anas metode - Webhook, ar kuras palÄ«dzÄ«bu var ērti integrēt Zabbix paziņojumus ar treÅ”o puÅ”u lietojumprogrammām.

JavaScript un Duktapes

Kāpēc tika izvēlēti JavaScript un Duktape? Tika apsvērtas dažādas valodu un dzinēju iespējas:

  • Lua ā€” Lua 5.1
  • Lua ā€” LuaJIT
  • Javascript ā€” Duktape
  • Javascript ā€” JerryScript
  • Iegultais Python
  • Iegultais Perl

Galvenie atlases kritēriji bija izplatÄ«ba, dzinēja integrÄ“Å”anas vienkārŔība produktā, zems resursu patēriņŔ un dzinēja vispārējā veiktspēja, kā arÄ« koda ievieÅ”anas droŔība Å”ajā valodā uzraudzÄ«bā. Pamatojoties uz rādÄ«tāju kombināciju, Duktape dzinējā uzvarēja JavaScript.

Mēs risinām praktiskas problēmas Zabbix, izmantojot JavaScript

Atlases kritēriji un veiktspējas pārbaude

Duktape īpaŔības:

ā€” Standarta ECMAScript E5/E5.1
ā€” Zabbix moduļi Duktape:

  • Zabbix.log() - ļauj rakstÄ«t dažādu detalizācijas lÄ«meņu ziņojumus tieÅ”i Zabbix Server žurnālā, kas ļauj korelēt kļūdas, piemēram, Web aizÄ·erē, ar servera stāvokli.
  • CurlHttpRequest() - ļauj veikt HTTP pieprasÄ«jumus tÄ«klam, uz kuriem balstās Webhook izmantoÅ”ana.
  • atob() un btoa() - ļauj kodēt un atÅ”ifrēt virknes Base64 formātā.

PIEZÄŖME. Duktape atbilst ACME standartiem. Zabbix izmanto skripta 2015. gada versiju. Turpmākās izmaiņas ir nelielas, tāpēc tās var ignorēt..

JavaScript maģija

Visa JavaScript burvÄ«ba slēpjas dinamiskā maŔīnrakstÄ«Å”anā un veidu atraÅ”anā: virkne, ciparu un BÅ«la.

Tas nozÄ«mē, ka nav nepiecieÅ”ams iepriekÅ” deklarēt, kāda veida mainÄ«gajam ir jāatgriež vērtÄ«ba.

Matemātiskajās operācijās funkciju operatoru atgrieztās vērtÄ«bas tiek pārvērstas skaitļos. Izņēmums Ŕādām darbÄ«bām ir pievienoÅ”ana, jo, ja vismaz viens no terminiem ir virkne, virknes konvertÄ“Å”ana tiek piemērota visiem terminiem.

PIEZÄŖME. Metodes, kas ir atbildÄ«gas par Ŕādām transformācijām, parasti tiek ieviestas objekta vecāku prototipos, valueOf Šø toString. valueOf izsauc ciparu konvertÄ“Å”anas laikā un vienmēr pirms metodes toString. Metode valueOf ir jāatgriež primitÄ«vas vērtÄ«bas, pretējā gadÄ«jumā tā rezultāts tiek ignorēts.

Objektam tiek izsaukta metode vērtÄ«baOF. Ja tā netiek atrasta vai neatgriež primitÄ«vu vērtÄ«bu, tiek izsaukta metode toString. Ja metode toString nav atrasts, meklē valueOf objekta prototipā, un viss tiek atkārtots, lÄ«dz vērtÄ«bas apstrāde ir pabeigta un visas izteiksmes vērtÄ«bas tiek nodotas vienam tipam. Ja objekts realizē metodi toString, kas atgriež primitÄ«vu vērtÄ«bu, tad tā tiek izmantota virknes konvertÄ“Å”anai. Tomēr Ŕīs metodes piemēroÅ”anas rezultāts ne vienmēr ir virkne.

Piemēram, ja objektam 'objekts' metode ir definēta toString,

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

Metode toString atgriež tieÅ”i virkni, un, pievienojot virkni ar skaitli, mēs iegÅ«stam salÄ«mētu virkni:

`obj + 1 // '2001'` 

`obj + 'a' // ā€˜200a'`

Bet ja pārraksti toString, lai metode atgrieztu skaitli, kad objekts tiek pievienots, tiks veikta matemātiskā darbÄ«ba ar skaitļu konvertÄ“Å”anu un iegÅ«ts matemātiskās saskaitÄ«Å”anas rezultāts.

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

`obj + 1 // '2001'`

Å ajā gadÄ«jumā, ja veicam pievienoÅ”anu ar virkni, tiek veikta virknes konvertÄ“Å”ana, un mēs iegÅ«stam pielÄ«mētu virkni.

`obj + 'a' // ā€˜200a'`

Tas ir iemesls lielam skaitam kļūdu, ko pieļauj iesācēju JavaScript lietotāji.

Metode toString jÅ«s varat uzrakstÄ«t funkciju, kas palielinās objekta paÅ”reizējo vērtÄ«bu par 1.

Mēs risinām praktiskas problēmas Zabbix, izmantojot JavaScript
Skripta izpilde, ja mainīgais ir vienāds ar 3, un tas ir arī vienāds ar 4.

SalÄ«dzinot ar cast (==), metode tiek izpildÄ«ta katru reizi toString ar vērtÄ«bas palielināŔanas funkciju. AttiecÄ«gi ar katru nākamo salÄ«dzinājumu vērtÄ«ba palielinās. No tā var izvairÄ«ties, izmantojot ne-cast salÄ«dzinājumu (===).

Mēs risinām praktiskas problēmas Zabbix, izmantojot JavaScript
Salīdzinājums bez tipa lieŔanas

PIEZÄŖME. Neizmantojiet cast salÄ«dzinājumu bez vajadzÄ«bas.

Sarežģītiem skriptiem, piemēram, Webhooks ar sarežģītu loÄ£iku, kuriem nepiecieÅ”ams salÄ«dzinājums ar tipa apraidi, ieteicams iepriekÅ” uzrakstÄ«t to vērtÄ«bu pārbaudes, kas atgriež mainÄ«gos un apstrādā neatbilstÄ«bas un kļūdas.

Webhook Media

2019. gada beigās un 2020. gada sākumā Zabbix integrācijas komanda ir aktÄ«vi izstrādājusi Webhooks un gatavās integrācijas, kas nāk ar Zabbix izplatÄ«Å”anu.

Mēs risinām praktiskas problēmas Zabbix, izmantojot JavaScript
Saite uz dokumentācija

IepriekŔēja apstrāde

  • JavaScript priekÅ”apstrādes parādÄ«Å”anās ļāva atteikties no vairuma ārējo skriptu, un paÅ”laik Zabbix jÅ«s varat iegÅ«t jebkuru vērtÄ«bu un pārvērst to par pilnÄ«gi citu vērtÄ«bu.
  • IepriekŔēja apstrāde programmā Zabbix tiek Ä«stenota ar JavaScript kodu, kas, kompilējot baitkodā, tiek pārveidots par funkciju, kas kā parametru izmanto vienu vērtÄ«bu vērtÄ«ba kā virkne (virknē var bÅ«t gan cipars, gan skaitlis).
  • Tā kā izvade ir funkcija, skripta beigās ir nepiecieÅ”ams atgrieÅ”anās.
  • Kodā ir iespējams izmantot pielāgotus makro.
  • Resursus var ierobežot ne tikai operētājsistēmas lÄ«menÄ«, bet arÄ« programmatiski. PriekÅ”apstrādes solim ir pieŔķirts ne vairāk kā 10 megabaiti RAM un 10 sekunžu darbÄ«bas laika ierobežojums.

Mēs risinām praktiskas problēmas Zabbix, izmantojot JavaScript

PIEZÄŖME. 10 sekunžu taimauta vērtÄ«ba ir diezgan liela, jo nosacÄ«tu tÅ«kstoÅ”iem datu vienumu savākÅ”ana 1 sekundē saskaņā ar diezgan ā€œsmaguā€ priekÅ”apstrādes scenāriju var palēnināt Zabbix. Tāpēc nav ieteicams izmantot priekÅ”apstrādi, lai izpildÄ«tu pilnvērtÄ«gus JavaScript skriptus, izmantojot tā sauktos ēnu datu elementus (fiktÄ«vos vienumus), kas tiek palaisti tikai priekÅ”apstrādes veikÅ”anai..

Varat pārbaudīt savu kodu, veicot priekŔapstrādes testu vai izmantojot utilītu 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`

Praktiski uzdevumi

Uzdevums 1

Aizstāt aprēķināto vienumu ar priekÅ”apstrādi.

Stāvoklis: Iegūstiet no sensora temperatūru Fārenheitā, lai saglabātu to Celsija grādos.

IepriekÅ” mēs izveidojām vienumu, kas apkopo temperatÅ«ru Fārenheita grādos. Pēc tam vēl viens datu vienums (aprēķināts), kas, izmantojot formulu, pārvērstu pēc Fārenheita uz Celsija.

Problēmas:

  • Ir nepiecieÅ”ams dublēt datu elementus un saglabāt visas vērtÄ«bas datu bāzē.
  • Jāvienojas par intervāliem formulā aprēķinātajam un izmantotajam datu vienumam "vecāks" un aprēķinātajam datu vienumam. Pretējā gadÄ«jumā aprēķinātais vienums var nonākt neatbalstÄ«tā stāvoklÄ« vai aprēķināt iepriekŔējo vērtÄ«bu, kas ietekmēs uzraudzÄ«bas rezultātu ticamÄ«bu.

Viens no risinājumiem bija atteikties no elastÄ«giem pārbaudes intervāliem par labu fiksētiem intervāliem, lai nodroÅ”inātu, ka aprēķinātais vienums tiek novērtēts pēc vienuma, kas saņem datus (mÅ«su gadÄ«jumā temperatÅ«ra Fārenheita grādos).

Bet, ja, piemēram, mēs izmantojam veidni, lai pārbaudÄ«tu lielu skaitu ierīču, un pārbaude tiek veikta reizi 30 sekundēs, Zabbix "uzlauž" 29 sekundes, un pēdējā sekundē sāk pārbaudÄ«t un aprēķināt. Tas rada rindu un ietekmē veiktspēju. Tāpēc ir ieteicams izmantot fiksētus intervālus tikai tad, ja tas patieŔām ir nepiecieÅ”ams.

Å Ä«s problēmas optimālais risinājums ir vienas rindas JavaScript priekÅ”apstrāde, kas pārvērÅ” Fārenheita grādus pēc Celsija grādiem:

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

Tas ir ātri un vienkārÅ”i, jums nav jāveido nevajadzÄ«gi datu vienumi un jāglabā to vēsture, kā arÄ« varat izmantot elastÄ«gus pārbaužu intervālus.

Mēs risinām praktiskas problēmas Zabbix, izmantojot JavaScript

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

Bet, ja hipotētiskā situācijā ir nepiecieÅ”ams pievienot saņemto datu elementu, piemēram, ar jebkuru makro definētu konstanti, jāņem vērā, ka parametrs vērtÄ«ba izpleÅ”as virknē. Virknes pievienoÅ”anas operācijā divas virknes tiek vienkārÅ”i apvienotas vienā.

Mēs risinām praktiskas problēmas Zabbix, izmantojot JavaScript

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

Lai iegÅ«tu matemātiskas darbÄ«bas rezultātu, iegÅ«to vērtÄ«bu veidi ir jāpārvērÅ” ciparu formātā. Å im nolÅ«kam varat izmantot funkciju parseInt(), kas rada veselu skaitli, funkciju parseFloat(), kas veido decimāldaļu vai funkciju skaits, kas atgriež veselu skaitli vai decimāldaļu.

2. uzdevums

Iegūstiet laiku sekundēs līdz sertifikāta beigām.

Stāvoklis: pakalpojums izsniedz sertifikāta derīguma termiņu formātā "Feb 12 12:33:56 2022 GMT".

Programmā ECMAScript5 date.parse() pieņem datumu ISO 8601 formātā (GGGG-MM-DDTHH:mm:ss.sssZ). Tam ir jāieraida virkne formātā MMM DD GGGG HH:mm:ss ZZ

problēma: mēneÅ”a vērtÄ«ba tiek izteikta kā teksts, nevis kā skaitlis. Datus Ŕādā formātā Duktape nepieņem.

Risinājuma piemērs:

  • Pirmkārt, tiek deklarēts mainÄ«gais, kas iegÅ«st vērtÄ«bu (viss skripts ir mainÄ«go lielumu deklarācija, kas ir uzskaitÄ«ti, atdalot tos ar komatiem).

  • Pirmajā rindā mēs iegÅ«stam datumu parametrā vērtÄ«ba un atdaliet to ar atstarpēm, izmantojot metodi sadalÄ«t. Tādējādi mēs iegÅ«stam masÄ«vu, kurā katrs masÄ«va elements, sākot ar indeksu 0, atbilst vienam datuma elementam pirms un pēc atstarpes. sadalÄ«t (0) - mēnesis, sadalÄ«t (1) - numurs, sadalÄ«t (2) - virkne ar laiku utt. Pēc tam katram datuma elementam var piekļūt ar indeksu masÄ«vā.

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

  • Katrs mēnesis (hronoloÄ£iskā secÄ«bā) atbilst tā pozÄ«cijas indeksam masÄ«vā (no 0 lÄ«dz 11). Lai teksta vērtÄ«bu pārvērstu par skaitlisku vērtÄ«bu, mēneÅ”a indeksam tiek pievienota viena vērtÄ«ba (jo mēneÅ”i tiek numurēti, sākot ar 1). Å ajā gadÄ«jumā izteiksme ar pievienojumu viens tiek ņemta iekavās, jo pretējā gadÄ«jumā tiks iegÅ«ta virkne, nevis skaitlis. Beigās darām Ŕķēle () - izgrieziet masÄ«vu no beigām, lai atstātu tikai divas rakstzÄ«mes (kas ir svarÄ«gi mēneÅ”iem ar divciparu skaitli).

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

  • No iegÅ«tajām vērtÄ«bām mēs veidojam virkni ISO formātā, parasti pievienojot virknes atbilstoŔā secÄ«bā.

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

Dati iegÅ«tajā formātā ir sekunžu skaits no 1970. gada lÄ«dz noteiktam brÄ«dim nākotnē. Saņemtā formāta datus ir gandrÄ«z neiespējami izmantot trigeros, jo Zabbix ļauj darboties tikai ar makro {Datums} Šø {Laiks}, kas atgriež datumu un laiku lietotājam draudzÄ«gā formātā.

  • Pēc tam mēs varam iegÅ«t paÅ”reizējo datumu JavaScript formātā Unix Timestamp un atņemt to no iegÅ«tā sertifikāta derÄ«guma termiņa, lai iegÅ«tu milisekundes no Ŕī brīža lÄ«dz sertifikāta derÄ«guma termiņa beigām.

`now = Date.now();`

  • Mēs dalām saņemto vērtÄ«bu ar tÅ«kstoti, lai iegÅ«tu sekundes Zabbix.

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

Aktivizētājā varat norādÄ«t izteiksmi "Pēdējais', kam seko ciparu kopa, kas atbilst sekunžu skaitam periodā, uz kuru vēlaties atbildēt, piemēram, nedēļās. Tādējādi aktivizētājs paziņos, ka sertifikāta derÄ«guma termiņŔ beigsies pēc nedēļas.

PIEZÄŖME. Pievērsiet uzmanÄ«bu lietoÅ”anai parseInt() funkcijā atgrieÅ”anāslai pārvērstu daļskaitli, kas iegÅ«ts, dalot milisekundes, par veselu skaitli. Varat arÄ« izmantot parseFloat() un uzglabāt daļējus datus.

Skatīties reportāžu

Avots: www.habr.com

Pievieno komentāru