
Tihhon Uskov, Zabbixi integreerimismeeskonna insener
Zabbix on kohandatav platvorm, mida kasutatakse igasuguste andmete jÀlgimiseks. Zabbixi varajastes versioonides olid monitorimise administreerijatel vÔimalus kÀivitada erinevaid skripte lÀbi Tegevused sihtpunkte vÔrku kontrollideks. Siiski, skriptide kÀivitamine tÔi kaasa mitmeid keerukusi, sealhulgas skriptide toetamise vajadus, nende edastamine sidepunktidesse ja proxidesse ning erinevate versioonide toetamine.
JavaScript Zabbixi jaoks
Aprillis 2019 esitleb Zabbix 4.2, milles on JavaScripti eelprotsessimise funktsioon. Paljud innustusid loobuma skriptide kirjutamisest, mis kusagilt andmeid vÔtavad, neid töötlevad ja Zabbixi formaadis edastavad. Selle asemel soovitakse teha lihtsaid kontrollimisi, mis saavad Zabbixile mittevalmis andmeid ning seejÀrel töötlevad seda andmevoogu Zabbixi ja JavaScripti vahendeid kasutades. Koos madalama taseme tuvastamise ja sÔltuvate andmeelementidega, mis ilmusid Zabbix 3.4-s, saadi piisavalt paindlik kontseptsioon saadud andmete sorteerimiseks ja haldamiseks.
Zabbix 4.4-s, loogilise jĂ€tkuna JavaScripti eelprotsessimisele, ilmus uus teavitamise meetod â Webhook, mida saab kasutada Zabbixi teavituste lihtsaks integreerimiseks kolmandate osapoolte rakendustega.
JavaScript ja Duktape
Miks valiti just JavaScript ja Duktape? Kaaluakse erinevaid keeli ja mootorite variante:
- Lua â Lua 5.1
- Lua â LuaJIT
- JavaScript â Duktape
- JavaScript â JerryScript
- Sisseehitatud Python
- Sisseehitatud Perl
Peamised valikukriteeriumid olid laialdane kasutamine, mootoritootmise lihtsus, madal ressursi kasutus ja mootorite ĂŒldine jĂ”udlus, samuti selle keele koodi turvalisus jĂ€lgimisel. Nende nĂ€itajate kombinatsioonis vĂ”itis JavaScript Duktape'i mootori.

Valikukriteeriumid ja jÔudlustestimine
Duktape'i omadused:
â Standard
â Zabbixi moodulid Duktape'ile:
- Zabbix.log() â vĂ”imaldab kirjutada otse Zabbix Serveri logisse teateid erineva detailsuse tasemega, mis vĂ”imaldab seotud vigu vĂ”rreldes nĂ€iteks Webhooki ja serveri olekuga.
- CurlHttpRequest() â vĂ”imaldab teha HTTP-pĂ€ringuid vĂ”rku, millel pĂ”hineb Webhooki kasutamine.
- atob() ja btoa() â vĂ”imaldavad kodeerida ja dekodeerida stringe Base64 formaati.
MĂRKUS. Duktape vastab ACME standarditele. Zabbixis kasutatakse 2015. aasta skripti versiooni. JĂ€rgmised muudatused on ebaolulised, mistĂ”ttu neid vĂ”ib ignoreerida..
JavaScripti maagia
Kogu JavaScripti maagia seisneb dĂŒnaamilises tĂŒĂŒpide mÀÀramises ja tĂŒĂŒpide ĂŒmbersuunamises: stringide, numbrite ja loogiliste vÀÀrtuste osas.
See tĂ€hendab, et ei ole vaja eelnevalt kuulutada, millist tĂŒĂŒpi muutuja peaks vÀÀrtust tagastama.
Matemaatiliste operatsioonide kĂ€igus muudetakse funktsioonide operaatorite tagastatud vÀÀrtused numbriteks. Erandiks sellistes operatsioonides on liitmine, kuna kui vĂ€hemalt ĂŒks liidetav on string, rakendatakse kĂ”igile liidetavatele stringi konverteerimist.
MĂRKUS. Meetodid, mis vastutavad selliste konversioonide eest, on tavaliselt rakendatud objektide vanematel prototĂŒĂŒpidel, valueOf ja toString. valueOf kutsutakse esile numbrilise konverteerimise kĂ€igus ja esineb alati meetodi ees toString. Meetod valueOf peab tagastama primitiivsed vÀÀrtused, vastasel juhul ignoreeritakse selle tulemust.
Objekti puhul kutsutakse esile meetod valueOF. Kui seda ei leita vĂ”i see ei tagasta primitiivset vÀÀrtust, kutsutakse esile meetod toString. Kui meetod toString ei leita, otsitakse valueOf objekti prototĂŒĂŒbist ja kĂ”ik kordub kuni vÀÀrtuse töötlemise lĂ”puni ja kĂ”igi vĂ€ljendi vÀÀrtuste ĂŒhtse tĂŒĂŒbi saamiseni. Kui objekti jaoks on rakendatud meetod toString, mis tagastab primitiivse vÀÀrtuse, kasutatakse just seda stringi konverteerimisel. Sel juhul ei ole selle meetodi rakendamise tulemus tingimata string.
NĂ€iteks, kui objekti âobjâ jaoks on mÀÀratud meetod toString,
`var obj = { toString() { return "200" }}` meetod toString tagastab just stringi ja kui liidame stringi numbriga, saame kokku seotud stringi:
`obj + 1 // '2001'`
`obj + 'a' // â200a'`Kuid kui kirjutada ĂŒmber toString, nii et meetod tagastab numbri, toimub objekti liitmisel matemaatiline operatsioon numbriliseks teisendamiseks ja tulemuseks on matemaatiline liitmine.
`var obj = { toString() { return 200 }}`
`obj + 1 // '2001'`Siinkohal, kui teeme liitmise stringiga, toimub stringi teisendamine ja saame seotud stringi.
`obj + 'a' // â200a'`Just siin peitub algajate JavaScripti kasutajate paljude vigade pĂ”hjus.
Meetodisse toString vÔib kirjutada funktsiooni, mis suurendab objekti praegust vÀÀrtust 1 vÔrra.

Skripti tÀitmine juhul, kui muutuja on 3 ja see samal ajal on 4.
TĂŒĂŒpide teisendusega vĂ”rreldes (==) kutsub iga kord vĂ€lja meetodi toString vÀÀrtuse suurendamise funktsioon. Vastavalt sellele suurendatakse iga jĂ€rgneva vĂ”rdluse korral vÀÀrtust. Seda saab vĂ€ltida, kasutades tĂŒĂŒpide teisendamiseta vĂ”rreldes (===).

TĂŒĂŒpide teisendamiseta vĂ”rdlemine
MĂRKUS. Ărge kasutage tĂŒĂŒpide ĂŒlekandmist ilma vajaduseta.
Kuna keerulistes skriptides, nĂ€iteks keeruka loogikaga Webhookides, on vajalik tĂŒĂŒpide vĂ”rdlemine, on soovitatav eelnevalt kontrollida muutujate tagastatud vÀÀrtusi ning kĂ€sitseda vĂ”imalikke ebakĂ”lasid ja vigu.
Webhook Media
2019. aasta lÔpus ja 2020. aasta alguses töötas Zabbixi integreerimismeeskond aktiivselt Webhookide ja 'kastist vÀlja' integreeringute arendamise kallal, mis on Zabbixi jaotises saadaval.

Link
Eelprotsessimine
- Eelprotsessi ilmumine JavaScriptis on vÔimaldanud loobuda enamikust vÀlistest skriptidest, ning hetkel on Zabbixis vÔimalik saada mistahes vÀÀrtus ja muuta see tÀiesti teiseks vÀÀrtuseks.
- Eelprotsessimine Zabbixis on rakendatud JavaScripti koodi abil, mis kompileerimise kĂ€igus byte-koodiks muudetakse funktsiooniks, mis vĂ”tab parameetrina vastu ĂŒhe vÀÀrtuse value stringina (stringis vĂ”ib olla nii number kui arv).
- Kuna vÀljundiks on funktsioon, on skripti lÔpus vajalik return.
- Kohandatud makrode kasutamine koodis on vÔimalik.
- Ressursse saab piirata mitte ainult operatsioonisĂŒsteemi tasemel, vaid ka programmiliselt. Ettevalmistusetapis eraldatakse maksimaalselt 10 megabaiti peamĂ€lu ja kĂ€itusaeg on piiratud 10 sekundiga.

MĂRKUS. 10-sekundilised ajamuudatuse vÀÀrtused on ĂŒsna suured, kuna tuhandete andmepunktide kogumine ĂŒhe sekundi jooksul piisavalt ârasketesâ ettevalmistusskeemides vĂ”ib Zabbixi toimimist aeglustada. SeetĂ”ttu ei soovitata ettevalmistust kasutada tĂ€ielike JavaScripti skriptide tĂ€itmiseks nii nimetatud âvarjatud andmepunktideâ (dummy items) kaudu, mis kĂ€ivitatakse ainult ettevalmistuse tĂ€itmiseks..
Oma koodi saab kontrollida ettevalmistustesti vÔi utiliidi kaudu. 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`
Praktilised ĂŒlesanded
Ălesanne 1
Asenda arvutatud andmepunkt ettevalmistusega.
Tingimus: saame andurilt temperatuuri Fahrenheiti kraadides, et salvestada seda Celsiuse kraadides.
Varem oleksime loonud andmeelemendi, mis koguks temperatuuri Fahrenheiti kraadides. SeejĂ€rel veel ĂŒhe andmeelemendi (arvutatud), mis valemi abil muundaks Fahrenheiti kraadid Celsiuse kraadideks.
Probleemid:
- Kohustuslik on andmeelementide kopeerimine ja kÔik vÀÀrtuste salvestamine andmebaasi.
- On vajalik kooskÔlastada intervallid «vanema» andmeelemendi jaoks, mis arvutatakse ja mida kasutatakse valemis, ja arvutatud andmeelemendi jaoks. Vastasel juhul vÔib arvutatud andmeelement sattuda toetamatusse olekusse vÔi arvutada eelneva vÀÀrtuse, mis mÔjutab jÀlgimise tulemuste usaldusvÀÀrsust.
Ăks lahendusi oli loobuda paindlikest kontrollintervallidest fikseeritud intervallide kasuks, et tagada arvutatud andmeelemendi alati arvutamine pĂ€rast andmeelemendi, mis kogub andmeid (meie puhul Fahrenheiti kraadides temperatuuri).
Kuid kui nÀiteks kasutame ƥablonit paljude seadmete kontrollimiseks ja kontroll toimub iga 30 sekundi jÀrel, siis 29 sekundit Zabbix «töötleb» ja viimasel sekundil hakkab see kontrollima ja arvutama. See toob kaasa jÀrjekorra ja mÔjutab jÔudlust. SeetÔttu on soovitatav kasutada fikseeritud intervalle ainult siis, kui see on tÔeliselt vajalik.
Selles ĂŒlesandes on optimaalne lahendus kasutada ĂŒhe rea eelprotsessimist JavaScriptis, mis konverteerib Fahrenheit kraadid Celsiuse kraadideks:
`return (value - 32) * 5 / 9;`See on kiire ja lihtne, ei pea looma ĂŒlearuseid andmeelemente ja nende ajalugu salvestama ning saab kasutada ka paindlikke intervalle kontrollideks.

`return (parseInt(value) + parseInt("{$EXAMPLE.MACRO}"));`Kuid kui hĂŒpoteetilises olukorras on vajalik saadud andmeelement summeerida nĂ€iteks mingisuguse makros mÀÀratletud konstantiga, tuleb arvesse vĂ”tta, et parameeter value muudetakse stringiks. Stringide liitmisel ĂŒhendatakse kaks stringi lihtsalt ĂŒheks.

`return (value + "{$EXAMPLE.MACRO}");`Matemaatilise tehte tulemuse saamiseks tuleb saadaolevad vÀÀrtused arvu formaati viia. Selleks saab kasutada funktsiooni parseInt(), mis tagastab tÀisarvu, funktsiooni parseFloat(), mis tagastab komakohaga arvu, vÔi funktsiooni number, mis tagastab kas tÀisarvu vÔi komakohaga arvu.
Ălesanne 2
Saada aega sekundites kuni sertifikaadi lÔppemiseni.
Tingimus: ĂŒks teenus annab sertifikaadi lĂ”ppemise kuupĂ€eva formaadis "Feb 12 12:33:56 2022 GMT".
ECMAScript5-s Date.parse() vÔtab kuupÀeva ISO 8601 formaadis (YYYY-MM-DDTHH:mm:ss.sssZ). On vajalik viia string formaati MMM DD YYYY HH:mm:ss ZZ
Probleem: kuu vÀÀrtus on vÀljendatud tekstina, mitte numbrina. Sellisel formaadil andmeid Duktape ei aktsepteeri.
Lahenduse nÀide:
Esiteks kuulutatakse vÀlja muutuja, mis vÔtab vÀÀrtuse (kogu skript koosneb muutuja mÀÀratlemisest, mis on loetletud koma abil).
Esimeses reas saame kuupĂ€eva parameetris value ja eraldame selle tĂŒhikutega meetodi split. Nii saame massiivi, kus iga massiivi element, alustades indeksist 0, vastab ĂŒhele kuupĂ€eva elemendile enne ja pĂ€rast tĂŒhikut. split(0) â kuu, split(1) â pĂ€ev, split(2) â aeg ja muud. PĂ€rast seda saab iga kuupĂ€eva elementi massiivis indeksiga kĂŒsida.
`var split = value.split(' '),`- Iga kuule (kronoloogilises jĂ€rjestuses) vastab massiivi elementide indeks (0 kuni 11). Tekstilise vÀÀrtuse numbriliseks konverteerimiseks liidetakse kuuni indeksile ĂŒks (sest kuude numbrimine algab 1-st). Samas on see vĂ€ljend, kus liidetakse ĂŒks, pandud sulgudesse, kuna muidu saame stringi, mitte arvu. LĂ”pus tĂ€idame slice() â massiivi lĂ”ike, et jĂ€tta alles ainult kaks numbrit (mis on olulised kahe numbri kuude puhul).
`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),`- Moodustame saadud vÀÀrtustest stringi ISO formaadis, liites stringe vastavas jÀrjekorras.
`ISOdate = split[3] + '-' + month_index + '-' + split[1] + 'T' + split[2],`Saadud formaadis andmed â sekundite arv 1970. aastast kuni mingi hetk tulevikus. Andmete kasutamine saadud formaadis Zabbix'i kĂ€ivitustes on praktiliselt vĂ”imatu, kuna Zabbix vĂ”imaldab töötada vaid makrodega {Date} ja {Time}, mis tagastavad kuupĂ€eva ja kellaaega kasutajale arusaadavas formaadis.
- PÀrast seda saame JavaScriptis saada praeguse kuupÀeva Unix Timestamp formaadis ja lahutada selle saadud sertifikaadi lÔppkuupÀeva vÀÀrtusest, et arvutada millisekundite arv praegusest hetkest kuni sertifikaadi lÔppemise hetkeni.
`now = Date.now();`- Jagame saadud vÀÀrtuse tuhandega, et saada sekundid Zabbixis.
`return parseInt((Date.parse(ISOdate) - now) / 1000);`Tingimustes vĂ”ib kasutada vĂ€ljendit âlast<â ja numbrite kogumit, mis vastab sekundi arvule ajavahemikus, millele tuleb reageerida, nĂ€iteks nĂ€dalates. Nii teavitab tingimus, et sertifikaadi kehtivus aegub nĂ€dala jooksul.
MĂRKUS. Pange tĂ€hele, et kasutatakse parseInt() funktsioonis return, et konverteerida murdarv, mis on saadud millisekundite jagamisest, tĂ€isarvuks. Samuti vĂ”ib kasutada parseFloat() ja sĂ€ilitada murdarve..
Allikas: habr.com
