Vi løser praktiske problemer i Zabbix ved hjelp av JavaScript

Vi løser praktiske problemer i Zabbix ved hjelp av JavaScript
Tikhon Uskov, Zabbix integreringsteamingeniør

Zabbix er en tilpassbar plattform som brukes til å overvåke alle typer data. Siden de tidligste versjonene av Zabbix har overvåkingsadministratorer hatt muligheten til å kjøre ulike skript via handlinger for kontroller på målnettverksnoder. Samtidig førte lanseringen av skript til en rekke vanskeligheter, inkludert behovet for å støtte skript, levering til kommunikasjonsnoder og proxyer, samt støtte for ulike versjoner.

JavaScript for Zabbix

I april 2019 ble Zabbix 4.2 introdusert med JavaScript-forbehandling. Mange ble begeistret for ideen om å forlate å skrive skript som tar data et sted, fordøye dem og gi dem i et format som Zabbix forstår, og utføre enkle kontroller som vil motta data som ikke er klare for lagring og behandling av Zabbix, og behandle deretter denne datastrømmen ved hjelp av Zabbix- og JavaScript-verktøy. I forbindelse med lavnivåfunn og avhengige elementer som dukket opp i Zabbix 3.4, fikk vi et ganske fleksibelt konsept for sortering og administrasjon av mottatte data.

I Zabbix 4.4, som en logisk fortsettelse av forhåndsbehandling i JavaScript, har det dukket opp en ny varslingsmetode – Webhook, som kan brukes til enkelt å integrere Zabbix-varslinger med tredjepartsapplikasjoner.

JavaScript og Duktapes

Hvorfor ble JavaScript og Duktape valgt? Ulike alternativer for språk og motorer ble vurdert:

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

De viktigste utvalgskriteriene var utbredelse, enkel integrering av motoren i produktet, lavt ressursforbruk og generell ytelse til motoren, og sikkerheten ved å introdusere kode på dette språket i overvåking. Basert på kombinasjonen av indikatorer vant JavaScript på Duktape-motoren.

Vi løser praktiske problemer i Zabbix ved hjelp av JavaScript

Utvalgskriterier og ytelsestesting

Funksjoner til Duktape:

— Standard ECMAScript E5/E5.1
— Zabbix-moduler for Duktape:

  • Zabbix.log() – lar deg skrive meldinger med ulike detaljnivåer direkte inn i Zabbix Server-loggen, noe som gjør det mulig å korrelere feil, for eksempel i en Webhook, med servertilstanden.
  • CurlHttpRequest() - lar deg lage HTTP-forespørsler til nettverket som bruken av Webhook er basert på.
  • atob() og btoa() - lar deg kode og dekode strenger i Base64-format.

NOTE. Duktape overholder ACME-standarder. Zabbix bruker 2015-versjonen av manuset. Etterfølgende endringer er mindre, så de kan ignoreres..

JavaScript-magi

All magien til JavaScript ligger i dynamisk skriving og typecasting: streng, numerisk og boolsk.

Dette betyr at det ikke er nødvendig å deklarere på forhånd hvilken type variabelen skal returnere en verdi.

I matematiske operasjoner blir verdiene som returneres av funksjonsoperatører konvertert til tall. Unntaket fra slike operasjoner er tillegg, fordi hvis minst ett av termene er en streng, brukes strengkonvertering på alle termer.

NOTE. Metodene som er ansvarlige for slike transformasjoner er vanligvis implementert i objektets overordnede prototyper, verdien av и tilString. verdien av kalles under numerisk konvertering og alltid før metoden tilString. Metode verdien av må returnere primitive verdier, ellers blir resultatet ignorert.

En metode kalles på et objekt verdien av. Hvis den ikke blir funnet eller ikke returnerer en primitiv verdi, kalles metoden tilString. Hvis metoden tilString ikke funnet, søker verdien av i prototypen til objektet, og alt gjentas til behandlingen av verdien er fullført og alle verdiene i uttrykket er støpt til samme type. Hvis objektet implementerer en metode tilString, som returnerer en primitiv verdi, så er det den som brukes til strengkonvertering. Resultatet av å bruke denne metoden er imidlertid ikke nødvendigvis en streng.

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

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

метод tilString returnerer nøyaktig en streng, og når vi legger til en streng med et tall, får vi en limt streng:

`obj + 1 // '2001'` 

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

Men hvis du skriver om tilString, slik at metoden returnerer et tall, når objektet legges til, vil en matematisk operasjon med en numerisk konvertering bli utført og resultatet av matematisk addisjon vil bli oppnådd.

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

`obj + 1 // '2001'`

I dette tilfellet, hvis vi utfører addisjon med en streng, utføres en strengkonvertering, og vi får en limt streng.

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

Dette er grunnen til et stort antall feil fra nybegynnere av JavaScript-brukere.

Metoden tilString du kan skrive en funksjon som vil øke gjeldende verdi av objektet med 1.

Vi løser praktiske problemer i Zabbix ved hjelp av JavaScript
Utførelse av skriptet, forutsatt at variabelen er lik 3, og den er også lik 4.

Sammenlignet med en rollebesetning (==), utføres metoden hver gang tilString med verdiøkningsfunksjon. Følgelig, med hver påfølgende sammenligning, øker verdien. Dette kan unngås ved å bruke ikke-cast sammenligning (===).

Vi løser praktiske problemer i Zabbix ved hjelp av JavaScript
Sammenligning uten typestøping

NOTE. Ikke bruk rollebesetningssammenligning unødvendig.

For komplekse skript, som Webhooks med kompleks logikk, som krever sammenligning med typecasting, anbefales det å forhåndsskrive sjekker for verdiene som returnerer variabler og håndterer inkonsekvenser og feil.

Webhook Media

På slutten av 2019 og begynnelsen av 2020 har Zabbix-integrasjonsteamet aktivt utviklet Webhooks og ut-av-boksen integrasjoner som følger med Zabbix-distribusjonen.

Vi løser praktiske problemer i Zabbix ved hjelp av JavaScript
Link til dokumentasjon

forbehandling

  • Fremkomsten av forbehandling i JavaScript gjorde det mulig å forlate de fleste eksterne skript, og for øyeblikket i Zabbix kan du få hvilken som helst verdi og konvertere den til en helt annen verdi.
  • Forbehandling i Zabbix er implementert av JavaScript-kode, som, når den kompileres til bytekode, konverteres til en funksjon som tar en enkelt verdi som parameter verdi som en streng (en streng kan inneholde både et siffer og et tall).
  • Siden utdata er en funksjon, kreves det på slutten av skriptet retur.
  • Det er mulig å bruke egendefinerte makroer i koden.
  • Ressurser kan begrenses ikke bare på operativsystemnivå, men også programmatisk. Forbehandlingstrinnet er tildelt maksimalt 10 megabyte RAM og en kjøretid på 10 sekunder.

Vi løser praktiske problemer i Zabbix ved hjelp av JavaScript

NOTE. Tidsavbruddsverdien på 10 sekunder er ganske mye, fordi å samle betingede tusenvis av dataelementer på 1 sekund i henhold til et ganske "tungt" forbehandlingsscenario kan bremse Zabbix. Derfor anbefales det ikke å bruke forhåndsbehandling for å utføre fullverdige JavaScript-skript gjennom de såkalte skyggedataelementene (dummy-elementer), som kjøres kun for å utføre forhåndsbehandling.

Du kan sjekke koden din gjennom forbehandlingstesten eller ved å bruke verktøyet 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 oppgaver

Oppgave 1

Bytt ut beregnet vare med forbehandling.

Tilstand: Få temperaturen i Fahrenheit fra sensoren for å lagre i Celsius.

Tidligere ville vi laget et element som samler temperaturen i grader Fahrenheit. Etter det, et annet dataelement (beregnet) som ville konvertere Fahrenheit til Celsius ved hjelp av en formel.

Problemer:

  • Det er nødvendig å duplisere dataelementer og lagre alle verdier i databasen.
  • Du må avtale intervallene for "overordnet" dataelement som beregnes og brukes i formelen, og for det beregnede dataelementet. Ellers kan det beregnede elementet gå inn i en tilstand som ikke støttes eller beregne en tidligere verdi, noe som vil påvirke påliteligheten til overvåkingsresultatene.

En løsning var å gå bort fra fleksible kontrollintervaller til fordel for faste intervaller for å sikre at den beregnede varen blir evaluert etter varen som mottar dataene (i vårt tilfelle temperaturen i grader Fahrenheit).

Men hvis vi for eksempel bruker malen til å sjekke et stort antall enheter, og kontrollen utføres en gang hvert 30. sekund, "hakker" Zabbix i 29 sekunder, og i siste sekund begynner den å sjekke og regne. Dette skaper en kø og påvirker ytelsen. Derfor anbefales det å bruke faste intervaller kun hvis det virkelig er nødvendig.

I dette problemet er den optimale løsningen en énlinjes JavaScript-forbehandling som konverterer grader Fahrenheit til grader Celsius:

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

Det er raskt og enkelt, du trenger ikke lage unødvendige dataelementer og føre historikk på dem, og du kan også bruke fleksible intervaller for kontroller.

Vi løser praktiske problemer i Zabbix ved hjelp av JavaScript

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

Men hvis det i en hypotetisk situasjon er nødvendig å legge til det mottatte dataelementet, for eksempel med en konstant definert i makroen, må det tas i betraktning at parameteren verdi utvides til en streng. I en strengtilleggsoperasjon kombineres to strenger ganske enkelt til én.

Vi løser praktiske problemer i Zabbix ved hjelp av JavaScript

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

For å oppnå resultatet av en matematisk operasjon, er det nødvendig å konvertere typene av de oppnådde verdiene til et numerisk format. Til dette kan du bruke funksjonen parseInt(), som produserer et heltall, en funksjon parseFloat(), som produserer en desimal eller en funksjon Antall, som returnerer et heltall eller desimal.

Oppgave 2

Få tiden i sekunder til slutten av sertifikatet.

Tilstand: en tjeneste utsteder en utløpsdato for sertifikatet i formatet "12. feb 12:33:56 2022 GMT".

I ECMAScript5 Date.parse () godtar en dato i ISO 8601-format (ÅÅÅÅ-MM-DDTHH:mm:ss.sssZ). Det er nødvendig å kaste en streng til den i formatet MMM DD ÅÅÅÅ TT:mm:ss ZZ

problem: Månedsverdien uttrykkes som tekst, ikke som et tall. Data i dette formatet godtas ikke av Duktape.

Eksempel på løsning:

  • Først av alt er en variabel deklarert som tar en verdi (hele skriptet er en erklæring av variabler som er oppført atskilt med komma).

  • I første linje får vi datoen i parameteren verdi og skille den med mellomrom ved hjelp av metoden splittet. Dermed får vi en matrise, der hvert element i matrisen, som starter ved indeks 0, tilsvarer ett datoelement før og etter et mellomrom. delt(0) - måned, delt(1) - Antall, delt(2) - en streng med tid, osv. Etter det kan hvert element i datoen nås med indeks i matrisen.

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

  • Hver måned (i kronologisk rekkefølge) tilsvarer indeksen for sin posisjon i matrisen (fra 0 til 11). For å konvertere en tekstverdi til en numerisk verdi, legges en til månedsindeksen (fordi måneder er nummerert fra 1). I dette tilfellet er uttrykket med tillegg av en tatt i parentes, fordi ellers vil en streng fås, ikke et tall. På slutten gjør vi det skjære() - kutt matrisen fra slutten for å la bare to tegn være igjen (noe som er viktig for måneder med et tosifret tall).

`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 oppnådde verdiene ved vanlig tilsetning av strenger i riktig rekkefølge.

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

Dataene i det resulterende formatet er antall sekunder fra 1970 til et tidspunkt i fremtiden. Det er nesten umulig å bruke data i det mottatte formatet i triggere, fordi Zabbix lar deg kun operere med makroer {Dato} и {Tid}, som returnerer dato og klokkeslett i et brukervennlig format.

  • Vi kan deretter få gjeldende dato i JavaScript i Unix Timestamp-format og trekke den fra den resulterende sertifikatutløpsdatoen for å få antall millisekunder fra nå til sertifikatet utløper.

`now = Date.now();`

  • Vi deler den mottatte verdien med tusen for å få sekunder i Zabbix.

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

I utløseren kan du spesifisere uttrykket 'siste' etterfulgt av et sett med sifre som tilsvarer antall sekunder i perioden du ønsker å svare på, for eksempel i uker. Dermed vil utløseren varsle om at sertifikatet utløper om en uke.

NOTE. Vær oppmerksom på bruken parseInt() i funksjon returå konvertere brøktallet som følge av deling av millisekunder til et heltall. Du kan også bruke parseFloat() og lagre brøkdata.

Se reportasje

Kilde: www.habr.com

Legg til en kommentar