Mir léisen praktesch Problemer an Zabbix mat JavaScript

Mir léisen praktesch Problemer an Zabbix mat JavaScript
Tikhon Uskov, Zabbix Integratioun Team Ingenieur

Zabbix ass eng personaliséierbar Plattform déi benotzt gëtt fir all Daten ze iwwerwaachen. Zënter de fréierste Versioune vun Zabbix hunn d'Iwwerwaachungsadministrateuren d'Fähigkeit fir verschidde Skripte via Aktiounen fir Kontrollen op Zil- Reseau Wirbelen. Zur selwechter Zäit hunn d'Skripte lancéiert zu enger Rei vu Schwieregkeeten gefouert, ënner anerem wéi d'Noutwendegkeet fir Scripten z'ënnerstëtzen, hir Liwwerung un d'Kommunikatiounsknäppchen a Proxyen, souwéi Ënnerstëtzung fir verschidde Versiounen.

JavaScript fir Zabbix

Am Abrëll 2019 gouf Zabbix 4.2 mat JavaScript Preprocessing Funktionalitéit agefouert. Vill Leit sinn op d'Iddi komm fir Scripten opzeginn déi Daten iergendwou huelen, se verdauen an an engem Format verständlech fir Zabbix ubidden, an amplaz einfach Kontrollen ausféieren déi Daten kréien déi net prett sinn fir ze späicheren an ze veraarbechten Zabbix, a veraarbecht dann dësen Datestroum mat Zabbix a JavaScript Tools. Am Zesummenhang mat Low-Level Entdeckung an ofhängeg Datenelementer, déi an Zabbix 3.4 opgetaucht sinn, war d'Resultat e zimlech flexibel Konzept fir d'Sortéierung an d'Gestioun vun den erhalenen Donnéeën.

Am Zabbix 4.4, als logesch Fortsetzung vun der Virveraarbechtung am JavaScript, erschéngt eng nei Notifikatiounsmethod - Webhook, déi benotzt ka ginn fir Zabbix Notifikatiounen mat Drëtt Partei Uwendungen einfach z'integréieren.

JavaScript an Duktape

Firwat goufen JavaScript an Duktape gewielt? Verschidde Méiglechkeeten fir Sproochen a Motore goufen berücksichtegt:

  • Lua - Lua 5.1
  • Lua - LuaJIT
  • Javascript - Duktape
  • Javascript - JerryScript
  • Embedded Python
  • Embedded Perl

D'Haaptauswielkriterien waren d'Prévalenz, d'Liichtegkeet vun der Integratioun vum Motor an de Produit, de gerénge Ressourceverbrauch an d'Gesamtleistung vum Motor, an d'Sécherheet vum Implementéiere vum Code an dëser Sprooch an der Iwwerwaachung. Baséierend op der Gesamtheet vun den Indikatoren huet JavaScript op der Duktape-Motor gewonnen.

Mir léisen praktesch Problemer an Zabbix mat JavaScript

Selektiounscritèren a Performance Tester

Features vun Duktape:

- Standard ECMAScript E5/E5.1
- Zabbix Moduler fir Duktape:

  • Zabbix.log () - erlaabt Iech Messagen mat verschiddenen Niveau vun Detail direkt an der Zabbix Server Logbuch ze schreiwen, déi mécht et méiglech Feeler ze vergläichen, Zum Beispill, an Webhook mat de Server Staat.
  • CurlHttpRequest () - erlaabt Iech HTTP-Ufroen un d'Netz ze maachen, op wat Webhook baséiert.
  • atob () an btoa () - erlaabt Iech Strings an Base64 Format ze codéieren an decodéieren.

NOTIZ. Duktape entsprécht ACME Standarden. Zabbix benotzt d'2015 Versioun vum Skript. Déi spéider Ännerungen si kleng a kënne ignoréiert ginn.

D'Magie vu JavaScript

All d'Magie vu JavaScript läit am dynamesche Tippen an Typcasting: String, numeresch a boolesch.

Dëst bedeit datt et net néideg ass am Viraus ze deklaréieren wéi eng Zort d'Variabel soll zréckkommen.

A mathematesche Operatiounen ginn d'Wäerter, déi vu Funktiounsbedreiwer zréckginn, an Zuelen ëmgewandelt. Eng Ausnam zu esou Operatiounen ass Zousatz, well wann op d'mannst ee vun de Begrëffer eng String ass, gëtt eng Stringkonversioun op all Begrëffer applizéiert.

NOTIZ. Methoden verantwortlech fir sou Transformatiounen ginn normalerweis an Elterenobjekt Prototypen implementéiert, Wäert vun и zu String. Wäert vun während enger numerescher Konversioun genannt an ëmmer virun der Method zu String. Method Wäert vun muss primitiv Wäerter zréckginn, soss gëtt säi Resultat ignoréiert.

Eng Method gëtt op en Objet genannt WäertOF. Wann et net fonnt gëtt oder kee primitive Wäert zréckkënnt, gëtt d'Method genannt zu String. Wann d'Method zu String net fonnt, sicht Wäert vun am Prototyp vum Objet, an alles gëtt widderholl bis de Wäert veraarbecht gëtt an all Wäerter am Ausdrock op déiselwecht Aart gegoss ginn. Wann den Objet eng Method implementéiert huet zu String, deen e primitive Wäert zréckkënnt, da gëtt se fir Stringkonversioun benotzt. Wéi och ëmmer, d'Resultat vun der Benotzung vun dëser Method ass net onbedéngt e String.

Zum Beispill, wann fir fir Objet 'Objet' Method ass definéiert zu String,

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

Methode zu String gëtt genee d'String zréck, a wann Dir d'String mat enger Nummer bäidréit, kréie mir de verbonne String:

`obj + 1 // '2001'` 

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

Awer wann Dir iwwerschreift zu StringFir datt d'Method eng Zuel zréckkënnt, wann Dir en Objet bäidréit, gëtt eng mathematesch Operatioun mat enger numerescher Konversioun gemaach an d'Resultat vun der mathematescher Zousatz gëtt kritt.

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

`obj + 1 // '2001'`

Ausserdeem, wa mir Zousatz op engem String ausféieren, gëtt eng Stringkonversioun duerchgefouert a mir kréien e verbonne String.

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

Dëst ass genee de Grond fir eng grouss Unzuel vu Feeler vun Ufänger JavaScript Benotzer.

D'Method zu String Dir kënnt eng Funktioun aginn déi den aktuelle Wäert vum Objet ëm 1 erhéicht.

Mir léisen praktesch Problemer an Zabbix mat JavaScript
Ausféierung vum Skript virausgesat datt d'Variabel gläich ass 3, an et ass och gläich wéi 4.

Wann Dir mam Typ Casting (==) vergläicht, gëtt d'Method all Kéier ausgefouert zu String mat Wäert erhéijen Funktioun. Deementspriechend, mat all spéider Verglach geet de Wäert erop. Dëst kann vermeit ginn andeems Dir Vergläicher ouni Typ Casting benotzt (===).

Mir léisen praktesch Problemer an Zabbix mat JavaScript
Verglach ouni Typ Goss

NOTIZ. Benotzt net Cast Vergläicher onnéideg.

Fir komplex Scripten, wéi Webhook mat komplexer Logik, an deenen Vergläicher mat Typ Casts noutwendeg sinn, ass et recommandéiert d'Checke fir d'Wäerter virzeschreiwen, déi d'Variabelen zréckginn an d'Inkonsistenz a Feeler behandelen.

Webhook Medien

Um Enn vun 2019 an Ufank 2020 huet d'Zabbix Integratiounsteam aktiv Webhooks an Out-of-the-Box Integratiounen entwéckelt, déi mat der Zabbix Verdeelung kommen.

Mir léisen praktesch Problemer an Zabbix mat JavaScript
Link zu Dokumentatioun

Virveraarbechtung

  • D'Entstoe vu Virveraarbechtung a JavaScript huet et méiglech gemaach déi meescht extern Scripten opzeginn, an elo an Zabbix kënnt Dir all Wäert huelen an en an e komplett anere Wäert transforméieren.
  • Virveraarbechtung an Zabbix gëtt vum JavaScript Code implementéiert, deen, wann se an Bytecode kompiléiert ass, an eng Funktioun ëmgewandelt gëtt déi en eenzege Wäert als Parameter hëlt Wäert als String (de String kann souwuel eng Zuel an eng Zuel enthalen).
  • Well d'Ausgab eng Funktioun ass, ass et um Enn vum Skript erfuerderlech zréck.
  • Et ass méiglech personaliséiert Makroen am Code ze benotzen.
  • Ressourcen kënnen net nëmmen um Betribssystemniveau limitéiert ginn, awer och programmatesch. De Virveraarbechtungsschrëtt gëtt maximal 10 Megabytes RAM an eng Runtimelimit vun 10 Sekonnen zougewisen.

Mir léisen praktesch Problemer an Zabbix mat JavaScript

NOTIZ. En Timeout-Wäert vun 10 Sekonnen ass zimlech grouss, well Dausende vun Datenelementer an 1 Sekonn sammelen mat engem zimlech "schweren" Virveraarbechtungsszenario kann Zabbix verlangsamen. Dofir ass et net recommandéiert d'Virveraarbechtung ze benotzen fir vollwäerteg JavaScript Scripten auszeféieren duerch déi sougenannte Schattendatenelementer (Dummy Elementer), déi nëmme gestart ginn fir d'Virveraarbechtung auszeféieren..

Dir kënnt Äre Code duerch e Virveraarbechtungstest kontrolléieren oder den Utility benotzen 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`

Praktesch Problemer

Objective 1

Ersetzen e berechent Dateartikel mat Virveraarbechtung.

Zoustand: Kritt Temperatur a Grad Fahrenheit vum Sensor fir a Grad Celsius ze späicheren.

Virdrun hätte mir en Dateelement erstallt deen d'Temperatur a Grad Fahrenheit gesammelt huet. Duerno gëtt en aneren Dateartikel (berechent) deen eng Formel benotzt fir Fahrenheit op Celsius ze konvertéieren.

Problem:

  • Et ass néideg Datenelementer ze duplizéieren an all Wäerter an der Datebank ze späicheren.
  • Dir musst d'Intervalle fir den "Elteren" Dateartikel averstanen, deen an der Formel an der berechent Dateartikel berechent a benotzt gëtt. Soss kann de berechent Dateartikel an en net ënnerstëtzten Zoustand erakommen oder de fréiere Wäert zielen, wat d'Zouverlässegkeet vun den Iwwerwaachungsresultater beaflosst.

Eng Léisung war fir sech vu flexibele Scheckintervallen zugonschte vu fixen Intervalle ewechzekréien fir sécherzestellen datt de berechnen Dateartikel nom Empfangsdatenartikel berechent gëtt (an eisem Fall Temperatur a Grad Fahrenheit).

Awer wa mir zum Beispill eng Schabloun benotze fir eng grouss Unzuel vun Apparater ze kontrolléieren, an d'Kontroll gëtt eemol all 30 Sekonnen gemaach, Zabbix "slackt" fir 29 Sekonnen, an an der leschter Sekonn fänkt se un ze kontrolléieren an ze berechnen. Dëst schaaft eng Schlaang an beaflosst d'Performance. Dofir ass et recommandéiert fix Intervalle nëmmen ze benotzen wann absolut néideg.

Fir dëse Problem ass déi optimal Léisung eng One-Line JavaScript Virveraarbechtung déi Fahrenheit op Celsius konvertéiert:

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

Et ass séier an einfach, Dir musst net onnéideg Datenelementer erstellen an d'Geschicht op hinnen späicheren, an Dir kënnt och flexibel Intervalle fir Kontrollen benotzen.

Mir léisen praktesch Problemer an Zabbix mat JavaScript

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

Awer wann et an enger hypothetescher Situatioun néideg ass fir dat resultéierend Dateelement ze addéieren, zum Beispill, mat e puer konstanten an engem Makro definéiert, ass et néideg ze berücksichtegen datt de Parameter Wäert erweidert an eng Linn. An enger String Additioun Operatioun sinn zwee Saiten einfach an een kombinéiert.

Mir léisen praktesch Problemer an Zabbix mat JavaScript

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

Fir d'Resultat vun enger mathematescher Operatioun ze kréien, ass et néideg d'Zorte vu Wäerter an e numerescht Format ze konvertéieren. Fir dëst ze maachen, kënnt Dir d'Funktioun benotzen parseInt(), déi eng ganz Zuel, Funktioun produzéiert parseFloat(), déi eng Dezimalfraktioun produzéiert, oder Funktioun Zuel, déi eng ganz Zuel oder eng Dezimalfraktioun produzéiert.

Problem 2

Kritt d'Zäit a Sekonnen bis de Certificat ofleeft.

Zoustand: e bestëmmte Service gëtt den Zertifikatverfallsdatum am Format "Feb 12 12:33:56 2022 GMT" eraus.

An ECMAScript5 date.parse() akzeptéiert en Datum am ISO 8601 Format (JJJJ-MM-DDTHH:mm:ss.sssZ). Dir musst et an eng String am Format MMM DD JJJJ HH:mm:ss ZZ konvertéieren

Problem: De Mountwäert gëtt als Text ausgedréckt anstatt als Zuel. Daten an dësem Format ginn net vun Duktape ugeholl.

Beispill Léisung:

  • Als éischt gëtt eng Variabel deklaréiert déi e Wäert hëlt (de ganze Skript ass eng Deklaratioun vu Variabelen déi mat Komma getrennt sinn).

  • An der éischter Zeil kréien mir den Datum am Parameter Wäert a trennt et mat Raum mat der Method SPLIT. Also kréie mir eng Array wou all Element vun der Array, ugefaange mam Index 0, entsprécht engem Datumelement virun an nom Raum. opgedeelt (0) - Mount, opgedeelt (1) - Zuel, opgedeelt (2) - eng String mat Zäit, etc.. Duerno kann all Datumelement duerch Index an der Array zougänglech sinn.

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

  • All Mount (an chronologescher Uerdnung) entsprécht engem Index vu senger Positioun am Array (vun 0 bis 11). Fir en Textwäert an en numeresche Wäert ëmzewandelen, gëtt een an de Mountindex bäigefüügt (well d'Monatnummeréierung bei 1 ufänkt). An dësem Fall gëtt den Ausdrock mat der Zousatz vun engem an Klammern geholl, well soss gëtt d'Resultat e String, net eng Zuel. Zum Schluss maache mir op Scheiwen () - schneiden d'Array vum Enn fir nëmmen zwee Zeechen ze loossen (wat wichteg ass fir Méint mat enger zwee-Zifferen Nummer).

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

  • Mir bilden eng String am ISO-Format aus de kritt Wäerter andeems Dir d'String einfach an der entspriechender Uerdnung bäigefüügt.

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

D'Daten am entsteet Format sinn d'Zuel vun de Sekonnen vun 1970 bis e puer Punkt an der Zukunft. Et ass bal onméiglech Daten am resultéierende Format an Ausléiser ze benotzen, well Zabbix erlaabt Iech nëmme mat Makroen ze bedreiwen {Datum} и {Zeit}, déi den Datum an d'Zäit an engem User-liesbare Format zréckginn.

  • Mir kënnen dann den aktuellen Datum am JavaScript am Unix Timestamp Format kréien an et vum resultéierende Verfallsdatum vum Zertifika subtrahéieren fir d'Zuel vu Millisekonnen vun elo un ze kréien bis de Certificat ofleeft.

`now = Date.now();`

  • Mir deelen de resultéierende Wäert vun dausend fir Sekonnen an Zabbix ze kréien.

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

An engem Ausléiser kënnt Dir den Ausdrock spezifizéieren 'lescht' an eng Rei vun Zuelen, déi der Unzuel vu Sekonnen an der Period entsprécht, op déi Dir musst reagéieren, zum Beispill a Wochen. Sou wäert den Ausléiser matdeelen datt den Zertifika an enger Woch ofleeft.

NOTIZ. Opgepasst op d'Benotzung parseInt() an Funktioun zréckfir d'Fraktiounszuel ze konvertéieren, déi duerch d'Divisioun vun Millisekonnen an eng ganz Zuel resultéiert. Dir kënnt och benotzen parseFloat() a späichert fractional Daten.

Kuckt de Bericht

Source: will.com

Setzt e Commentaire