Risolvemu prublemi pratichi in Zabbix usendu JavaScript

Risolvemu prublemi pratichi in Zabbix usendu JavaScript
Tikhon Uskov, ingegnere di squadra di integrazione Zabbix

Zabbix hè una piattaforma persunalizabile chì hè aduprata per monitorà ogni tipu di dati. Dapoi e prime versioni di Zabbix, l'amministratori di monitoraghju anu avutu a capacità di eseguisce diversi script via Actions per i cuntrolli nantu à i nodi di rete di destinazione. À u listessu tempu, u lanciu di script hà purtatu à una quantità di difficultà, cum'è cum'è a necessità di supportà scripts, a so consegna à i nodi di cumunicazione è i proxy, è ancu u supportu per e diverse versioni.

JavaScript per Zabbix

In April 2019, Zabbix 4.2 hè statu introduttu cù preprocessing JavaScript. Parechje persone anu entusiasmu cù l'idea di abbandunà i script di scrittura chì piglianu dati in qualchì locu, digeriscenu è furnisce in un formatu chì Zabbix capisce, è eseguisce cuntrolli simplici chì riceveranu dati chì ùn sò micca pronti per u almacenamentu è u processu da Zabbix, è poi processà stu flussu di dati cù l'arnesi Zabbix è JavaScript. In cunghjunzione cù scuperta di livellu bassu è elementi dipendente chì apparsu in Zabbix 3.4, avemu un cuncettu abbastanza flexible per sorte è gestione di e dati ricevuti.

In Zabbix 4.4, cum'è una continuazione logica di pre-processamentu in JavaScript, hè apparsu un novu metudu di notificazione - Webhook, chì pò esse usatu per integrà facilmente e notificazioni Zabbix cù applicazioni di terzu.

JavaScript è Duktapes

Perchè sò stati scelti JavaScript è Duktape? Diverse opzioni per lingue è motori sò state cunsiderate:

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

I criterii principali di selezzione eranu prevalenza, facilità d'integrazione di u mutore in u produttu, u cunsumu di risorse bassu è u rendiment generale di u mutore, è a sicurità di introduzzione di codice in questa lingua in u monitoraghju. Basatu nantu à a cumminazzioni di indicatori, JavaScript hà vintu nantu à u mutore Duktape.

Risolvemu prublemi pratichi in Zabbix usendu JavaScript

Criteri di selezzione è teste di rendiment

Caratteristiche di Duktape:

- Standard ECMAScript E5/E5.1
- Moduli Zabbix per Duktape:

  • Zabbix.log () - permette di scrive missaghji cù diversi livelli di ditagli direttamente in u logu di u servitore Zabbix, chì permette di correlate l'errori, per esempiu, in un Webhook, cù u statu di u servitore.
  • CurlHttpRequest () - permette di fà dumande HTTP à a reta, nantu à quale l'usu di Webhook hè basatu.
  • atob () è btoa () - permette di codificà è decodificà stringhe in u formatu Base64.

NOTA. Duktape hè conforme à i standard ACME. Zabbix usa a versione 2015 di u script. I cambiamenti successivi sò minori, cusì ponu esse ignorati..

Magia JavaScript

Tutta a magia di JavaScript si trova in a tipografia dinamica è a casting di tipu: stringa, numerica è booleana.

Questu significa chì ùn hè micca necessariu di dichjarà in anticipu chì tippu a variàbile deve rinvià un valore.

In l'operazioni matematiche, i valori restituiti da l'operatori di funzione sò cunvertiti in numeri. L'eccezzioni à tali operazioni hè l'aghjunzione, perchè se almenu unu di i termini hè una stringa, a cunversione di stringa hè appiicata à tutti i termini.

NOTA. I metudi rispunsevuli di tali trasfurmazioni sò generalmente implementati in i prototipi parentali di l'ughjettu, valoreOf и àString. valoreOf chjamatu durante a cunversione numerica è sempre prima di u metudu àString. Metudu valoreOf deve rinvià i valori primitivi, altrimenti u so risultatu hè ignoratu.

Un metudu hè chjamatu nantu à un oggettu valore di. Se ùn hè micca truvatu o ùn torna micca un valore primitivu, u metudu hè chjamatu àString. Se u metudu àString micca trovu, cerca valoreOf in u prototipu di l'ughjettu, è tuttu hè ripetutu finu à chì u processu di u valore hè cumpletu è tutti i valori in l'espressione sò cast à u listessu tipu.. Se l'ughjettu implementa un metudu àString, chì torna un valore primitivu, allora hè quellu chì hè utilizatu per a cunversione di stringa. Tuttavia, u risultatu d'applicà stu metudu ùn hè micca necessariamente una stringa.

Per esempiu, se per l'ughjettu 'ughjettu"U metudu hè definitu àString,

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

Metu àString torna esattamente una stringa, è quandu aghjunghje una stringa cù un numeru, avemu una stringa incollata:

`obj + 1 // '2001'` 

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

Ma si riscrive àString, cusì chì u metudu torna un numeru, quandu l'ughjettu hè aghjuntu, una operazione matematica cù una cunversione numerica serà realizatu è u risultatu di l'aghjuntu matematicu serà ottenutu.

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

`obj + 1 // '2001'`

In questu casu, se facemu l'aghjunzione cù una stringa, una cunversione di stringa hè realizata, è avemu una stringa incollata.

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

Questu hè u mutivu di un gran numaru di sbagli da l'utilizatori novi JavaScript.

U metudu àString pudete scrive una funzione chì aumenterà u valore attuale di l'ughjettu da 1.

Risolvemu prublemi pratichi in Zabbix usendu JavaScript
Esecuzione di u script, basta chì a variabile hè uguale à 3, è hè ancu uguale à 4.

Comparatu cù un cast (==), u metudu hè eseguitu ogni volta àString cù a funzione di crescita di valore. Per quessa, cù ogni paraguni sussegwente, u valore aumenta. Questu pò esse evitata usendu paraguni non-cast (===).

Risolvemu prublemi pratichi in Zabbix usendu JavaScript
Paragone senza tippu casting

NOTA. Ùn aduprate micca u Cast Comparaison Inutilmente.

Per i scripti cumplessi, cum'è Webhooks cù logica cumplessa, chì necessitanu paraguni cù u casting di tipu, hè cunsigliatu di pre-scrive cuntrolli per i valori chì tornanu variabili è trattanu inconsistenze è errori.

Webhook Media

À a fine di u 2019 è à l'iniziu di u 2020, a squadra di integrazione Zabbix hà sviluppatu attivamente Webhooks è integrazioni out-of-the-box chì venenu cù a distribuzione Zabbix.

Risolvemu prublemi pratichi in Zabbix usendu JavaScript
Ligame à documentazione

Preprucessamentu

  • L'avventu di preprocessing in JavaScript hà permessu di abbandunà a maiò parte di i script esterni, è attualmente in Zabbix pudete ottene qualsiasi valore è cunvertisce in un valore completamente diversu.
  • A preprocessazione in Zabbix hè implementata da u codice JavaScript, chì, quandu compilatu in bytecode, hè cunvertitu in una funzione chì piglia un valore unicu cum'è paràmetru. valore cum'è una stringa (una stringa pò cuntene un cifru è un numeru).
  • Siccomu l'output hè una funzione, à a fine di u script hè necessariu ritornu.
  • Hè pussibule aduprà macros persunalizati in u codice.
  • I risorsi ponu esse limitati micca solu à u nivellu di u sistema operatore, ma ancu programmaticu. U passu di preprocessing hè attribuitu un massimu di 10 megabytes di RAM è un limitu di runtime di 10 seconde.

Risolvemu prublemi pratichi in Zabbix usendu JavaScript

NOTA. U valore di timeout di 10 seconde hè assai assai, perchè a cullizzioni di millaie di dati cundiziunali in 1 secondu secondu un scenariu di preprocessazione piuttostu "pesante" pò rallentà Zabbix. Per quessa, ùn hè micca cunsigliatu di utilizà a preprocessazione per eseguisce scripts JavaScript cumpletu attraversu l'elementi di dati ombra chjamati (elementi fittizi), chì sò eseguiti solu per eseguisce preprocessing..

Pudete cuntrollà u vostru còdice attraversu a prova di preprocessing o usendu l'utilità 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`

I travaglii pratichi

Objettivu 1

Sustituisce l'elementu calculatu cù preprocessing.

Cundizione: Ottene a temperatura in Fahrenheit da u sensor per almacenà in Celsius.

Nanzu, avemu da creà un articulu chì recullà a temperatura in gradi Fahrenheit. Dopu quì, un altru articulu di dati (calculatu) chì cunvertisce Fahrenheit à Celsius cù una formula.

Problemi:

  • Hè necessariu duplicà elementi di dati è almacenà tutti i valori in a basa di dati.
  • Avete bisognu di l'intervalli per l'elementu di dati "parent" chì hè calculatu è utilizatu in a formula, è per l'elementu di dati calculatu. Altrimenti, l'elementu calculatu pò andà in un statu micca supportatu o calculà un valore precedente, chì affettarà l'affidabilità di i risultati di u monitoraghju.

Una solu suluzione era di alluntanassi da intervalli di cuntrollu flessibili in favore di intervalli fissi per assicurà chì l'articulu calculatu hè evaluatu dopu à l'articulu chì riceve i dati (in u nostru casu, a temperatura in gradi Fahrenheit).

Ma s'è, per esempiu, avemu aduprà u mudellu à verificà un gran numaru di dispusitivi, è u cuntrollu hè realizatu una volta ogni 30 seconde, Zabbix "hacks" per 29 seconde, è à l 'ultimu secondu principia à verificà è calculà. Questu crea una fila è affetta u rendiment. Dunque, hè cunsigliatu di utilizà intervalli fissi solu s'ellu hè veramente necessariu.

In questu prublema, a suluzione ottima hè un preprocessing JavaScript in una linea chì cunverte gradi Fahrenheit à gradi Celsius:

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

Hè veloce è faciule, ùn avete micca bisognu di creà elementi di dati innecessarii è mantene una storia nantu à elli, è pudete ancu aduprà intervalli flessibili per i cuntrolli.

Risolvemu prublemi pratichi in Zabbix usendu JavaScript

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

Ma, se in una situazione ipotetica hè necessariu aghjunghje l'elementu di dati ricivutu, per esempiu, cù qualsiasi constante definita in a macro, deve esse cunsideratu chì u paràmetru. valore si dilata in una corda. In una operazione di addizione di corde, duie corde sò simpliciamente cumminate in una sola.

Risolvemu prublemi pratichi in Zabbix usendu JavaScript

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

Per ottene u risultatu di una operazione matematica, hè necessariu di cunvertisce i tipi di i valori ottenuti in un furmatu numericu. Per questu pudete aduprà a funzione parseInt(), chì pruduce un interu, una funzione parseFloat(), chì pruduce un decimale, o una funzione nùmeru, chì restituisce un interu o decimale.

Task 2

Ottene u tempu in seconde finu à a fine di u certificatu.

Cundizione: un serviziu emette una data di scadenza di certificatu in u formatu "Feb 12 12:33:56 2022 GMT".

In ECMAScript5 data.parse() accetta una data in u furmatu ISO 8601 (AAAA-MM-GGTHH:mm:ss.sssZ). Hè necessariu di cascà una stringa in u furmatu MMM DD AAAA HH:mm:ss ZZ

prublemu: U valore di u mese hè spressu cum'è testu, micca cum'è un numeru. I dati in stu formatu ùn sò micca accettati da Duktape.

Esempiu di suluzione:

  • Prima di tuttu, una variàbile hè dichjarata chì piglia un valore (u scrittu sanu hè una dichjarazione di variàbili chì sò listati separati da virgule).

  • In a prima linea avemu a data in u paràmetru valore è separà cù spazii cù u metudu Split. Cusì, avemu un array, induve ogni elementu di l'array, cuminciendu à l'indice 0, currisponde à un elementu di data prima è dopu un spaziu. split (0) - mese, split (1) - numeru, split (2) - una stringa cù u tempu, etc. Dopu à quessa, ogni elementu di a data pò esse accessu per index in u array.

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

  • Ogni mese (in ordine cronologicu) currisponde à l'indici di a so pusizioni in l'array (da 0 à 11). Per cunvertisce un valore di testu à un valore numericu, unu hè aghjuntu à l'indici di u mese (perchè i mesi sò numerati da 1). In questu casu, l'espressione cù l'aghjunzione di unu hè presa in parentesi, perchè altrimenti una stringa serà ottenuta, micca un numeru. À a fine facemu fetta () - cut the array from the end to leave only two characters (chì hè impurtante per mesi cù un numeru di dui cifre).

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

  • Formemu una stringa in formatu ISO da i valori ottenuti da l'aghjunzione di stringhe in l'ordine adattatu.

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

I dati in u formatu risultatu hè u numeru di seconde da 1970 à qualchì puntu in u futuru. Hè quasi impussibile di utilizà dati in u formatu ricevutu in triggers, perchè Zabbix vi permette di operà solu cù macros. {Data} и {Time}, chì torna a data è l'ora in un formatu amichevule.

  • Pudemu allora ottene a data attuale in JavaScript in u formatu Unix Timestamp è sottrallu da a data di scadenza di u certificatu risultatu per ottene u numeru di millisecondi da avà finu à chì u certificatu scade.

`now = Date.now();`

  • Dividemu u valore ricevutu per mille per ottene seconde in Zabbix.

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

In u trigger, pudete specificà l'espressione 'ultimu' seguita da un inseme di cifre chì currisponde à u numeru di seconde in u periodu à quale vulete risponde, per esempiu, in settimane. Cusì, u trigger avvisarà chì u certificatu scade in una settimana.

NOTA. Attenti à l'usu parseInt() in funzione ritornuper cunvertisce u numeru fraccionariu risultatu da a divisione di millisecondi à un entero. Pudete ancu aduprà parseFloat() è almacenà dati fraccionari.

Fighjate u rapportu

Source: www.habr.com

Add a comment