
Tikhon Uscov, inxhinier i ekipit të integrimit Zabbix
Zabbix është një platformë e personalizueshme që përdoret për të monitoruar çdo lloj të dhëne. Që nga versionet e para të Zabbix, administratorët e monitorimit kanë pasur mundësinë të ekzekutojnë skenare të ndryshme përmes Veprimet për kontrolle në nyjet e targetuara të rrjetit. Megjithatë, ekzekutimi i skenarëve ka sjellë një sërë sfidash, përfshirë nevojën për të mbështetur skenarët, për t'i transportuar ato në nyjet e lidhjes dhe proxy, si dhe për të mbështetur versione të ndryshme.
JavaScript për Zabbix
Në prill 2019, u prezantua Zabbix 4.2 me funksionin e përpunimit në JavaScript. Shumë njerëz filluan të nxiten nga ideja për të abandonuar shkruajtjen e skenarëve që marrin të dhëna nga ndokund, i përpunojnë ato dhe i ofrojnë në një format të kuptueshëm për Zabbix, dhe për të kryer kontrolle të thjeshta që do të merrnin të dhëna jo të gatshme për ruajtje dhe përpunim nga Zabbix, duke e përpunuar më pas këtë rrjedhë të dhënash duke përdorur mjetet e Zabbix dhe JavaScript. Në kombinim me zbulimin e niveli të ulët dhe elementët e dhënave të varur, që u shfaqën në Zabbix 3.4, rezultoi një koncept mjaft fleksibël për renditjen dhe menaxhimin e të dhënave të marra.
Në Zabbix 4.4, si një vazhdim logjik i përpunimit para, u shfaq një mënyrë e re për njoftim - Webhook, i cili mund të përdoret për integrimin e lehtë të njoftimeve Zabbix me aplikacione të palëve të treta.
JavaScript dhe Duktape
Pse u zgjodhën pikërisht JavaScript dhe Duktape? U shqyrtuan variante të ndryshme të gjuhëve dhe motorëve:
- Lua â Lua 5.1
- Lua â LuaJIT
- JavaScript â Duktape
- JavaScript â JerryScript
- Python i Integruar
- Perl i Integruar
Kriteret kryesore të zgjedhjes ishin shpërndarja, thjeshtësia e integrimit të motorit në produkt, konsumi i ulët i burimeve dhe performanca e përgjithshme e motorit, si dhe siguria e implementimit të kodit në këtë gjuhë në monitorim. Përmbushja e këtyre kritereve e çoi JavaScript me motorin Duktape në krye.

Kriteret e zgjedhjes dhe testimi i performancës
Veçoritë e Duktape:
â Standarti
â Modules Zabbix pĂ«r Duktape:
- Zabbix.log() â lejon tĂ« shkruani drejtpĂ«rdrejt nĂ« logun e Zabbix Server mesazhe me nivel tĂ« ndryshĂ«m detajesh, duke siguruar mundĂ«sinĂ« e pĂ«rputhjes sĂ« gabimeve, pĂ«r shembull, nĂ« Webhook me gjendjen e serverit.
- CurlHttpRequest() â lejon tĂ« bĂ«ni kĂ«rkesa HTTP nĂ« rrjet, mbi tĂ« cilin bazohet pĂ«rdorimi i Webhook.
- atob() dhe btoa() â lejon kodimin dhe dekodimin e vargjeve nĂ« formatin Base64.
VĂREJTJE. Duktape pĂ«rputhet me standardet ACME. NĂ« Zabbix pĂ«rdoret versioni i skriptit nga viti 2015. Ndryshimet pasuese janĂ« tĂ« papĂ«rfillshme, prandaj mund tĂ« injorohen..
Magjia e JavaScript
E gjithë magia e JavaScript-it qëndron në tipizimin dinamik dhe konvertimin e tipave: string, numra dhe logjik.
Kjo do të thotë se nuk është e nevojshme të shpallet paraprakisht se çfarë tipi do të kthejë një variabël.
Në operacionet matematike, vlerat që kthehen nga operatorët-funksione konvertohen në numra. Përjashtim nga këto operacione është mbledhja, pasi, nëse çdo numër i shtuar është një string, mbi të gjitha numrat e shtuar aplikohet konvertimi në string.
VĂREJTJE. Metodat qĂ« janĂ« tĂ« pĂ«rgjegjshme pĂ«r kĂ«to konvertime zakonisht janĂ« tĂ« implementuara nĂ« prototipat prindĂ«r tĂ« objekteve, valueOf dhe toString. valueOf thirret gjatĂ« konvertimit numĂ«ror dhe gjithmonĂ« para metodĂ«s toString. Metoda valueOf duhet tĂ« kthejĂ« vlera primitive, pĂ«rndryshe rezultati i saj injorohet.
Për një objekt thirret metoda valueOF. Nëse ajo nuk gjendet ose nuk kthen një vlerë primitive, thirret metoda toString. Nëse metoda toString nuk gjendet, kërkimi vazhdon valueOf n prototipin e objektit, dhe gjithçka përsëritet deri në përfundimin e përpunimit të vlerës dhe bashkimin e të gjitha vlerave në një lloj të vetëm. Nëse për objektin është realizuar metoda toString, e cila kthen një vlerë primitive, atëherë ajo përdoret për konvertimin në varg. Rezultati i përdorimit të kësaj metode nuk është domosdoshmërisht një varg.
Për shembull, nëse për objektin 'obj' përkufizohet metoda toString,
`var obj = { toString() { return "200" }}` metode toString kthen pikërisht një varg, dhe kur bastohet vargu me një numër, ne marrim një varg të bashkuar:
`obj + 1 // '2001'`
`obj + 'a' // â200a'`Por nĂ«se e ri-shkruajmĂ« toString, nĂ« mĂ«nyrĂ« qĂ« metoda tĂ« kthejĂ« numrin, gjatĂ« bastosjes sĂ« objektit do tĂ« ekzekutohet njĂ« operacion matematikor me konvertim numra dhe rezultati do tĂ« jetĂ« shumĂ«zimi matematikor.
`var obj = { toString() { return 200 }}`
`obj + 1 // '2001'`Në këtë rast, nëse ne kryejmë bastosje me një varg, kryhet një konvertim në varg, dhe ne marrim një varg të bashkuar.
`obj + 'a' // â200a'`Kjo Ă«shtĂ« arsyeja pĂ«r numrin e madh tĂ« gabimeve nga pĂ«rdoruesit fillestarĂ« tĂ« JavaScript.
Në metodën toString mund të shkruhet një funksion që do të rrisë vlerën aktuale të objektit me 1.

Ekzekutimi i skriptit kur variabla është 3, dhe po ashtu është 4.
Kur krahasohet me konvertim tipash (==), metoda ekzekutohet çdo herë. toString me funksionin e rritjes së vlerës. Prandaj, në çdo krahasim të mëtejshëm, vlera rritet. Kjo mund të shmanget duke përdorur krahasimin pa konvertim tipash (===).

Krahasimi pa konvertim tipash
VĂREJTJE. Mos pĂ«rdorni krahasimin me konvertim tipash pa nevojĂ«.
Për skriptet e ndërlikuara, siç është Webhook me logjikë të ndërlikuar, ku nevojitet krahasimi me konvertim tipash, rekomandohet të shkruani paraprakisht kontrollet për vlerat që kthehen nga variablat dhe të trajtoni moskorespondencat dhe gabimet.
Webhook Media
Në fund të vitit 2019 dhe në fillim të vitit 2020, ekipi i integrimit të Zabbix ishte duke u angazhuar në zhvillimin aktiv të Webhooks dhe integrimeve "out-of-the-box" që ofrohen në distribuimin e Zabbix.

Lidhja me
Parapërpunimi
- Shfaqja e përpunimit paraprak në JavaScript lejoi heqjen e shumicës së skripteve të jashtme, dhe tani në Zabbix mund të merrni çdo vlerë dhe ta transformoni atë në një vlerë krejtësisht tjetër.
- Përpunimi paraprak në Zabbix realizohet me kodin JavaScript, i cili gjatë kompilimit në bytecode shndërrohet në një funksion që merr një vlerë të vetme si parametër. vlera në formën e një stringu (në string mund të ketë numra dhe shifra).
- Duke qenë se në fund merr fund një funksion, në përfundim të skriptit është e domosdoshme. kthehu.
- ĂshtĂ« e mundur tĂ« pĂ«rdoren makro tĂ« personalizuara nĂ« kod.
- Burimet mund të kufizohen jo vetëm në nivelin e sistemit operativ, por gjithashtu programatikisht. Për hapin paraprak, ndahen maksimum 10 megabajt memorie RAM dhe një kufizim i kohës së ekzekutimit prej 10 sekondash.

VĂREJTJE. Vlerat e kohĂ«s sĂ« pritjes prej 10 sekondash janĂ« mjaft tĂ« mĂ«dha, sepse mbledhja e mijĂ«ra elementeve tĂ« dhĂ«nash nĂ« 1 sekondĂ« nĂ« njĂ« skenar mjaft 'tĂ« rĂ«ndĂ«' tĂ« pĂ«rpunimit paraprak mund ta ngadalĂ«sojĂ« funksionimin e Zabbix. Prandaj, nuk rekomandohet pĂ«rdorimi i pĂ«rpunimit paraprak pĂ«r ekzekutimin e skripteve tĂ« plota nĂ« JavaScript pĂ«rmes elementeve tĂ« dhĂ«nash tĂ« ashtuquajtur 'dummy', tĂ« cilat nisin vetĂ«m pĂ«r tĂ« realizuar pĂ«rpunimin paraprak..
Mund të kontrolloni kodin tuaj përmes një testi të përpunimit paraprak ose me ndihmën e utilitarit 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`
Detyrat praktike
Detyra 1
Zëvendësoni elementin e dhënash të llogaritur me përpunim paraprak.
Kushti: marrim me sensor temperaturën në gradë Fahrenheit për ta ruajtur në gradë Celsius.
MĂ« parĂ« do tĂ« kishim krijuar njĂ« element tĂ« dhĂ«nash, i cili mbledh temperaturĂ«n nĂ« gradĂ« Fahrenheit. Pastaj â njĂ« tjetĂ«r element tĂ« dhĂ«nash (i llogaritur), qĂ« sipas formulĂ«s do ta shndĂ«rronte gradĂ«n Fahrenheit nĂ« gradĂ« Celsius.
Problemet:
- ĂshtĂ« e nevojshme tĂ« dyfishohen elementet e dhĂ«nash dhe tĂ« ruhet tĂ« gjitha vlerat nĂ« bazĂ« tĂ« tĂ« dhĂ«nave.
- Duhet të konfirmohen intervalet për elementin e të dhënave "prind" që llogaritet dhe përdoret në formulë, dhe për elementin e të dhënave të llogaritur. Të kundërtën, elementi i të dhënave të llogaritur mund të kalojë në një gjendje të papërshtatshme ose të llogarisë vlerën e mëparshme, gjë që do të ndikojë në besueshmërinë e rezultateve të monitorimit.
NjĂ« nga zgjidhjet ishte heqja dorĂ« nga intervalet fleksibelĂ« tĂ« kontrollit nĂ« favor tĂ« intervaleve fikse, pĂ«r tĂ« garantuar llogaritjen e elementit tĂ« tĂ« dhĂ«nave tĂ« llogaritur pas elementit tĂ« tĂ« dhĂ«nave qĂ« merr tĂ« dhĂ«nat (nĂ« rastin tonĂ« â temperatura nĂ« gradĂ«t Fahrenheit).
Por nëse, për shembull, shablloni që përdorim për të kontrolluar një numër të madh pajisjesh, dhe kontrolli kryhet çdo 30 sekonda, 29 sekonda Zabbix "ka punuar" në mënyrë të papërgjegjshme, dhe në sekondën e fundit fillon kontrollimet dhe llogaritjet. Kjo çon në krijimin e një rrethi dhe ndikon në performancën. Prandaj rekomandohet të përdoren intervale fikse, vetëm nëse është vërtet e nevojshme.
Në këtë detyrë, zgjidhja optimale është përpunimi i një vargu në JavaScript, i cili konverton Fahrenheit në Celsius:
`return (value - 32) * 5 / 9;`Kjo është e shpejtë dhe e thjeshtë, nuk është e nevojshme të krijohen elemente të panevojshme të të dhënave dhe të ruhet historia për to, si dhe mund të përdoret për verifikime me intervale fleksibël.

`return (parseInt(value) + parseInt("{$EXAMPLE.MACRO}"));`Por, nëse në një situatë hipotetike është e nevojshme të shtohet elementi i fituar i të dhënave me një konstante të caktuar në makro, duhet marrë parasysh se parametri vlera shkruhet si një varg. Gjatë operacionit të shtimit të vargjeve, dy vargje thjesht bashkohen në një.

`return (value + "{$EXAMPLE.MACRO}");`Për të marrë rezultatin e veprimit matematikor, është e nevojshme të konvertohen tipet e vlerave të marra në format numëror. Për këtë, mund të përdoret funksioni parseInt(), i cili kthen në një numër të plotë, funksioni parseFloat(), i cili kthen në një numër të dekretuar, ose funksioni numri, i cili kthen në një numër të plotë ose të dekretuar.
Detyra 2
Merrni kohën në sekonda deri në skadimin e certifikatës.
Kushti: një shërbim jep datën e skadimit të certifikatës në formatin "Feb 12 12:33:56 2022 GMT".
NĂ« ECMAScript5 Date.parse() merr datĂ«n nĂ« formatin ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ). ĂshtĂ« e nevojshme tĂ« konvertohet nĂ« kĂ«tĂ« format njĂ« string nĂ« formatin MMM DD YYYY HH:mm:ss ZZ
Problemi: vlera e muajit shprehet me tekst, jo me numra. Të dhënat në këtë format nuk pranohen nga Duktape.
Shembulli i zgjidhjes:
Në radhë të parë shpallet një variabël, e cila merr një vlerë (e gjithë skripti është shpallja e variablave, të cilat renditen me një presje).
NĂ« rreshtin e parĂ« marrim datĂ«n si parametrin vlera dhe e ndajmĂ« atĂ« me hapĂ«sira pĂ«rmes metodĂ«s ndarje. KĂ«shtu, ne marrim njĂ« varg, ku çdo element i vargut, duke filluar nga indeksi 0, i pĂ«rgjigjet njĂ« elementi tĂ« datĂ«s pĂ«rpara dhe pas hapĂ«sirĂ«s. split(0) â muaji, split(1) â numri, split(2) â stringu me kohĂ«n etj. Pas kĂ«saj, çdo element tĂ« datĂ«s mund tĂ« aksesohĂ«t sipas indeksit nĂ« varg.
`var split = value.split(' '),`- Ădo muaji (nĂ« rend kronologjik) i korrespondon njĂ« indeks pozicioni nĂ« varg (nga 0 deri nĂ« 11). PĂ«r tĂ« konvertuar vlerĂ«n tekstuale nĂ« njĂ« numĂ«r, indeksi i muajit shtohet me njĂ« (sepse numĂ«rimi i muajve fillon nga 1). NĂ« kĂ«tĂ« rast, shprehja me shtimin e njĂ« Ă«shtĂ« marrĂ« nĂ« kaqĂ«, sepse ndryshe do tĂ« merrej njĂ« varg, jo njĂ« numĂ«r. NĂ« fund, ne kryejmĂ« slice() â njĂ« prerje e vargut nga fundi, pĂ«r tĂ« lĂ«nĂ« vetĂ«m dy shenja (çka Ă«shtĂ« e rĂ«ndĂ«sishme pĂ«r muajt me numĂ«r dyshifror).
`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),`- Formojmë nga vlerat e marra një varg në format ISO duke përdorur shumzimin e vargjeve në rendin përkatës.
`ISOdate = split[3] + '-' + month_index + '-' + split[1] + 'T' + split[2],`Të dhënat në formatin e marrë janë numri i sekondave nga viti 1970 deri në ndonjë moment në të ardhmen. Përdorimi i të dhënave në formatin e marrë në trigger është praktikisht i pamundur, sepse Zabbix lejon të operosh vetëm me makro {Date} dhe {Time}, që kthejnë datën dhe kohën në një format të kuptueshëm për përdoruesin.
- Pas këtyre, ne mund t'i marrim të dhënat aktuale në JavaScript në formatin Unix Timestamp dhe ta shmangim atë nga data e përfundimit të marrë të certifikatës, për të marrë numrin e milisekondave nga momenti aktual deri në skadimin e certifikatës.
`now = Date.now();`- E ndajmë vlerën e marrë me një mijë, për të marrë sekondat në Zabbix.
`return parseInt((Date.parse(ISOdate) - now) / 1000);`Në trigger mund të specifikohet shprehja 'last<' dhe një grup numrash që korrespondon me numrin e sekondave në periudhën për të cilën duhet të reagojë, p.sh., në javë. Kështu, trigger do të njoftojë se data e skadimit të certifikatës përfundon pas një jave.
VĂREJTJE. Kujdesi me pĂ«rdorimin e parseInt() nĂ« funksionin kthehu, pĂ«r tĂ« konvertuar numrin pishtar e trajtuar, tĂ« marrĂ« si rezultat i ndarjes sĂ« milisekondave, nĂ« njĂ« numĂ«r tĂ« plotĂ«. Gjithashtu, mund tĂ« pĂ«rdorim parseFloat() dhe tĂ« ruajmĂ« tĂ« dhĂ«nat pishtare..
Burimi: habr.com
