Niresolba namin ang mga praktikal na problema sa Zabbix gamit ang JavaScript

Niresolba namin ang mga praktikal na problema sa Zabbix gamit ang JavaScript
Tikhon Uskov, Zabbix integration team engineer

Ang Zabbix ay isang napapasadyang platform na ginagamit upang subaybayan ang anumang uri ng data. Mula noong mga pinakaunang bersyon ng Zabbix, ang mga tagapangasiwa ng pagsubaybay ay may kakayahang magpatakbo ng iba't ibang mga script sa pamamagitan ng Aksyon para sa mga pagsusuri sa mga target na node ng network. Kasabay nito, ang paglulunsad ng mga script ay humantong sa isang bilang ng mga paghihirap, kabilang ang tulad ng pangangailangan upang suportahan ang mga script, ang kanilang paghahatid sa mga node at proxy ng komunikasyon, pati na rin ang suporta para sa iba't ibang mga bersyon.

JavaScript para sa Zabbix

Noong Abril 2019, ipinakilala ang Zabbix 4.2 kasama ang JavaScript preprocessing. Maraming mga tao ang nasasabik tungkol sa ideya ng pag-abandona sa pagsusulat ng mga script na kumukuha ng data sa isang lugar, hinuhukay ito at ibigay ito sa isang format na naiintindihan ng Zabbix, at magsagawa ng mga simpleng pagsusuri na makakatanggap ng data na hindi handa para sa imbakan at pagproseso ng Zabbix, at pagkatapos ay iproseso ang stream ng data na ito gamit ang mga tool ng Zabbix at JavaScript. Kasabay ng pagtuklas sa mababang antas at mga umaasang item na lumabas sa Zabbix 3.4, nakakuha kami ng medyo flexible na konsepto para sa pag-uuri at pamamahala sa natanggap na data.

Sa Zabbix 4.4, bilang isang lohikal na pagpapatuloy ng paunang pagproseso sa JavaScript, lumitaw ang isang bagong paraan ng pag-abiso - Webhook, na maaaring magamit upang madaling isama ang mga abiso ng Zabbix sa mga third-party na application.

JavaScript at Duktapes

Bakit napili ang JavaScript at Duktape? Ang iba't ibang mga pagpipilian para sa mga wika at makina ay isinasaalang-alang:

  • Lua - Lua 5.1
  • Lua - LuaJIT
  • Javascript - Duktape
  • JavaScript - JerryScript
  • Naka-embed na Python
  • Naka-embed na Perl

Ang pangunahing pamantayan sa pagpili ay ang pagkalat, kadalian ng pagsasama ng makina sa produkto, mababang pagkonsumo ng mapagkukunan at pangkalahatang pagganap ng makina, at ang kaligtasan ng pagpasok ng code sa wikang ito sa pagsubaybay. Batay sa kumbinasyon ng mga indicator, nanalo ang JavaScript sa Duktape engine.

Niresolba namin ang mga praktikal na problema sa Zabbix gamit ang JavaScript

Pamantayan sa pagpili at pagsubok sa pagganap

Mga Tampok ng Duktape:

β€” Pamantayan ECMAScript E5/E5.1
- Mga module ng Zabbix para sa Duktape:

  • Zabbix.log() - nagbibigay-daan sa iyo na magsulat ng mga mensahe na may iba't ibang antas ng detalye nang direkta sa log ng Zabbix Server, na ginagawang posible na maiugnay ang mga error, halimbawa, sa isang Webhook, sa estado ng server.
  • CurlHttpRequest() - nagbibigay-daan sa iyong gumawa ng mga kahilingan sa HTTP sa network, kung saan nakabatay ang paggamit ng Webhook.
  • atob() at btoa() - pinapayagan kang mag-encode at mag-decode ng mga string sa Base64 na format.

TANDAAN. Sumusunod ang Duktape sa mga pamantayan ng ACME. Ginagamit ng Zabbix ang 2015 na bersyon ng script. Ang mga kasunod na pagbabago ay menor de edad, kaya maaaring hindi papansinin..

JavaScript magic

Ang lahat ng mahika ng JavaScript ay nakasalalay sa dynamic na pag-type at pag-type ng cast: string, numeric, at boolean.

Nangangahulugan ito na hindi kinakailangang ideklara nang maaga kung anong uri ang dapat ibalik ng variable ng isang halaga.

Sa mga pagpapatakbo ng matematika, ang mga halaga na ibinalik ng mga operator ng function ay na-convert sa mga numero. Ang pagbubukod sa mga naturang operasyon ay karagdagan, dahil kung ang kahit isa sa mga termino ay isang string, ang conversion ng string ay inilalapat sa lahat ng mga termino.

TANDAAN. Ang mga pamamaraan na responsable para sa mga naturang pagbabago ay karaniwang ipinapatupad sa mga prototype ng magulang ng object, halagaOf ΠΈ saString. halagaOf tinatawag sa panahon ng numerical conversion at palaging bago ang pamamaraan saString. Pamamaraan halagaOf dapat ibalik ang mga primitive na halaga, kung hindi, ang resulta nito ay hindi papansinin.

Ang isang pamamaraan ay tinatawag sa isang bagay halagaOF. Kung hindi ito natagpuan o hindi nagbabalik ng primitive na halaga, ang pamamaraan ay tinatawag saString. Kung ang pamamaraan saString hindi natagpuan, naghahanap halagaOf sa prototype ng bagay, at ang lahat ay paulit-ulit hanggang sa makumpleto ang pagproseso ng halaga at ang lahat ng mga halaga sa expression ay ihagis sa parehong uri. Kung ang bagay ay nagpapatupad ng isang pamamaraan saString, na nagbabalik ng primitive na halaga, pagkatapos ay ito ang ginagamit para sa conversion ng string. Gayunpaman, ang resulta ng paglalapat ng pamamaraang ito ay hindi kinakailangang isang string.

Halimbawa, kung para sa object 'obj' paraan ay tinukoy saString,

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

Paraan saString nagbabalik ng eksaktong string, at kapag nagdaragdag ng string na may numero, nakakakuha tayo ng nakadikit na string:

`obj + 1 // '2001'` 

`obj + 'a' // β€˜200a'`

Ngunit kung isusulat mo muli saString, upang ang pamamaraan ay magbabalik ng isang numero, kapag ang bagay ay idinagdag, isang mathematical operation na may isang numeric na conversion ay isasagawa at ang resulta ng mathematical na karagdagan ay makukuha.

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

`obj + 1 // '2001'`

Sa kasong ito, kung magsasagawa kami ng karagdagan gamit ang isang string, isang string na conversion ay isinasagawa, at makakakuha tayo ng nakadikit na string.

`obj + 'a' // β€˜200a'`

Ito ang dahilan ng malaking bilang ng mga pagkakamali ng mga baguhang gumagamit ng JavaScript.

Ang paraan saString maaari kang magsulat ng isang function na magpapataas ng kasalukuyang halaga ng object ng 1.

Niresolba namin ang mga praktikal na problema sa Zabbix gamit ang JavaScript
Pagpapatupad ng script, sa kondisyon na ang variable ay katumbas ng 3, at ito ay katumbas din ng 4.

Kung ihahambing sa isang cast (==), ang pamamaraan ay isinasagawa sa bawat oras saString na may function na pagtaas ng halaga. Alinsunod dito, sa bawat kasunod na paghahambing, ang halaga ay tumataas. Ito ay maiiwasan sa pamamagitan ng paggamit ng non-cast na paghahambing (===).

Niresolba namin ang mga praktikal na problema sa Zabbix gamit ang JavaScript
Paghahambing nang walang uri ng paghahagis

TANDAAN. Huwag Gumamit ng Paghahambing ng Cast nang Hindi Kinakailangan.

Para sa mga kumplikadong script, tulad ng Webhooks na may kumplikadong lohika, na nangangailangan ng paghahambing sa uri ng pag-cast, inirerekumenda na paunang sumulat ng mga tseke para sa mga halaga na nagbabalik ng mga variable at pinangangasiwaan ang mga hindi pagkakapare-pareho at mga error.

Webhook Media

Sa huling bahagi ng 2019 at unang bahagi ng 2020, ang Zabbix integration team ay aktibong bumubuo ng mga Webhook at out-of-the-box na pagsasama na kasama ng Zabbix distribution.

Niresolba namin ang mga praktikal na problema sa Zabbix gamit ang JavaScript
Link sa dokumentasyon

Nagpoproseso

  • Ang pagdating ng preprocessing sa JavaScript ay naging posible na iwanan ang karamihan sa mga panlabas na script, at sa kasalukuyan sa Zabbix maaari kang makakuha ng anumang halaga at i-convert ito sa isang ganap na naiibang halaga.
  • Ang preprocessing sa Zabbix ay ipinapatupad ng JavaScript code, na, kapag pinagsama-sama sa bytecode, ay na-convert sa isang function na tumatagal ng isang solong halaga bilang isang parameter halaga bilang isang string (ang isang string ay maaaring maglaman ng parehong digit at isang numero).
  • Dahil ang output ay isang function, sa dulo ng script ay kinakailangan pagbabalik.
  • Posibleng gumamit ng mga custom na macro sa code.
  • Ang mga mapagkukunan ay maaaring limitado hindi lamang sa antas ng operating system, kundi pati na rin sa programmatically. Ang hakbang sa preprocessing ay inilalaan ng maximum na 10 megabytes ng RAM at isang run time limit na 10 segundo.

Niresolba namin ang mga praktikal na problema sa Zabbix gamit ang JavaScript

TANDAAN. Ang halaga ng timeout na 10 segundo ay napakalaki, dahil ang pagkolekta ng may kondisyong libu-libong mga item ng data sa 1 segundo ayon sa isang medyo "mabigat" na senaryo ng preprocessing ay maaaring makapagpabagal sa Zabbix. Samakatuwid, hindi inirerekomenda na gumamit ng preprocessing upang magsagawa ng ganap na mga script ng JavaScript sa pamamagitan ng tinatawag na mga elemento ng shadow data (mga dummy item), na pinapatakbo lamang upang maisagawa ang preprocessing.

Maaari mong suriin ang iyong code sa pamamagitan ng preprocessing test o gamit ang utility 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`

Mga praktikal na gawain

Gawain 1

Palitan ang kinakalkula na item ng preprocessing.

Kundisyon: Kunin ang temperatura sa Fahrenheit mula sa sensor upang maiimbak sa Celsius.

Dati, gagawa kami ng item na nangongolekta ng temperatura sa degrees Fahrenheit. Pagkatapos noon, isa pang data item (kinakalkula) na magko-convert ng Fahrenheit sa Celsius gamit ang isang formula.

Mga Problema:

  • Kinakailangan na i-duplicate ang mga elemento ng data at iimbak ang lahat ng mga halaga sa database.
  • Dapat kang sumang-ayon sa mga pagitan para sa item ng data na "magulang" na kinakalkula at ginagamit sa formula, at para sa nakalkulang item ng data. Kung hindi, ang nakalkula na item ay maaaring mapunta sa isang hindi suportadong estado o magkalkula ng isang nakaraang halaga, na makakaapekto sa pagiging maaasahan ng mga resulta ng pagsubaybay.

Ang isang solusyon ay ang paglayo sa mga nababagong agwat ng pagsusuri sa pabor sa mga nakapirming agwat upang matiyak na ang nakalkulang item ay sinusuri pagkatapos ng item na tumatanggap ng data (sa aming kaso, ang temperatura sa degrees Fahrenheit).

Ngunit kung, halimbawa, ginagamit namin ang template upang suriin ang isang malaking bilang ng mga aparato, at ang pagsusuri ay isinasagawa nang isang beses bawat 30 segundo, ang Zabbix ay "nag-hack" sa loob ng 29 segundo, at sa huling segundo ay nagsisimula itong suriin at kalkulahin. Lumilikha ito ng isang pila at nakakaapekto sa pagganap. Samakatuwid, inirerekumenda na gumamit lamang ng mga nakapirming agwat kung talagang kinakailangan.

Sa problemang ito, ang pinakamainam na solusyon ay isang one-line na JavaScript preprocessing na nagko-convert ng degrees Fahrenheit sa degrees Celsius:

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

Ito ay mabilis at madali, hindi mo kailangang gumawa ng mga hindi kinakailangang item ng data at panatilihin ang isang kasaysayan sa mga ito, at maaari ka ring gumamit ng mga nababagong agwat para sa mga pagsusuri.

Niresolba namin ang mga praktikal na problema sa Zabbix gamit ang JavaScript

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

Ngunit, kung sa isang hypothetical na sitwasyon ay kinakailangan upang idagdag ang natanggap na elemento ng data, halimbawa, sa anumang pare-pareho na tinukoy sa macro, dapat itong isaalang-alang na ang parameter halaga lumalawak sa isang string. Sa isang operasyon ng pagdaragdag ng string, ang dalawang string ay pinagsama-sama lamang sa isa.

Niresolba namin ang mga praktikal na problema sa Zabbix gamit ang JavaScript

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

Upang makuha ang resulta ng isang mathematical operation, kinakailangan na i-convert ang mga uri ng mga nakuhang halaga sa isang numeric na format. Para dito maaari mong gamitin ang function parseInt(), na gumagawa ng isang integer, isang function parseFloat(), na gumagawa ng isang decimal, o isang function numero, na nagbabalik ng integer o decimal.

Gawain 2

Kunin ang oras sa ilang segundo hanggang sa katapusan ng certificate.

Kundisyon: naglalabas ang isang serbisyo ng petsa ng pag-expire ng certificate sa format na "Feb 12 12:33:56 2022 GMT".

Sa ECMAScript5 date.parse() tumatanggap ng petsa sa ISO 8601 na format (YYYY-MM-DDTHH:mm:ss.sssZ). Kinakailangang maglagay ng string dito sa format na MMM DD YYYY HH:mm:ss ZZ

problema: Ang halaga ng buwan ay ipinahayag bilang teksto, hindi bilang isang numero. Ang data sa format na ito ay hindi tinatanggap ng Duktape.

Halimbawa ng solusyon:

  • Una sa lahat, ang isang variable ay ipinahayag na tumatagal ng isang halaga (ang buong script ay isang deklarasyon ng mga variable na nakalista na pinaghihiwalay ng mga kuwit).

  • Sa unang linya makuha namin ang petsa sa parameter halaga at paghiwalayin ito ng mga puwang gamit ang pamamaraan pagsibak. Kaya, nakakakuha tayo ng array, kung saan ang bawat elemento ng array, simula sa index 0, ay tumutugma sa isang elemento ng petsa bago at pagkatapos ng isang puwang. hati(0) - buwan, hati(1) - numero, hati(2) - isang string na may oras, atbp. Pagkatapos nito, ang bawat elemento ng petsa ay maaaring ma-access sa pamamagitan ng index sa array.

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

  • Ang bawat buwan (sa magkakasunod na pagkakasunud-sunod) ay tumutugma sa index ng posisyon nito sa array (mula 0 hanggang 11). Upang i-convert ang isang text value sa isang numeric na halaga, ang isa ay idaragdag sa index ng buwan (dahil ang mga buwan ay binibilang simula sa 1). Sa kasong ito, ang expression na may pagdaragdag ng isa ay kinuha sa mga bracket, dahil kung hindi, isang string ang makukuha, hindi isang numero. Sa dulo ginagawa namin slice() - gupitin ang array mula sa dulo upang mag-iwan lamang ng dalawang character (na mahalaga para sa mga buwan na may dalawang-digit na numero).

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

  • Bumubuo kami ng isang string sa format na ISO mula sa nakuha na mga halaga sa pamamagitan ng karaniwang pagdaragdag ng mga string sa naaangkop na pagkakasunud-sunod.

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

Ang data sa resultang format ay ang bilang ng mga segundo mula 1970 hanggang sa ilang punto sa hinaharap. Halos imposible na gumamit ng data sa natanggap na format sa mga trigger, dahil pinapayagan ka ng Zabbix na gumana lamang sa mga macro {Petsa} ΠΈ {Oras}, na nagbabalik ng petsa at oras sa isang format na madaling gamitin.

  • Pagkatapos ay makukuha natin ang kasalukuyang petsa sa JavaScript sa Unix Timestamp na format at ibawas ito sa resultang petsa ng pag-expire ng certificate upang makuha ang bilang ng mga millisecond mula ngayon hanggang sa mag-expire ang certificate.

`now = Date.now();`

  • Hinahati namin ang natanggap na halaga sa isang libo upang makakuha ng mga segundo sa Zabbix.

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

Sa trigger, maaari mong tukuyin ang expression na 'huli' na sinusundan ng isang hanay ng mga digit na tumutugma sa bilang ng mga segundo sa panahon kung saan mo gustong tumugon, halimbawa, sa mga linggo. Kaya, aabisuhan ng trigger na mag-e-expire ang certificate sa loob ng isang linggo.

TANDAAN. Bigyang-pansin ang paggamit parseInt() sa pag-andar pagbabalikupang i-convert ang fractional number na nagreresulta mula sa paghahati ng milliseconds sa isang integer. Maaari mo ring gamitin parseFloat() at mag-imbak ng fractional data.

Panoorin ang ulat

Pinagmulan: www.habr.com

Magdagdag ng komento