Gyakorlati problémákat oldunk meg a Zabbix-ban JavaScript segítségével

Gyakorlati problémákat oldunk meg a Zabbix-ban JavaScript segítségével
Tikhon Uskov, Zabbix integrációs csapat mérnöke

A Zabbix egy testreszabható platform, amely bármilyen adat figyelésére szolgál. A Zabbix legkorábbi verziói óta a megfigyelő rendszergazdák különféle szkripteket futtathatnak ezen keresztül Hozzászólások a célhálózati csomópontok ellenőrzéséhez. Ugyanakkor a szkriptek elindítása számos nehézséghez vezetett, többek között a szkriptek támogatásának szükségessége, kommunikációs csomópontokhoz és proxykhoz való eljuttatása, valamint a különböző verziók támogatása.

JavaScript a Zabbix számára

2019 áprilisában bevezették a Zabbix 4.2-t JavaScript-előfeldolgozással. Sokan felbuzdultak a gondolattal, hogy felhagynak olyan szkriptek írásával, amelyek adatokat visznek valahova, megemésztik és olyan formátumban szolgáltatják, amit a Zabbix ért, és egyszerű ellenőrzéseket hajtanak végre, amelyek olyan adatokat kapnak, amelyek nem állnak készen a Zabbix általi tárolásra és feldolgozásra, és majd feldolgozza ezt az adatfolyamot Zabbix és JavaScript eszközökkel. A Zabbix 3.4-ben megjelent alacsony szintű felderítési és függő tételekkel együtt egy meglehetősen rugalmas koncepciót kaptunk a kapott adatok rendezésére és kezelésére.

A Zabbix 4.4-ben a JavaScript-ben történő előfeldolgozás logikus folytatásaként megjelent egy új értesítési módszer - a Webhook, amellyel egyszerűen integrálhatók a Zabbix értesítései harmadik féltől származó alkalmazásokkal.

JavaScript és Duktapes

Miért választották a JavaScriptet és a Duktape-et? A nyelvek és a motorok különféle lehetőségeit fontolgatták:

  • Lua – Lua 5.1
  • Lua - LuaJIT
  • Javascript – Duktape
  • Javascript - JerryScript
  • Beágyazott Python
  • Beágyazott Perl

A fő kiválasztási kritériumok az elterjedtség, a motor termékbe történő integrálásának egyszerűsége, az alacsony erőforrás-fogyasztás és a motor általános teljesítménye, valamint a kód ezen a nyelven történő bevezetésének biztonsága volt a felügyeletben. A mutatók kombinációja alapján a JavaScript nyert a Duktape motoron.

Gyakorlati problémákat oldunk meg a Zabbix-ban JavaScript segítségével

Kiválasztási kritériumok és teljesítményteszt

A Duktape jellemzői:

- Alapértelmezett ECMAScript E5/E5.1
— Zabbix modulok Duktape-hez:

  • Zabbix.log() - lehetővé teszi, hogy különböző részletezettségű üzeneteket írjon közvetlenül a Zabbix Server naplójába, ami lehetővé teszi például a Webhook hibáinak a szerver állapotával való összefüggését.
  • CurlHttpRequest() - lehetővé teszi, hogy HTTP kéréseket küldjön a hálózatnak, amelyen a Webhook használata alapul.
  • atob() és btoa() - lehetővé teszi karakterláncok kódolását és dekódolását Base64 formátumban.

Megjegyzés. A Duktape megfelel az ACME szabványoknak. A Zabbix a forgatókönyv 2015-ös verzióját használja. A későbbi változtatások kisebbek, így figyelmen kívül hagyhatók..

JavaScript varázslat

A JavaScript minden varázsa a dinamikus gépelésben és típus-öntésben rejlik: karakterlánc, numerikus és logikai.

Ez azt jelenti, hogy nem szükséges előre deklarálni, hogy a változó milyen típusú értéket ad vissza.

A matematikai műveleteknél a függvényoperátorok által visszaadott értékek számokká alakulnak. Az ilyen műveletek alól kivételt képez az összeadás, mivel ha legalább az egyik kifejezés egy karakterlánc, a karakterlánc-konverzió minden kifejezésre vonatkozik.

Megjegyzés. Az ilyen átalakításokért felelős metódusokat általában az objektum szülő prototípusaiban implementálják, értéke и Sztring. értéke a numerikus átalakítás során és mindig a metódus előtt hívják meg Sztring. Módszer értéke primitív értékeket kell visszaadnia, különben az eredményt figyelmen kívül hagyja.

Egy metódus meghívásra kerül egy objektumon értéke. Ha nem található, vagy nem ad vissza primitív értéket, a metódus meghívásra kerül Sztring. Ha a módszer Sztring nem található, keres értéke az objektum prototípusában, és mindent addig ismételnek, amíg az érték feldolgozása be nem fejeződik, és a kifejezésben szereplő összes érték ugyanabba a típusba kerül.. Ha az objektum egy metódust valósít meg Sztring, amely primitív értéket ad vissza, akkor ez az, ami a karakterlánc-konverzióhoz használatos. Ennek a módszernek az eredménye azonban nem feltétlenül karakterlánc.

Például ha az objektumhoz 'obj' metódus van meghatározva Sztring,

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

módszer Sztring pontosan egy karakterláncot ad vissza, és ha számot adunk hozzá, egy ragasztott karakterláncot kapunk:

`obj + 1 // '2001'` 

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

De ha átírod Sztring, így a metódus egy számot ad vissza, az objektum hozzáadásakor egy numerikus konverziós matematikai műveletet hajtunk végre, és megkapjuk a matematikai összeadás eredményét.

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

`obj + 1 // '2001'`

Ebben az esetben, ha egy karakterlánccal végezzük az összeadást, akkor string konverzió történik, és egy ragasztott karakterláncot kapunk.

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

Ez az oka annak, hogy a kezdő JavaScript-felhasználók sok hibát követnek el.

A módszer Sztring írhat egy függvényt, amely 1-gyel növeli az objektum aktuális értékét.

Gyakorlati problémákat oldunk meg a Zabbix-ban JavaScript segítségével
A szkript végrehajtása, feltéve, hogy a változó egyenlő 3-mal, és egyenlő 4-gyel.

Egy öntéssel (==) összehasonlítva a metódus minden alkalommal végrehajtódik Sztring értéknövelő funkcióval. Ennek megfelelően minden további összehasonlítással az érték növekszik. Ez elkerülhető nem öntött összehasonlítással (===).

Gyakorlati problémákat oldunk meg a Zabbix-ban JavaScript segítségével
Összehasonlítás típusöntvény nélkül

Megjegyzés. Ne használja feleslegesen a Cast-összehasonlítást.

Az olyan összetett szkripteknél, mint például a bonyolult logikával rendelkező Webhookok, amelyek összehasonlítást igényelnek a típusöntéssel, ajánlott előzetesen ellenőrizni azokat az értékeket, amelyek változókat adnak vissza, és kezelik az inkonzisztenciákat és hibákat.

Webhook Media

2019 végén és 2020 elején a Zabbix integrációs csapata aktívan fejleszti a Zabbix disztribúcióval együtt járó Webhook-okat és az azonnali integrációkat.

Gyakorlati problémákat oldunk meg a Zabbix-ban JavaScript segítségével
Link a dokumentáció

Előfeldolgozás

  • A JavaScript előfeldolgozásának megjelenése lehetővé tette a legtöbb külső szkript elhagyását, és jelenleg a Zabbixben bármilyen értéket megkaphat, és teljesen más értékre konvertálhatja.
  • A Zabbixban az előfeldolgozást JavaScript kód valósítja meg, amely bájtkódba fordítva olyan függvényré alakul, amely egyetlen értéket vesz fel paraméterként érték karakterláncként (egy karakterlánc tartalmazhat számjegyet és számot is).
  • Mivel a kimenet egy függvény, a szkript végén kötelező visszatérés.
  • Lehetőség van egyéni makrók használatára a kódban.
  • Az erőforrások nem csak operációs rendszer szintjén korlátozhatók, hanem programozottan is. Az előfeldolgozási lépéshez maximum 10 megabájt RAM és 10 másodperces futási időkorlát tartozik.

Gyakorlati problémákat oldunk meg a Zabbix-ban JavaScript segítségével

Megjegyzés. A 10 másodperces időtúllépési érték elég sok, mert egy meglehetősen „nehéz” előfeldolgozási forgatókönyv szerint feltételes több ezer adatelem gyűjtése 1 másodperc alatt lelassíthatja a Zabbixot. Ezért nem javasolt az előfeldolgozás használata teljes értékű JavaScript szkriptek végrehajtásához az úgynevezett árnyék adatelemeken (dummy elemeken) keresztül, amelyek csak előfeldolgozás végrehajtására futnak..

A kódot az előfeldolgozási teszttel vagy a segédprogrammal ellenőrizheti 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`

Gyakorlati feladatok

Feladat 1

Cserélje ki a számított elemet előfeldolgozással.

Állapot: A hőmérsékletet Fahrenheitben kapja meg az érzékelőtől, hogy Celsiusban tárolja.

Korábban olyan elemet hoztunk létre, amely a hőmérsékletet Fahrenheit-fokban gyűjti. Ezt követően egy másik adatelem (számított), amely egy képlet segítségével konvertálja a Fahrenheit-et Celsiusra.

Problémák:

  • Szükséges az adatelemek megkettőzése és az összes érték tárolása az adatbázisban.
  • Meg kell állapodni a képletben kiszámított és felhasznált "szülő" adatelem és a számított adattétel intervallumaiban. Ellenkező esetben a kiszámított tétel nem támogatott állapotba kerülhet, vagy egy korábbi értéket számíthat ki, ami befolyásolja a megfigyelési eredmények megbízhatóságát.

Az egyik megoldás az volt, hogy a rugalmas ellenőrzési időközöktől eltértünk a rögzített időközök javára, így biztosítva, hogy a kiszámított tétel az adatokat fogadó elem (esetünkben a hőmérséklet Fahrenheit-fokban) után kerüljön kiértékelésre.

De ha például a sablont nagyszámú eszköz ellenőrzésére használjuk, és az ellenőrzést 30 másodpercenként egyszer hajtják végre, akkor a Zabbix 29 másodpercig "hackel", és az utolsó másodpercben elkezdi az ellenőrzést és a számolást. Ez sorokat hoz létre, és befolyásolja a teljesítményt. Ezért csak akkor javasolt a rögzített intervallumok használata, ha valóban szükséges.

Ebben a problémában az optimális megoldás egy egysoros JavaScript-előfeldolgozás, amely a Fahrenheit-fokokat Celsius-fokokra konvertálja:

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

Gyors és egyszerű, nem kell felesleges adatelemeket létrehozni és előzményeket vezetni róluk, és rugalmas időközönként is használható az ellenőrzések elvégzése.

Gyakorlati problémákat oldunk meg a Zabbix-ban JavaScript segítségével

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

De ha egy hipotetikus helyzetben szükség van például a kapott adatelem hozzáadására a makróban definiált bármely konstanssal, akkor figyelembe kell venni, hogy a paraméter érték stringgé bővül. Egy karakterlánc-összeadási művelet során két karakterlánc egyszerűen egybe van vonva.

Gyakorlati problémákat oldunk meg a Zabbix-ban JavaScript segítségével

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

A matematikai művelet eredményének megszerzéséhez a kapott értékek típusait numerikus formátumba kell konvertálni. Ehhez használhatja a funkciót parseInt (), amely egy egész számot, egy függvényt állít elő parseFloat(), amely tizedesjegyet vagy függvényt állít elő szám, amely egész vagy tizedes számot ad vissza.

2. feladat

Kapja meg az időt másodpercben a tanúsítvány végéig.

Állapot: egy szolgáltatás tanúsítvány lejárati dátumát ad ki „Feb 12 12:33:56 2022 GMT” formátumban.

ECMAScript5-ben date.parse() elfogad egy dátumot ISO 8601 formátumban (ÉÉÉÉ-HH-NNTHH:mm:ss.sssZ). Egy karakterláncot kell rá önteni HH DD ÉÉÉÉ ÓÓ:pp:ss ZZ formátumban

probléma: A hónap értéke szövegben van kifejezve, nem számként. Az ilyen formátumú adatokat a Duktape nem fogadja el.

Megoldási példa:

  • Először is deklarálunk egy változót, amely értéket vesz fel (a teljes szkript olyan változók deklarációja, amelyek vesszővel vannak elválasztva).

  • Az első sorban a dátumot kapjuk a paraméterben érték és a metódus segítségével szóközökkel válassza el osztott. Így kapunk egy tömböt, ahol a tömb minden eleme a 0 indextől kezdve egy szóköz előtti és utáni dátumelemnek felel meg. osztás(0) - hónap, osztás(1) - szám, osztás(2) - egy string időt, stb. Ezt követően a dátum minden eleme indexel érhető el a tömbben.

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

  • Minden hónap (időrendi sorrendben) megfelel a tömbben elfoglalt pozíciójának indexének (0-tól 11-ig). Szöveges érték numerikus értékké alakításához hozzáad egyet a hónap indexéhez (mivel a hónapok számozása 1-től kezdődik). Ebben az esetben az egy hozzáadásával járó kifejezést zárójelbe tesszük, mert különben egy karakterláncot kapunk, nem egy számot. A végén megtesszük szelet () - vágja le a tömböt a végéről, hogy csak két karakter maradjon (ami kétjegyű szám esetén hónapokig fontos).

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

  • A kapott értékekből ISO formátumú karakterláncot képezünk a szokásos karakterláncok megfelelő sorrendben történő hozzáadásával.

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

Az így kapott formátumban szereplő adatok a másodpercek száma 1970-től a jövő egy pontjáig. Szinte lehetetlen a fogadott formátumú adatokat triggerekben használni, mert a Zabbix csak makróval működik {Dátum} и {Idő}, amelyek felhasználóbarát formátumban adják vissza a dátumot és az időt.

  • Ezután megkaphatjuk az aktuális dátumot JavaScriptben Unix időbélyeg formátumban, és levonhatjuk a kapott tanúsítvány lejárati dátumából, hogy megkapjuk a mostantól a tanúsítvány lejártáig tartó ezredmásodpercek számát.

`now = Date.now();`

  • A kapott értéket elosztjuk ezerrel, hogy Zabbixban másodperceket kapjunk.

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

A triggerben megadhatja a ' kifejezéstutolsó' után egy olyan számjegykészlet, amely megfelel annak az időszaknak a másodperceinek, amelyre válaszolni kíván, például hetekben. Így a trigger értesíti, hogy a tanúsítvány egy héten belül lejár.

Megjegyzés. Ügyeljen a használatára parseInt () funkcióban visszatéréshogy az ezredmásodpercek osztásából származó törtszámot egész számmá alakítsuk. Használhatod is parseFloat() és töredékes adatokat tárol.

Nézd meg a riportot

Forrás: will.com

Hozzászólás