Решаваме практически проблеми в Zabbix с помощта на JavaScript

Решаваме практически проблеми в Zabbix с помощта на JavaScript
Тихон Усков, инженер на екипа за интеграция на Zabbix

Zabbix е адаптивна платформа, която се използва за наблюдение на всякакъв вид данни. От най-ранните версии на Zabbix администраторите за мониторинг са имали възможността да изпълняват различни скриптове чрез Действия за проверки на целеви мрежови възли. В същото време стартирането на скриптове доведе до редица трудности, включително необходимостта от поддръжка на скриптове, доставката им до комуникационни възли и проксита, както и поддръжка за различни версии.

JavaScript за Zabbix

През април 2019 г. Zabbix 4.2 беше представен с предварителна обработка на JavaScript. Много хора се развълнуваха от идеята да изоставят писането на скриптове, които вземат данни някъде, усвояват ги и ги предоставят във формат, който Zabbix разбира, и извършват прости проверки, които ще получат данни, които не са готови за съхранение и обработка от Zabbix, и след това обработете този поток от данни с помощта на Zabbix и JavaScript инструменти. Във връзка с откриването на ниско ниво и зависимите елементи, които се появиха в Zabbix 3.4, получихме доста гъвкава концепция за сортиране и управление на получените данни.

В Zabbix 4.4, като логично продължение на предварителната обработка в JavaScript, се появи нов метод за уведомяване - Webhook, който може да се използва за лесно интегриране на Zabbix известия с приложения на трети страни.

JavaScript и Duktapes

Защо бяха избрани JavaScript и Duktape? Бяха разгледани различни опции за езици и двигатели:

  • Lua - Lua 5.1
  • Lua - LuaJIT
  • Javascript - Duktape
  • Javascript - JerryScript
  • Вграден Python
  • Вграден Perl

Основните критерии за избор бяха разпространение, лекота на интегриране на двигателя в продукта, ниска консумация на ресурси и цялостна производителност на двигателя, както и безопасността на въвеждане на код на този език в мониторинга. Въз основа на комбинацията от индикатори, JavaScript спечели на двигателя Duktape.

Решаваме практически проблеми в Zabbix с помощта на JavaScript

Критерии за подбор и тестване на ефективността

Характеристики на Duktape:

— Стандартно ECMAScript E5/E5.1
— Zabbix модули за Duktape:

  • Zabbix.log() - позволява ви да пишете съобщения с различни нива на детайлност директно в регистъра на Zabbix сървъра, което прави възможно свързването на грешки, например в Webhook, със състоянието на сървъра.
  • CurlHttpRequest() - позволява ви да правите HTTP заявки към мрежата, на които се базира използването на Webhook.
  • atob() и btoa() - позволява ви да кодирате и декодирате низове във формат Base64.

ЗАБЕЛЕЖКА. Duktape отговаря на стандартите ACME. Zabbix използва версията от 2015 г. на скрипта. Последващите промени са незначителни, така че могат да бъдат пренебрегнати..

JavaScript магия

Цялата магия на JavaScript се крие в динамичното въвеждане и преобразуването на типове: низови, числови и булеви.

Това означава, че не е необходимо да се декларира предварително какъв тип променливата трябва да върне стойност.

При математическите операции стойностите, върнати от функционалните оператори, се преобразуват в числа. Изключение от такива операции е добавянето, защото ако поне един от термините е низ, преобразуването на низове се прилага към всички термини.

ЗАБЕЛЕЖКА. Методите, отговорни за такива трансформации, обикновено се изпълняват в родителските прототипи на обекта, стойност на и toString. стойност на извиква се по време на числово преобразуване и винаги преди метода toString. Метод стойност на трябва да върне примитивни стойности, в противен случай резултатът му се игнорира.

Извиква се метод на обект стойност на. Ако не бъде намерен или не върне примитивна стойност, методът се извиква toString. Ако методът toString не е намерено, търси се стойност на в прототипа на обекта и всичко се повтаря, докато обработката на стойността приключи и всички стойности в израза се прехвърлят към същия тип. Ако обектът имплементира метод toString, който връща примитивна стойност, тогава тя се използва за преобразуване на низ. Резултатът от прилагането на този метод обаче не е непременно низ.

Например, ако за за обект 'OBJ' е дефиниран метод toString,

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

метод toString връща точно низ и при добавяне на низ с число получаваме слепен низ:

`obj + 1 // '2001'` 

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

Но ако пренапишете toString, така че методът да върне число, когато обектът бъде добавен, ще бъде извършена математическа операция с числово преобразуване и ще бъде получен резултатът от математическото събиране.

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

`obj + 1 // '2001'`

В този случай, ако извършим добавяне с низ, се извършва преобразуване на низ и получаваме слепен низ.

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

Това е причината за голям брой грешки от начинаещи потребители на JavaScript.

Методът toString можете да напишете функция, която ще увеличи текущата стойност на обекта с 1.

Решаваме практически проблеми в Zabbix с помощта на JavaScript
Изпълнение на скрипта, при условие че променливата е равна на 3 и също е равна на 4.

Когато се сравнява с каст (==), методът се изпълнява всеки път toString с функция за увеличаване на стойността. Съответно с всяко следващо сравнение стойността се увеличава. Това може да се избегне чрез използване на несравнено сравнение (===).

Решаваме практически проблеми в Zabbix с помощта на JavaScript
Сравнение без преобразуване на типа

ЗАБЕЛЕЖКА. Не използвайте ненужно сравнение на актьори.

За сложни скриптове, като Webhooks със сложна логика, които изискват сравнение с преобразуване на типове, се препоръчва предварително да напишете проверки за стойностите, които връщат променливи и обработват несъответствия и грешки.

Webhook Media

В края на 2019 г. и началото на 2020 г. екипът за интегриране на Zabbix активно разработва Webhooks и готови интеграции, които идват с дистрибуцията на Zabbix.

Решаваме практически проблеми в Zabbix с помощта на JavaScript
Връзка към документация

Предварителна обработка

  • Появата на предварителната обработка в JavaScript направи възможно изоставянето на повечето външни скриптове и в момента в Zabbix можете да получите всяка стойност и да я конвертирате в напълно различна стойност.
  • Предварителната обработка в Zabbix се изпълнява от JavaScript код, който, когато се компилира в байт код, се преобразува във функция, която приема една стойност като параметър стойност като низ (низът може да съдържа както цифра, така и число).
  • Тъй като изходът е функция, в края на скрипта се изисква връщане.
  • Възможно е да използвате персонализирани макроси в кода.
  • Ресурсите могат да бъдат ограничени не само на ниво операционна система, но и програмно. На стъпката на предварителна обработка се разпределят максимум 10 мегабайта RAM и ограничение на времето за изпълнение от 10 секунди.

Решаваме практически проблеми в Zabbix с помощта на JavaScript

ЗАБЕЛЕЖКА. Стойността на изчакване от 10 секунди е доста голяма, защото събирането на условни хиляди елементи от данни за 1 секунда според доста „тежък“ сценарий на предварителна обработка може да забави Zabbix. Поради това не се препоръчва използването на предварителна обработка за изпълнение на пълноценни JavaScript скриптове чрез така наречените сенчести елементи от данни (фиктивни елементи), които се изпълняват само за извършване на предварителна обработка.

Можете да проверите кода си чрез теста за предварителна обработка или с помощта на помощната програма 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`

Практически задачи

Задача 1

Заменете изчисления елемент с предварителна обработка.

Състояние: Вземете температурата във Фаренхайт от сензора, за да я съхраните в Целзий.

Преди това щяхме да създадем елемент, който събира температурата в градуси по Фаренхайт. След това друг елемент от данни (изчислен), който ще преобразува Фаренхайт в Целзий с помощта на формула.

Проблеми:

  • Необходимо е да се дублират елементи от данни и да се съхраняват всички стойности в базата данни.
  • Трябва да се споразумеете за интервалите за "родителския" елемент от данни, който се изчислява и използва във формулата, и за изчисления елемент от данни. В противен случай изчисленият елемент може да премине в неподдържано състояние или да изчисли предишна стойност, което ще повлияе на надеждността на резултатите от мониторинга.

Едно решение беше да се отдалечим от гъвкавите интервали на проверка в полза на фиксираните интервали, за да гарантираме, че изчисленият елемент се оценява след елемента, който получава данните (в нашия случай температурата в градуси по Фаренхайт).

Но ако например използваме шаблона за проверка на голям брой устройства и проверката се извършва веднъж на всеки 30 секунди, Zabbix "хаква" за 29 секунди и в последната секунда започва да проверява и изчислява. Това създава опашка и засяга производителността. Поради това се препоръчва използването на фиксирани интервали само ако наистина е необходимо.

В този проблем оптималното решение е предварителна обработка на JavaScript в един ред, която преобразува градуси по Фаренхайт в градуси по Целзий:

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

Бързо и лесно е, не е необходимо да създавате ненужни елементи от данни и да поддържате история за тях, а също така можете да използвате гъвкави интервали за проверки.

Решаваме практически проблеми в Zabbix с помощта на JavaScript

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

Но ако в хипотетична ситуация е необходимо да добавите получения елемент от данни, например, с която и да е константа, дефинирана в макроса, трябва да се има предвид, че параметърът стойност разширява се в низ. При операция за добавяне на низове два низа просто се комбинират в един.

Решаваме практически проблеми в Zabbix с помощта на JavaScript

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

За да получите резултата от математическа операция, е необходимо да преобразувате типовете получени стойности в цифров формат. За целта можете да използвате функцията parseInt(), което произвежда цяло число, функция parseFloat(), което произвежда десетичен знак или функция брой, който връща цяло число или десетичен знак.

Проблем 2

Получете времето в секунди до края на сертификата.

Състояние: услуга издава дата на валидност на сертификата във формат „12 февруари 12:33:56 2022 GMT“.

В ECMAScript5 date.parse() приема дата във формат ISO 8601 (ГГГГ-ММ-ДДТЧЧ:мм:сс.ссссZ). Необходимо е да го кастнете низ във формат MMM DD YYYY HH:mm:ss ZZ

проблем: Месечната стойност се изразява като текст, а не като число. Данните в този формат не се приемат от Duktape.

Пример за решение:

  • Първо се декларира променлива, която приема стойност (целият скрипт е декларация на променливи, които са изброени разделени със запетаи).

  • В първия ред получаваме датата в параметъра стойност и го отделете с интервали, като използвате метода разделят. Така получаваме масив, в който всеки елемент от масива, започващ от индекс 0, отговаря на един елемент от дата преди и след интервал. разделяне (0) - месец, разделяне (1) - номер, разделяне (2) - низ с време и т.н. След това всеки елемент от датата може да бъде достъпен по индекс в масива.

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

  • Всеки месец (в хронологичен ред) отговаря на индекса на позицията си в масива (от 0 до 11). За да преобразувате текстова стойност в числова стойност, единица се добавя към индекса на месеца (тъй като месеците се номерират, започвайки от 1). В този случай изразът с добавяне на единица се взема в скоби, защото в противен случай ще се получи низ, а не число. Накрая го правим резен() - изрежете масива от края, за да оставите само два знака (което е важно за месеци с двуцифрено число).

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

  • Формираме низ във формат ISO от получените стойности чрез обичайното добавяне на низове в съответния ред.

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

Данните в получения формат са броят секунди от 1970 г. до някакъв момент в бъдещето. Почти невъзможно е да използвате данни в получения формат в тригери, тъй като Zabbix ви позволява да работите само с макроси {Дата} и {Time}, които връщат датата и часа в удобен за потребителя формат.

  • След това можем да получим текущата дата в JavaScript във формат Unix Timestamp и да я извадим от получената дата на изтичане на сертификата, за да получим броя милисекунди от сега до изтичането на сертификата.

`now = Date.now();`

  • Разделяме получената стойност на хиляда, за да получим секунди в Zabbix.

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

В тригера можете да посочите израза 'последно', последвано от набор от цифри, който съответства на броя секунди в периода, на който искате да отговорите, например в седмици. По този начин тригерът ще уведоми, че сертификатът изтича след седмица.

ЗАБЕЛЕЖКА. Обърнете внимание на употребата parseInt() във функция връщанеза преобразуване на дробното число, получено от деленето на милисекунди, в цяло число. Можете също да използвате parseFloat() и съхранявайте частични данни.

Гледайте репортаж

Източник: www.habr.com

Добавяне на нов коментар