Kami menyelesaikan masalah praktikal dalam Zabbix menggunakan JavaScript

Kami menyelesaikan masalah praktikal dalam Zabbix menggunakan JavaScript
Tikhon Uskov, jurutera pasukan integrasi Zabbix

Zabbix ialah platform yang boleh disesuaikan yang digunakan untuk memantau sebarang jenis data. Sejak Zabbix versi terawal, pentadbir pemantauan mempunyai keupayaan untuk menjalankan pelbagai skrip melalui Tindakan untuk semakan pada nod rangkaian sasaran. Pada masa yang sama, pelancaran skrip membawa kepada beberapa kesukaran, termasuk seperti keperluan untuk menyokong skrip, penghantarannya kepada nod komunikasi dan proksi, serta sokongan untuk versi yang berbeza.

JavaScript untuk Zabbix

Pada April 2019, Zabbix 4.2 telah diperkenalkan dengan prapemprosesan JavaScript. Ramai orang teruja dengan idea untuk meninggalkan skrip penulisan yang membawa data ke suatu tempat, mencernanya dan menyediakannya dalam format yang difahami oleh Zabbix, dan melakukan pemeriksaan mudah yang akan menerima data yang tidak sedia untuk disimpan dan diproses oleh Zabbix, dan kemudian proses aliran data ini menggunakan alat Zabbix dan JavaScript. Bersempena dengan penemuan peringkat rendah dan item bergantung yang muncul dalam Zabbix 3.4, kami mendapat konsep yang agak fleksibel untuk mengisih dan mengurus data yang diterima.

Dalam Zabbix 4.4, sebagai kesinambungan logik pra-pemprosesan dalam JavaScript, kaedah pemberitahuan baharu telah muncul - Webhook, yang boleh digunakan untuk menyepadukan pemberitahuan Zabbix dengan mudah dengan aplikasi pihak ketiga.

JavaScript dan Duktapes

Mengapakah JavaScript dan Duktape dipilih? Pelbagai pilihan untuk bahasa dan enjin telah dipertimbangkan:

  • Lua - Lua 5.1
  • Lua - LuaJIT
  • Javascript - Duktape
  • JavaScript - JerryScript
  • Python Terbenam
  • Perl Terbenam

Kriteria pemilihan utama adalah kelaziman, kemudahan penyepaduan enjin ke dalam produk, penggunaan sumber yang rendah dan prestasi keseluruhan enjin, dan keselamatan memperkenalkan kod dalam bahasa ini ke dalam pemantauan. Berdasarkan gabungan penunjuk, JavaScript menang pada enjin Duktape.

Kami menyelesaikan masalah praktikal dalam Zabbix menggunakan JavaScript

Kriteria pemilihan dan ujian prestasi

Ciri-ciri Duktape:

- Standard ECMAScript E5/E5.1
- Modul Zabbix untuk Duktape:

  • Zabbix.log() - membolehkan anda menulis mesej dengan tahap perincian yang berbeza terus ke dalam log Pelayan Zabbix, yang memungkinkan untuk mengaitkan ralat, contohnya, dalam Webhook, dengan keadaan pelayan.
  • CurlHttpRequest() - membolehkan anda membuat permintaan HTTP ke rangkaian, yang berasaskan penggunaan Webhook.
  • atob() dan btoa() - membolehkan anda mengekod dan menyahkod rentetan dalam format Base64.

NOTA. Duktape mematuhi piawaian ACME. Zabbix menggunakan skrip versi 2015. Perubahan seterusnya adalah kecil, jadi ia boleh diabaikan..

sihir JavaScript

Semua keajaiban JavaScript terletak pada taip dinamik dan penghantaran taip: rentetan, angka dan boolean.

Ini bermakna tidak perlu mengisytiharkan terlebih dahulu jenis pembolehubah yang harus mengembalikan nilai.

Dalam operasi matematik, nilai yang dikembalikan oleh pengendali fungsi ditukar kepada nombor. Pengecualian kepada operasi sedemikian ialah penambahan, kerana jika sekurang-kurangnya satu daripada istilah ialah rentetan, penukaran rentetan digunakan pada semua istilah.

NOTA. Kaedah yang bertanggungjawab untuk transformasi tersebut biasanya dilaksanakan dalam prototaip induk objek, nilai ΠΈ menjalin. nilai dipanggil semasa penukaran berangka dan sentiasa sebelum kaedah menjalin. Kaedah nilai mesti mengembalikan nilai primitif, jika tidak, hasilnya diabaikan.

Kaedah dipanggil pada objek nilai. Jika ia tidak dijumpai atau tidak mengembalikan nilai primitif, kaedah itu dipanggil menjalin. Jika kaedah menjalin tidak dijumpai, mencari nilai dalam prototaip objek, dan semuanya diulang sehingga pemprosesan nilai selesai dan semua nilai dalam ungkapan dibuang ke jenis yang sama. Jika objek melaksanakan kaedah menjalin, yang mengembalikan nilai primitif, maka ialah yang digunakan untuk penukaran rentetan. Walau bagaimanapun, hasil daripada menggunakan kaedah ini tidak semestinya rentetan.

Sebagai contoh, jika untuk objek 'obj' kaedah ditakrifkan menjalin,

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

Kaedah menjalin mengembalikan dengan tepat rentetan, dan apabila menambah rentetan dengan nombor, kita mendapat rentetan terpaku:

`obj + 1 // '2001'` 

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

Tetapi jika anda menulis semula menjalin, supaya kaedah mengembalikan nombor, apabila objek ditambah, operasi matematik dengan penukaran berangka akan dilakukan dan hasil penambahan matematik akan diperolehi.

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

`obj + 1 // '2001'`

Dalam kes ini, jika kita melakukan penambahan dengan rentetan, penukaran rentetan dilakukan dan kita mendapat rentetan terpaku.

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

Ini adalah sebab untuk sejumlah besar kesilapan oleh pengguna JavaScript pemula.

Cara menjalin anda boleh menulis fungsi yang akan meningkatkan nilai semasa objek sebanyak 1.

Kami menyelesaikan masalah praktikal dalam Zabbix menggunakan JavaScript
Pelaksanaan skrip, dengan syarat pembolehubah adalah sama dengan 3, dan ia juga sama dengan 4.

Apabila dibandingkan dengan pelakon (==), kaedah dilaksanakan setiap kali menjalin dengan fungsi peningkatan nilai. Sehubungan itu, dengan setiap perbandingan seterusnya, nilainya meningkat. Ini boleh dielakkan dengan menggunakan perbandingan bukan tuang (===).

Kami menyelesaikan masalah praktikal dalam Zabbix menggunakan JavaScript
Perbandingan tanpa tuangan jenis

NOTA. Jangan Gunakan Perbandingan Cast Tanpa Perlu.

Untuk skrip kompleks, seperti Webhooks dengan logik kompleks, yang memerlukan perbandingan dengan penghantaran jenis, adalah disyorkan untuk pra-menulis semakan untuk nilai yang mengembalikan pembolehubah dan mengendalikan ketidakkonsistenan dan ralat.

Media Webhook

Pada akhir 2019 dan awal 2020, pasukan penyepaduan Zabbix telah secara aktif membangunkan Webhooks dan penyepaduan luar kotak yang disertakan dengan pengedaran Zabbix.

Kami menyelesaikan masalah praktikal dalam Zabbix menggunakan JavaScript
Pautan ke dokumentasi

Pemprosesan Pra

  • Kemunculan prapemprosesan dalam JavaScript memungkinkan untuk meninggalkan kebanyakan skrip luaran, dan pada masa ini dalam Zabbix anda boleh mendapatkan sebarang nilai dan menukarnya kepada nilai yang sama sekali berbeza.
  • Prapemprosesan dalam Zabbix dilaksanakan oleh kod JavaScript, yang, apabila disusun menjadi bytecode, ditukar menjadi fungsi yang mengambil satu nilai sebagai parameter nilai sebagai rentetan (rentetan boleh mengandungi kedua-dua digit dan nombor).
  • Oleh kerana output adalah fungsi, pada akhir skrip diperlukan pulangan.
  • Anda boleh menggunakan makro tersuai dalam kod.
  • Sumber boleh dihadkan bukan sahaja pada peringkat sistem pengendalian, tetapi juga secara pengaturcaraan. Langkah prapemprosesan diperuntukkan maksimum 10 megabait RAM dan had masa larian selama 10 saat.

Kami menyelesaikan masalah praktikal dalam Zabbix menggunakan JavaScript

NOTA. Nilai tamat masa 10 saat adalah agak banyak, kerana mengumpul beribu-ribu item data bersyarat dalam 1 saat mengikut senario prapemprosesan yang agak "berat" boleh melambatkan Zabbix. Oleh itu, adalah tidak disyorkan untuk menggunakan prapemprosesan untuk melaksanakan skrip JavaScript sepenuhnya melalui apa yang dipanggil elemen data bayangan (item dummy), yang dijalankan hanya untuk melaksanakan prapemprosesan..

Anda boleh menyemak kod anda melalui ujian prapemprosesan atau menggunakan utiliti 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`

Tugasan praktikal

Petugas 1

Gantikan item yang dikira dengan prapemprosesan.

Keadaan: Dapatkan suhu dalam Fahrenheit daripada penderia untuk disimpan dalam Celsius.

Sebelum ini, kami akan mencipta item yang mengumpul suhu dalam darjah Fahrenheit. Selepas itu, item data lain (dikira) yang akan menukar Fahrenheit kepada Celsius menggunakan formula.

Masalah:

  • Adalah perlu untuk menduplikasi elemen data dan menyimpan semua nilai dalam pangkalan data.
  • Anda mesti bersetuju dengan selang untuk item data "ibu bapa" yang dikira dan digunakan dalam formula, dan untuk item data yang dikira. Jika tidak, item yang dikira mungkin berada dalam keadaan tidak disokong atau mengira nilai sebelumnya, yang akan menjejaskan kebolehpercayaan hasil pemantauan.

Satu penyelesaian adalah untuk beralih daripada selang semakan fleksibel yang memihak kepada selang tetap untuk memastikan item yang dikira dinilai selepas item yang menerima data (dalam kes kami, suhu dalam darjah Fahrenheit).

Tetapi jika, sebagai contoh, kami menggunakan templat untuk menyemak sejumlah besar peranti, dan pemeriksaan dilakukan sekali setiap 30 saat, Zabbix "menggoda" selama 29 saat, dan pada saat terakhir ia mula menyemak dan mengira. Ini mewujudkan baris gilir dan menjejaskan prestasi. Oleh itu, adalah disyorkan untuk menggunakan selang tetap hanya jika ia benar-benar perlu.

Dalam masalah ini, penyelesaian optimum ialah prapemprosesan JavaScript satu baris yang menukar darjah Fahrenheit kepada darjah Celsius:

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

Ia pantas dan mudah, anda tidak perlu mencipta item data yang tidak perlu dan menyimpan sejarah pada item tersebut, dan anda juga boleh menggunakan selang yang fleksibel untuk semakan.

Kami menyelesaikan masalah praktikal dalam Zabbix menggunakan JavaScript

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

Tetapi, jika dalam situasi hipotesis adalah perlu untuk menambah elemen data yang diterima, sebagai contoh, dengan sebarang pemalar yang ditakrifkan dalam makro, ia mesti diambil kira bahawa parameter nilai mengembang menjadi rentetan. Dalam operasi penambahan rentetan, dua rentetan digabungkan menjadi satu.

Kami menyelesaikan masalah praktikal dalam Zabbix menggunakan JavaScript

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

Untuk mendapatkan hasil operasi matematik, adalah perlu untuk menukar jenis nilai yang diperoleh kepada format angka. Untuk ini anda boleh menggunakan fungsi parseInt(), yang menghasilkan integer, fungsi parseFloat(), yang menghasilkan perpuluhan, atau fungsi nombor, yang mengembalikan integer atau perpuluhan.

Tugasan 2

Dapatkan masa dalam beberapa saat sehingga tamat sijil.

Keadaan: perkhidmatan mengeluarkan tarikh tamat tempoh sijil dalam format "12 Feb 12:33:56 2022 GMT".

Dalam ECMAScript5 date.parse() menerima tarikh dalam format ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ). Ia perlu menghantar rentetan kepadanya dalam format MMM DD YYYY HH:mm:ss ZZ

masalah: Nilai bulan dinyatakan sebagai teks, bukan sebagai nombor. Data dalam format ini tidak diterima oleh Duktape.

Contoh Penyelesaian:

  • Pertama sekali, pembolehubah diisytiharkan yang mengambil nilai (keseluruhan skrip ialah pengisytiharan pembolehubah yang disenaraikan dipisahkan dengan koma).

  • Dalam baris pertama kita mendapat tarikh dalam parameter nilai dan asingkan dengan ruang menggunakan kaedah berpecah. Oleh itu, kita mendapat tatasusunan, di mana setiap elemen tatasusunan, bermula pada indeks 0, sepadan dengan satu elemen tarikh sebelum dan selepas ruang. belah(0) - bulan, belah(1) - nombor, belah(2) - rentetan dengan masa, dsb. Selepas itu, setiap elemen tarikh boleh diakses oleh indeks dalam tatasusunan.

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

  • Setiap bulan (dalam susunan kronologi) sepadan dengan indeks kedudukannya dalam tatasusunan (dari 0 hingga 11). Untuk menukar nilai teks kepada nilai angka, satu ditambahkan pada indeks bulan (kerana bulan dinomborkan bermula pada 1). Dalam kes ini, ungkapan dengan penambahan satu diambil dalam kurungan, kerana jika tidak, rentetan akan diperoleh, bukan nombor. Pada akhirnya kita lakukan kepingan () - potong tatasusunan dari hujung untuk meninggalkan hanya dua aksara (yang penting untuk bulan dengan nombor dua digit).

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

  • Kami membentuk rentetan dalam format ISO daripada nilai yang diperoleh dengan penambahan rentetan biasa dalam susunan yang sesuai.

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

Data dalam format yang terhasil ialah bilangan saat dari 1970 hingga beberapa titik pada masa hadapan. Hampir mustahil untuk menggunakan data dalam format yang diterima dalam pencetus, kerana Zabbix membenarkan anda untuk beroperasi hanya dengan makro {Tarikh} ΠΈ {Masa}, yang mengembalikan tarikh dan masa dalam format yang mesra pengguna.

  • Kami kemudiannya boleh mendapatkan tarikh semasa dalam JavaScript dalam format Unix Timestamp dan menolaknya daripada tarikh tamat tempoh sijil yang terhasil untuk mendapatkan bilangan milisaat dari sekarang sehingga sijil tamat tempoh.

`now = Date.now();`

  • Kami membahagikan nilai yang diterima dengan seribu untuk mendapatkan saat dalam Zabbix.

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

Dalam pencetus, anda boleh menentukan ungkapan 'terakhir' diikuti dengan set digit yang sepadan dengan bilangan saat dalam tempoh yang anda mahu balas, contohnya, dalam beberapa minggu. Oleh itu, pencetus akan memberitahu bahawa sijil tamat tempoh dalam seminggu.

NOTA. Perhatikan penggunaannya parseInt() dalam fungsi pulanganuntuk menukar nombor pecahan yang terhasil daripada pembahagian milisaat kepada integer. Anda juga boleh menggunakan parseFloat() dan menyimpan data pecahan.

Tonton laporan

Sumber: www.habr.com

Tambah komen