Vi løser praktiske problemer i Zabbix ved hjælp af JavaScript

Vi løser praktiske problemer i Zabbix ved hjælp af JavaScript
Tikhon Uskov, Zabbix integrationsteamingeniør

Zabbix er en tilpasselig platform, der bruges til at overvåge enhver form for data. Siden de tidligste versioner af Zabbix har overvågningsadministratorer haft mulighed for at køre forskellige scripts via handlinger til kontrol af målnetværksknuder. Samtidig førte lanceringen af ​​scripts til en række vanskeligheder, herunder behovet for at understøtte scripts, deres levering til kommunikationsnoder og proxyer, samt understøttelse af forskellige versioner.

JavaScript til Zabbix

I april 2019 blev Zabbix 4.2 introduceret med JavaScript-forbehandling. Mange mennesker blev begejstrede for ideen om at opgive at skrive scripts, der tager data et sted hen, fordøje dem og levere dem i et format, som Zabbix forstår, og udføre enkle kontroller, der vil modtage data, der ikke er klar til lagring og behandling af Zabbix, og bearbejd derefter denne datastrøm ved hjælp af Zabbix- og JavaScript-værktøjer. I forbindelse med opdagelse på lavt niveau og afhængige elementer, der dukkede op i Zabbix 3.4, fik vi et ret fleksibelt koncept til sortering og styring af de modtagne data.

I Zabbix 4.4 er der som en logisk fortsættelse af forbehandling i JavaScript dukket en ny notifikationsmetode op - Webhook, som kan bruges til nemt at integrere Zabbix notifikationer med tredjeparts applikationer.

JavaScript og Duktapes

Hvorfor blev JavaScript og Duktape valgt? Forskellige muligheder for sprog og motorer blev overvejet:

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

De vigtigste udvælgelseskriterier var udbredelse, let integration af motoren i produktet, lavt ressourceforbrug og motorens overordnede ydeevne og sikkerheden ved at indføre kode på dette sprog i overvågningen. Baseret på kombinationen af ​​indikatorer vandt JavaScript på Duktape-motoren.

Vi løser praktiske problemer i Zabbix ved hjælp af JavaScript

Udvælgelseskriterier og præstationstest

Funktioner af Duktape:

- Standard ECMAScript E5/E5.1
- Zabbix-moduler til Duktape:

  • Zabbix.log() - giver dig mulighed for at skrive beskeder med forskellige detaljeringsniveauer direkte ind i Zabbix Server-loggen, hvilket gør det muligt at korrelere fejl, for eksempel i en Webhook, med servertilstanden.
  • CurlHttpRequest() - giver dig mulighed for at lave HTTP-anmodninger til netværket, som brugen af ​​Webhook er baseret på.
  • atob() og btoa() - giver dig mulighed for at kode og afkode strenge i Base64-format.

BEMÆRK. Duktape overholder ACME standarder. Zabbix bruger 2015-versionen af ​​scriptet. Efterfølgende ændringer er mindre, så de kan ignoreres..

JavaScript-magi

Al magien ved JavaScript ligger i dynamisk indtastning og typecasting: streng, numerisk og boolesk.

Det betyder, at det ikke er nødvendigt på forhånd at erklære, hvilken type variablen skal returnere en værdi.

I matematiske operationer konverteres de værdier, der returneres af funktionsoperatorer, til tal. Undtagelsen fra sådanne operationer er tilføjelse, fordi hvis mindst et af termerne er en streng, anvendes strengkonvertering på alle termer.

BEMÆRK. De metoder, der er ansvarlige for sådanne transformationer, er normalt implementeret i objektets overordnede prototyper, Værdi af и tilString. Værdi af kaldet under numerisk konvertering og altid før metoden tilString. Metode Værdi af skal returnere primitive værdier, ellers ignoreres resultatet.

En metode kaldes på et objekt Værdi af. Hvis den ikke findes eller ikke returnerer en primitiv værdi, kaldes metoden tilString. Hvis metoden tilString ikke fundet, søger Værdi af i objektets prototype, og alt gentages, indtil behandlingen af ​​værdien er afsluttet, og alle værdier i udtrykket er støbt til samme type. Hvis objektet implementerer en metode tilString, som returnerer en primitiv værdi, så er det den, der bruges til strengkonvertering. Resultatet af at anvende denne metode er dog ikke nødvendigvis en streng.

For eksempel, hvis for for objekt 'obj' metode er defineret tilString,

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

метод tilString returnerer nøjagtigt en streng, og når vi tilføjer en streng med et tal, får vi en limet streng:

`obj + 1 // '2001'` 

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

Men hvis du omskriver tilString, således at metoden returnerer et tal, når objektet tilføjes, vil der blive udført en matematisk operation med en numerisk konvertering og resultatet af matematisk addition vil blive opnået.

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

`obj + 1 // '2001'`

I dette tilfælde, hvis vi udfører addition med en streng, udføres en strengkonvertering, og vi får en limet streng.

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

Dette er årsagen til et stort antal fejl af nybegyndere JavaScript-brugere.

Metoden tilString du kan skrive en funktion, der vil øge den aktuelle værdi af objektet med 1.

Vi løser praktiske problemer i Zabbix ved hjælp af JavaScript
Udførelse af scriptet, forudsat at variablen er lig med 3, og den er også lig med 4.

Sammenlignet med en cast (==), udføres metoden hver gang tilString med værdiforøgelsesfunktion. Følgelig stiger værdien ved hver efterfølgende sammenligning. Dette kan undgås ved at bruge non-cast sammenligning (===).

Vi løser praktiske problemer i Zabbix ved hjælp af JavaScript
Sammenligning uden typestøbning

BEMÆRK. Brug ikke Cast-sammenligning unødigt.

For komplekse scripts, såsom Webhooks med kompleks logik, der kræver sammenligning med typecasting, anbefales det at forskrive kontroller for de værdier, der returnerer variabler og håndterer inkonsekvenser og fejl.

Webhook Media

I slutningen af ​​2019 og begyndelsen af ​​2020 har Zabbix-integrationsteamet aktivt udviklet Webhooks og out-of-the-box integrationer, der følger med Zabbix-distributionen.

Vi løser praktiske problemer i Zabbix ved hjælp af JavaScript
Link til dokumentation

forbehandling

  • Fremkomsten af ​​forbehandling i JavaScript gjorde det muligt at opgive de fleste eksterne scripts, og i øjeblikket kan du i Zabbix få en hvilken som helst værdi og konvertere den til en helt anden værdi.
  • Forbehandling i Zabbix er implementeret af JavaScript-kode, som, når den kompileres til bytekode, konverteres til en funktion, der tager en enkelt værdi som parameter værdi som en streng (en streng kan indeholde både et ciffer og et tal).
  • Da outputtet er en funktion, kræves i slutningen af ​​scriptet afkast.
  • Det er muligt at bruge brugerdefinerede makroer i koden.
  • Ressourcer kan begrænses ikke kun på operativsystemniveau, men også programmatisk. Forbehandlingstrinnet tildeles maksimalt 10 megabyte RAM og en køretid på 10 sekunder.

Vi løser praktiske problemer i Zabbix ved hjælp af JavaScript

BEMÆRK. Timeoutværdien på 10 sekunder er ret meget, fordi indsamling af betingede tusindvis af dataelementer på 1 sekund ifølge et ret "tungt" forbehandlingsscenario kan bremse Zabbix. Derfor anbefales det ikke at bruge forbehandling til at udføre fuldgyldige JavaScript-scripts gennem de såkaldte skyggedataelementer (dummy items), som kun køres for at udføre forbehandling.

Du kan tjekke din kode gennem forbehandlingstesten eller ved hjælp af hjælpeprogrammet 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`

Praktiske opgaver

Opgave 1

Erstat beregnet vare med forbehandling.

Tilstand: Få temperaturen i Fahrenheit fra sensoren til lagring i Celsius.

Tidligere ville vi lave en vare, der opsamler temperaturen i grader Fahrenheit. Derefter et andet dataelement (beregnet), der ville konvertere Fahrenheit til Celsius ved hjælp af en formel.

Problemer:

  • Det er nødvendigt at duplikere dataelementer og gemme alle værdier i databasen.
  • I skal aftale intervallerne for den "overordnede" datapost, der beregnes og anvendes i formlen, og for den beregnede datapost. Ellers kan det beregnede element gå i en ikke-understøttet tilstand eller beregne en tidligere værdi, hvilket vil påvirke pålideligheden af ​​overvågningsresultaterne.

En løsning var at gå væk fra fleksible kontrolintervaller til fordel for faste intervaller for at sikre, at det beregnede element evalueres efter det element, der modtager dataene (i vores tilfælde temperaturen i grader Fahrenheit).

Men hvis vi for eksempel bruger skabelonen til at tjekke et stort antal enheder, og kontrollen udføres en gang hvert 30. sekund, "hacker" Zabbix i 29 sekunder, og i sidste sekund begynder den at tjekke og regne. Dette skaber en kø og påvirker ydeevnen. Derfor anbefales det kun at bruge faste intervaller, hvis det virkelig er nødvendigt.

I dette problem er den optimale løsning en one-line JavaScript-forbehandling, der konverterer grader Fahrenheit til grader Celsius:

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

Det er hurtigt og nemt, du behøver ikke oprette unødvendige dataelementer og føre en historik på dem, og du kan også bruge fleksible intervaller til kontrol.

Vi løser praktiske problemer i Zabbix ved hjælp af JavaScript

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

Men hvis det i en hypotetisk situation er nødvendigt at tilføje det modtagne dataelement, for eksempel med en konstant defineret i makroen, skal det tages i betragtning, at parameteren værdi udvides til en streng. I en strengadditionsoperation kombineres to strenge simpelthen til én.

Vi løser praktiske problemer i Zabbix ved hjælp af JavaScript

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

For at opnå resultatet af en matematisk operation er det nødvendigt at konvertere typerne af de opnåede værdier til et numerisk format. Til dette kan du bruge funktionen parseInt(), som producerer et heltal, en funktion parseFloat(), som producerer en decimal eller en funktion nummer, som returnerer et heltal eller decimal.

2 udfordring

Få tiden i sekunder indtil slutningen af ​​certifikatet.

Tilstand: en tjeneste udsteder en certifikatudløbsdato i formatet "12. feb 12:33:56 2022 GMT".

I ECMAScript5 date.parse() accepterer en dato i ISO 8601-format (ÅÅÅÅ-MM-DDTHH:mm:ss.sssZ). Det er nødvendigt at caste en streng til den i formatet MMM DD ÅÅÅÅ TT:mm:ss ZZ

problem: Månedsværdien er udtrykt som tekst, ikke som et tal. Data i dette format accepteres ikke af Duktape.

Eksempel på løsning:

  • Først og fremmest erklæres en variabel, der tager en værdi (hele scriptet er en erklæring af variabler, der er opført adskilt med kommaer).

  • I første linje får vi datoen i parameteren værdi og adskille det med mellemrum ved hjælp af metoden delt. Således får vi et array, hvor hvert element i arrayet, startende ved indeks 0, svarer til et datoelement før og efter et mellemrum. split(0) - måned, split(1) - nummer, split(2) - en streng med tid osv. Derefter kan hvert element i datoen tilgås ved indeks i arrayet.

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

  • Hver måned (i kronologisk rækkefølge) svarer til indekset for dens position i arrayet (fra 0 til 11). For at konvertere en tekstværdi til en numerisk værdi tilføjes en til månedsindekset (fordi måneder er nummereret med start ved 1). I dette tilfælde tages udtrykket med tilføjelse af en i parentes, fordi ellers vil der fås en streng, ikke et tal. Til sidst gør vi det skive() - klip arrayet fra enden, så der kun er to tegn tilbage (hvilket er vigtigt i måneder med et tocifret tal).

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

  • Vi danner en streng i ISO-format fra de opnåede værdier ved den sædvanlige tilføjelse af strenge i den passende rækkefølge.

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

Dataene i det resulterende format er antallet af sekunder fra 1970 til et tidspunkt i fremtiden. Det er næsten umuligt at bruge data i det modtagne format i triggere, fordi Zabbix tillader dig kun at arbejde med makroer {Dato} и {Tid}, som returnerer dato og klokkeslæt i et brugervenligt format.

  • Vi kan derefter få den aktuelle dato i JavaScript i Unix Timestamp-format og trække den fra den resulterende certifikatudløbsdato for at få antallet af millisekunder fra nu, indtil certifikatet udløber.

`now = Date.now();`

  • Vi dividerer den modtagne værdi med tusind for at få sekunder i Zabbix.

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

I triggeren kan du angive udtrykket 'sidst' efterfulgt af et sæt cifre, der svarer til det antal sekunder i den periode, du vil svare på, for eksempel i uger. Således vil udløseren give besked om, at certifikatet udløber om en uge.

BEMÆRK. Vær opmærksom på brugen parseInt() i funktion afkastat konvertere det brøktal, der er resultatet af division af millisekunder, til et heltal. Du kan også bruge parseFloat() og gemme fraktioneret data.

Se rapport

Kilde: www.habr.com

Tilføj en kommentar