Kami memecahkan masalah praktis di Zabbix menggunakan JavaScript

Kami memecahkan masalah praktis di Zabbix menggunakan JavaScript
Tikhon Uskov, insinyur tim integrasi Zabbix

Zabbix adalah platform yang dapat disesuaikan yang digunakan untuk memantau segala jenis data. Sejak versi awal Zabbix, administrator pemantauan memiliki kemampuan untuk menjalankan berbagai skrip melalui tindakan untuk pemeriksaan pada node jaringan target. Pada saat yang sama, peluncuran skrip menyebabkan sejumlah kesulitan, termasuk kebutuhan untuk mendukung skrip, pengirimannya ke node komunikasi dan proxy, serta dukungan untuk versi yang berbeda.

JavaScript untuk Zabbix

Pada April 2019, Zabbix 4.2 diperkenalkan dengan JavaScript preprocessing. Banyak orang bersemangat dengan ide meninggalkan skrip penulisan yang mengambil data di suatu tempat, mencernanya, dan menyediakannya dalam format yang dipahami Zabbix, dan melakukan pemeriksaan sederhana yang akan menerima data yang belum siap untuk disimpan dan diproses oleh Zabbix, dan lalu proses aliran data ini menggunakan alat Zabbix dan JavaScript. Sehubungan dengan penemuan tingkat rendah dan item dependen yang muncul di Zabbix 3.4, kami mendapatkan konsep yang cukup fleksibel untuk menyortir dan mengelola data yang diterima.

Di Zabbix 4.4, sebagai kelanjutan logis dari pra-pemrosesan dalam JavaScript, metode notifikasi baru telah muncul - Webhook, yang dapat digunakan untuk mengintegrasikan notifikasi Zabbix dengan mudah dengan aplikasi pihak ketiga.

JavaScript dan Duktapes

Mengapa JavaScript dan Duktape dipilih? Berbagai opsi untuk bahasa dan mesin dipertimbangkan:

  • Lua - Lua 5.1
  • Lua - LuaJIT
  • Javascript - Duktape
  • Javascript - JerryScript
  • Python tertanam
  • Perl . Tertanam

Kriteria pemilihan utama adalah prevalensi, kemudahan integrasi mesin ke dalam produk, konsumsi sumber daya yang rendah dan kinerja mesin secara keseluruhan, dan keamanan memasukkan kode dalam bahasa ini ke dalam pemantauan. Berdasarkan kombinasi indikator, JavaScript menang di mesin Duktape.

Kami memecahkan masalah praktis di Zabbix menggunakan JavaScript

Kriteria seleksi dan pengujian kinerja

Fitur Duktape:

β€” Standar Skrip ECMA E5/E5.1
- Modul Zabbix untuk Duktape:

  • Zabbix.log() - memungkinkan Anda menulis pesan dengan berbagai tingkat detail langsung ke log Server Zabbix, yang memungkinkan untuk membandingkan kesalahan, misalnya, di Webhook, dengan status server.
  • CurlHttpRequest() - memungkinkan Anda membuat permintaan HTTP ke jaringan, yang menjadi dasar penggunaan Webhook.
  • atob() dan btoa() - memungkinkan Anda untuk menyandikan dan mendekode string dalam format Base64.

CATATAN. Duktape mematuhi standar ACME. Zabbix menggunakan skrip versi 2015. Perubahan selanjutnya kecil, sehingga dapat diabaikan..

keajaiban JavaScript

Semua keajaiban JavaScript terletak pada pengetikan dinamis dan pengecoran tipe: string, numerik, dan boolean.

Ini berarti bahwa tidak perlu mendeklarasikan terlebih dahulu jenis variabel apa yang harus mengembalikan nilai.

Dalam operasi matematika, nilai yang dikembalikan oleh operator fungsi diubah menjadi angka. Pengecualian untuk operasi tersebut adalah penjumlahan, karena jika setidaknya salah satu suku adalah string, konversi string diterapkan ke semua suku.

CATATAN. Metode yang bertanggung jawab untuk transformasi semacam itu biasanya diimplementasikan dalam prototipe induk objek, Nilai dari ΠΈ keString. Nilai dari dipanggil selama konversi numerik dan selalu sebelum metode keString. metode Nilai dari harus mengembalikan nilai primitif, jika tidak hasilnya akan diabaikan.

Metode dipanggil pada objek Nilai dari. Jika tidak ditemukan atau tidak mengembalikan nilai primitif, metode ini dipanggil keString. Jika metode keString tidak ditemukan, mencari Nilai dari dalam prototipe objek, dan semuanya diulang sampai pemrosesan nilai selesai dan semua nilai dalam ekspresi dilemparkan ke tipe yang sama. Jika objek mengimplementasikan metode keString, yang mengembalikan nilai primitif, maka itu yang digunakan untuk konversi string. Namun, hasil penerapan metode ini belum tentu berupa string.

Misalnya, jika untuk untuk objek 'obj' metode didefinisikan keString,

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

Metode keString mengembalikan string dengan tepat, dan saat menambahkan string dengan angka, kita mendapatkan string terpaku:

`obj + 1 // '2001'` 

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

Tetapi jika Anda menulis ulang keString, sehingga metode mengembalikan angka, ketika objek ditambahkan, operasi matematika dengan konversi numerik akan dilakukan dan hasil penjumlahan matematika akan diperoleh.

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

`obj + 1 // '2001'`

Dalam hal ini, jika kita melakukan penjumlahan dengan string, konversi string dilakukan, dan kita mendapatkan string yang direkatkan.

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

Inilah alasan banyaknya kesalahan oleh pengguna JavaScript pemula.

Metode keString Anda dapat menulis fungsi yang akan meningkatkan nilai objek saat ini sebesar 1.

Kami memecahkan masalah praktis di Zabbix menggunakan JavaScript
Eksekusi skrip, asalkan variabelnya sama dengan 3, dan juga sama dengan 4.

Jika dibandingkan dengan pemeran (==), metode ini dieksekusi setiap kali keString dengan fungsi peningkatan nilai. Dengan demikian, dengan setiap perbandingan berikutnya, nilainya meningkat. Ini dapat dihindari dengan menggunakan perbandingan non-cast (===).

Kami memecahkan masalah praktis di Zabbix menggunakan JavaScript
Perbandingan tanpa pengecoran tipe

CATATAN. Jangan Gunakan Perbandingan Pemeran jika Tidak Perlu.

Untuk skrip kompleks, seperti Webhook dengan logika kompleks, yang memerlukan perbandingan dengan pengecoran tipe, disarankan untuk melakukan pemeriksaan awal untuk nilai yang mengembalikan variabel dan menangani ketidakkonsistenan dan kesalahan.

Media webhook

Pada akhir 2019 dan awal 2020, tim integrasi Zabbix telah secara aktif mengembangkan Webhook dan integrasi siap pakai yang disertakan dengan distribusi Zabbix.

Kami memecahkan masalah praktis di Zabbix menggunakan JavaScript
Tautan ke dokumentasi

Pemrosesan awal

  • Munculnya preprocessing dalam JavaScript memungkinkan untuk meninggalkan sebagian besar skrip eksternal, dan saat ini di Zabbix Anda bisa mendapatkan nilai apa pun dan mengubahnya menjadi nilai yang sama sekali berbeda.
  • Preprocessing di Zabbix diimplementasikan oleh kode JavaScript, yang ketika dikompilasi menjadi bytecode, diubah menjadi fungsi yang mengambil satu nilai sebagai parameter nilai sebagai string (string dapat berisi digit dan angka).
  • Karena keluarannya adalah fungsi, di akhir skrip diperlukan kembali.
  • Dimungkinkan untuk menggunakan makro khusus dalam kode.
  • Sumber daya dapat dibatasi tidak hanya pada level sistem operasi, tetapi juga secara terprogram. Langkah preprocessing dialokasikan maksimal 10 megabytes RAM dan batas run time 10 detik.

Kami memecahkan masalah praktis di Zabbix menggunakan JavaScript

CATATAN. Nilai timeout 10 detik cukup banyak, karena mengumpulkan ribuan item data bersyarat dalam 1 detik menurut skenario preprocessing yang agak β€œberat” dapat memperlambat Zabbix. Oleh karena itu, tidak disarankan untuk menggunakan prapemrosesan untuk mengeksekusi skrip JavaScript lengkap melalui apa yang disebut elemen data bayangan (item dummy), yang dijalankan hanya untuk melakukan prapemrosesan..

Anda dapat memeriksa kode Anda melalui tes preprocessing atau menggunakan utilitas 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`

Tugas praktis

Tugas 1

Ganti item terhitung dengan preprocessing.

Kondisi: Dapatkan suhu dalam Fahrenheit dari sensor untuk disimpan dalam Celcius.

Sebelumnya, kita akan membuat item yang mengumpulkan suhu dalam derajat Fahrenheit. Setelah itu, item data lain (dihitung) yang akan mengubah Fahrenheit menjadi Celcius menggunakan rumus.

Masalah:

  • Penting untuk menduplikasi elemen data dan menyimpan semua nilai dalam database.
  • Anda harus menyetujui interval untuk item data "induk" yang dihitung dan digunakan dalam rumus, dan untuk item data yang dihitung. Jika tidak, item yang dihitung dapat masuk ke status tidak didukung atau menghitung nilai sebelumnya, yang akan memengaruhi keandalan hasil pemantauan.

Salah satu solusinya adalah beralih dari interval pemeriksaan fleksibel demi interval tetap untuk memastikan bahwa item yang dihitung dievaluasi setelah item yang menerima data (dalam kasus kami, suhu dalam derajat Fahrenheit).

Tetapi jika, misalnya, kami menggunakan templat untuk memeriksa sejumlah besar perangkat, dan pemeriksaan dilakukan setiap 30 detik sekali, Zabbix "meretas" selama 29 detik, dan pada detik terakhir mulai memeriksa dan menghitung. Ini menciptakan antrean dan memengaruhi kinerja. Oleh karena itu, disarankan untuk menggunakan interval tetap hanya jika benar-benar diperlukan.

Dalam masalah ini, solusi optimal adalah preprocessing JavaScript satu baris yang mengubah derajat Fahrenheit menjadi derajat Celsius:

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

Ini cepat dan mudah, Anda tidak perlu membuat item data yang tidak perlu dan menyimpan riwayatnya, dan Anda juga dapat menggunakan interval fleksibel untuk pemeriksaan.

Kami memecahkan masalah praktis di Zabbix menggunakan JavaScript

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

Tetapi, jika dalam situasi hipotetis perlu menambahkan elemen data yang diterima, misalnya, dengan konstanta apa pun yang ditentukan dalam makro, harus diperhitungkan bahwa parameternya nilai mengembang menjadi string. Dalam operasi penjumlahan string, dua string digabungkan menjadi satu.

Kami memecahkan masalah praktis di Zabbix menggunakan JavaScript

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

Untuk mendapatkan hasil operasi matematika, perlu dilakukan konversi jenis nilai yang diperoleh ke format numerik. Untuk ini, Anda dapat menggunakan fungsi tersebut parseInt(), yang menghasilkan bilangan bulat, sebuah fungsi parseFloat(), yang menghasilkan desimal, atau fungsi jumlah, yang mengembalikan bilangan bulat atau desimal.

Tantangan 2

Dapatkan waktu dalam hitungan detik hingga akhir sertifikat.

Kondisi: layanan mengeluarkan tanggal kedaluwarsa sertifikat dalam format "12 Feb 12:33:56 2022 GMT".

Dalam ECMAScript5 Date.parse () menerima tanggal dalam format ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ). Anda perlu memasukkan string ke dalamnya dalam format MMM DD YYYY HH:mm:ss ZZ

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

Contoh solusi:

  • Pertama-tama, sebuah variabel yang mengambil nilai dideklarasikan (seluruh skrip adalah deklarasi variabel yang terdaftar dipisahkan dengan koma).

  • Di baris pertama kita mendapatkan tanggal di parameter nilai dan pisahkan dengan spasi menggunakan metode membagi. Jadi, kita mendapatkan sebuah array, di mana setiap elemen array, mulai dari indeks 0, sesuai dengan satu elemen tanggal sebelum dan sesudah spasi. bagi(0) - bulan, bagi(1) - nomor, bagi(2) - string dengan waktu, dll. Setelah itu, setiap elemen tanggal dapat diakses dengan indeks dalam array.

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

  • Setiap bulan (dalam urutan kronologis) sesuai dengan indeks posisinya dalam larik (dari 0 hingga 11). Untuk mengonversi nilai teks menjadi nilai numerik, satu ditambahkan ke indeks bulan (karena bulan diberi nomor mulai dari 1). Dalam hal ini, ekspresi dengan penambahan satu diambil dalam tanda kurung, karena jika tidak, string akan diperoleh, bukan angka. Pada akhirnya kita lakukan mengiris() - potong array dari ujung untuk menyisakan hanya dua karakter (yang penting selama berbulan-bulan dengan angka 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 string dalam format ISO dari nilai yang diperoleh dengan penambahan string biasa dalam urutan yang sesuai.

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

Data dalam format yang dihasilkan adalah jumlah detik dari tahun 1970 hingga suatu saat di masa depan. Hampir tidak mungkin menggunakan data dalam format yang diterima di pemicu, karena Zabbix memungkinkan Anda untuk beroperasi hanya dengan makro {Tanggal} ΠΈ {Waktu}, yang menampilkan tanggal dan waktu dalam format yang mudah digunakan.

  • Kami kemudian bisa mendapatkan tanggal saat ini dalam JavaScript dalam format Unix Timestamp dan menguranginya dari tanggal kedaluwarsa sertifikat yang dihasilkan untuk mendapatkan jumlah milidetik dari sekarang hingga sertifikat kedaluwarsa.

`now = Date.now();`

  • Kami membagi nilai yang diterima dengan seribu untuk mendapatkan detik di Zabbix.

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

Di pemicu, Anda dapat menentukan ekspresi 'terakhir' diikuti dengan sekumpulan digit yang sesuai dengan jumlah detik dalam periode yang ingin Anda tanggapi, misalnya dalam minggu. Dengan demikian, pemicu akan memberi tahu bahwa sertifikat kedaluwarsa dalam seminggu.

CATATAN. Perhatikan penggunaannya parseInt() dalam fungsi kembaliuntuk mengubah bilangan pecahan yang dihasilkan dari pembagian milidetik menjadi bilangan bulat. Anda juga bisa menggunakan parseFloat() dan menyimpan data pecahan.

Laporan tontonan

Sumber: www.habr.com

Tambah komentar