Zabbix'teki pratik sorunları JavaScript kullanarak çözüyoruz

Zabbix'teki pratik sorunları JavaScript kullanarak çözüyoruz
Tikhon Uskov, Zabbix entegrasyon ekibi mühendisi

Zabbix, her türlü veriyi izlemek için kullanılan özelleştirilebilir bir platformdur. Zabbix'in en eski sürümlerinden bu yana, izleme yöneticileri, çeşitli komut dosyalarını İşlemler hedef ağ düğümlerindeki kontroller için. Aynı zamanda, betiklerin piyasaya sürülmesi, betikleri destekleme ihtiyacı, bunların iletişim düğümlerine ve proxy'lere teslim edilmesinin yanı sıra farklı sürümler için destek gibi bir dizi zorluğa yol açtı.

Zabbix için JavaScript

Nisan 2019'da Zabbix 4.2, JavaScript ön işleme ile tanıtıldı. Birçok kişi, verileri bir yere götüren, sindiren ve Zabbix'in anlayacağı bir formatta sağlayan ve Zabbix tarafından depolamaya ve işlemeye hazır olmayan verileri alacak basit kontroller yapan komut dosyaları yazmaktan vazgeçme fikrinden heyecan duydu ve sonra Zabbix ve JavaScript araçlarını kullanarak bu veri akışını işleyin. Zabbix 3.4'te ortaya çıkan düşük seviyeli keşif ve bağımlı öğelerle bağlantılı olarak, alınan verileri sıralamak ve yönetmek için oldukça esnek bir konsepte sahibiz.

Zabbix 4.4'te, JavaScript'te ön işlemenin mantıksal bir devamı olarak, yeni bir bildirim yöntemi ortaya çıktı - Zabbix bildirimlerini üçüncü taraf uygulamalarla kolayca entegre etmek için kullanılabilen Webhook.

JavaScript ve Dutape'ler

JavaScript ve Duktape neden seçildi? Diller ve motorlar için çeşitli seçenekler değerlendirildi:

  • Lua - Lua 5.1
  • Lua - LuaJIT
  • JavaScript - Duktepe
  • JavaScript – JerryScript
  • Gömülü Python
  • Gömülü Perl

Ana seçim kriterleri, yaygınlık, motorun ürüne entegrasyon kolaylığı, düşük kaynak tüketimi ve motorun genel performansı ve izlemeye bu dilde kod eklemenin güvenliği idi. Göstergelerin kombinasyonuna dayalı olarak, Duktape motorunda JavaScript kazandı.

Zabbix'teki pratik sorunları JavaScript kullanarak çözüyoruz

Seçim kriterleri ve performans testi

Düktepe'nin Özellikleri:

— Standart ECMAScript E5/E5.1
— Duktape için Zabbix modülleri:

  • Zabbix.log() - farklı ayrıntı düzeylerine sahip mesajları doğrudan Zabbix Sunucu günlüğüne yazmanıza olanak tanır; bu, örneğin bir Webhook'taki hataları sunucu durumuyla ilişkilendirmeyi mümkün kılar.
  • CurlHttpRequest() - Webhook kullanımının temel aldığı ağa HTTP istekleri yapmanızı sağlar.
  • atob() ve btoa() - dizeleri Base64 biçiminde kodlamanıza ve kodunu çözmenize olanak tanır.

NOT. Duktape ACME standartlarına uygundur. Zabbix, komut dosyasının 2015 sürümünü kullanır. Sonraki değişiklikler önemsizdir, bu nedenle göz ardı edilebilirler..

JavaScript büyüsü

JavaScript'in tüm sihri, dinamik yazma ve tür atamada yatar: dize, sayısal ve boolean.

Bu, değişkenin hangi türde bir değer döndürmesi gerektiğini önceden bildirmenin gerekli olmadığı anlamına gelir.

Matematiksel işlemlerde fonksiyon operatörlerinin döndürdüğü değerler sayılara çevrilir. Bu tür işlemlerin istisnası toplama işlemidir, çünkü terimlerden en az biri bir dize ise, dize dönüştürme tüm terimlere uygulanır.

NOT. Bu tür dönüşümlerden sorumlu yöntemler genellikle nesnenin ana prototiplerinde uygulanır. değeri и toString. değeri sayısal dönüştürme sırasında ve her zaman yöntemden önce çağrılır toString. Yöntem değeri ilkel değerler döndürmelidir, aksi takdirde sonucu dikkate alınmaz.

Bir nesne üzerinde bir yöntem çağrılır değeri. Bulunamazsa veya ilkel bir değer döndürmezse, yöntem çağrılır. toString. eğer yöntem toString bulunamadı, aranıyor değeri nesnenin prototipinde ve değerin işlenmesi tamamlanana ve ifadedeki tüm değerler aynı türe dökülene kadar her şey tekrarlanır.. Nesne bir yöntem uyguluyorsa toString, ilkel bir değer döndürürse, dize dönüştürme için kullanılan odur. Ancak, bu yöntemi uygulamanın sonucu mutlaka bir dizi değildir.

Örneğin, for nesnesi için ise 'obj' yöntemi tanımlandı toString,

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

yöntem toString tam olarak bir dize döndürür ve sayı içeren bir dize eklerken yapıştırılmış bir dize elde ederiz:

`obj + 1 // '2001'` 

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

Ama yeniden yazarsan toString, böylece yöntem bir sayı döndürür, nesne eklendiğinde sayısal dönüştürme ile matematiksel işlem yapılır ve matematiksel toplama sonucu elde edilir.

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

`obj + 1 // '2001'`

Bu durumda bir string ile toplama yaparsak string dönüştürmesi yapılır ve yapıştırılmış bir string elde ederiz.

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

Acemi JavaScript kullanıcıları tarafından yapılan çok sayıda hatanın nedeni budur.

yöntem toString nesnenin mevcut değerini 1 artıracak bir fonksiyon yazabilirsiniz.

Zabbix'teki pratik sorunları JavaScript kullanarak çözüyoruz
Değişkenin 3'e eşit olması ve ayrıca 4'e eşit olması koşuluyla betiğin yürütülmesi.

Bir atama (==) ile karşılaştırıldığında, yöntem her seferinde yürütülür toString değer artırma fonksiyonu ile. Buna göre, sonraki her karşılaştırmada değer artar. Bu, döküm olmayan karşılaştırma (===) kullanılarak önlenebilir.

Zabbix'teki pratik sorunları JavaScript kullanarak çözüyoruz
Tip dökümü olmadan karşılaştırma

NOT. Döküm Karşılaştırmasını Gereksiz Yere Kullanmayın.

Tip atama ile karşılaştırma gerektiren karmaşık mantığa sahip Webhooks gibi karmaşık betikler için, değişkenleri döndüren ve tutarsızlıkları ve hataları işleyen değerler için önceden kontroller yazılması önerilir.

Web kancası Ortamı

2019'un sonlarında ve 2020'nin başlarında Zabbix entegrasyon ekibi, Zabbix dağıtımıyla birlikte gelen Web kancalarını ve kullanıma hazır entegrasyonları aktif olarak geliştiriyor.

Zabbix'teki pratik sorunları JavaScript kullanarak çözüyoruz
Link belgeleme

Ön İşleme

  • JavaScript'te ön işlemenin ortaya çıkışı, çoğu harici komut dosyasının terk edilmesini mümkün kıldı ve şu anda Zabbix'te herhangi bir değeri alabilir ve onu tamamen farklı bir değere dönüştürebilirsiniz.
  • Zabbix'te ön işleme, bayt koduna derlendiğinde parametre olarak tek bir değer alan bir işleve dönüştürülen JavaScript kodu tarafından uygulanır. değer bir dizi olarak (bir dizi hem rakam hem de sayı içerebilir).
  • Çıktı bir fonksiyon olduğundan betiğin sonunda gereklidir. dönüş.
  • Kodda özel makrolar kullanmak mümkündür.
  • Kaynaklar yalnızca işletim sistemi düzeyinde değil, aynı zamanda programlı olarak da sınırlandırılabilir. Ön işleme adımına maksimum 10 megabayt RAM ve 10 saniyelik bir çalışma süresi sınırı tahsis edilir.

Zabbix'teki pratik sorunları JavaScript kullanarak çözüyoruz

NOT. 10 saniyelik zaman aşımı değeri oldukça fazladır çünkü oldukça “ağır” bir ön işleme senaryosuna göre 1 saniyede koşullu binlerce veriyi toplamak Zabbix'i yavaşlatabilir. Bu nedenle, yalnızca ön işlemeyi gerçekleştirmek için çalıştırılan sözde gölge veri öğeleri (sahte öğeler) aracılığıyla tam teşekküllü JavaScript komut dosyalarını çalıştırmak için ön işlemenin kullanılması önerilmez..

Kodunuzu ön işleme testi aracılığıyla veya yardımcı programı kullanarak kontrol edebilirsiniz. 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`

Pratik görevler

Görev 1

Hesaplanan öğeyi ön işleme ile değiştirin.

durum: Santigrat cinsinden saklamak için sensörden sıcaklığı Fahrenhayt cinsinden alın.

Önceden, sıcaklığı Fahrenhayt cinsinden toplayan bir öğe yaratırdık. Bundan sonra, bir formül kullanarak Fahrenheit'i Celsius'a çevirecek başka bir veri öğesi (hesaplanmıştır).

Sorunları:

  • Veri öğelerini çoğaltmak ve tüm değerleri veritabanında saklamak gerekir.
  • Formülde hesaplanan ve kullanılan "üst" veri öğesi ve hesaplanan eri öğesi için aralıklar üzerinde anlaşmanız gerekir. Aksi takdirde, hesaplanan öğe desteklenmeyen bir duruma geçebilir veya izleme sonuçlarının güvenilirliğini etkileyecek bir önceki değeri hesaplayabilir.

Çözümlerden biri, hesaplanan öğenin verileri alan öğeden sonra değerlendirilmesini sağlamak için esnek kontrol aralıklarından sabit aralıklar lehine hareket etmekti (bizim durumumuzda, Fahrenheit derece cinsinden sıcaklık).

Ancak, örneğin, çok sayıda cihazı kontrol etmek için şablonu kullanırsak ve kontrol her 30 saniyede bir yapılırsa, Zabbix 29 saniye boyunca "hackler" ve son saniyede kontrol etmeye ve hesaplamaya başlar. Bu bir sıra oluşturur ve performansı etkiler. Bu nedenle, yalnızca gerçekten gerekliyse sabit aralıkların kullanılması önerilir.

Bu problemde en uygun çözüm, Fahrenheit derecesini Celsius derecesine çeviren tek satırlık bir JavaScript ön işlemesidir:

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

Hızlı ve kolaydır, gereksiz veri öğeleri oluşturmanıza ve bunlarla ilgili geçmiş tutmanıza gerek kalmaz ve ayrıca kontroller için esnek aralıklar kullanabilirsiniz.

Zabbix'teki pratik sorunları JavaScript kullanarak çözüyoruz

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

Ancak varsayımsal bir durumda, alınan veri öğesini, örneğin makroda tanımlanan herhangi bir sabitle eklemek gerekirse, parametrenin dikkate alınması gerekir. değer bir diziye genişler. Dizi toplama işleminde, iki dizi basit bir şekilde bir dizi halinde birleştirilir.

Zabbix'teki pratik sorunları JavaScript kullanarak çözüyoruz

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

Matematiksel bir işlemin sonucunu elde etmek için elde edilen değerlerin türlerini sayısal bir formata dönüştürmek gerekir. Bunun için işlevi kullanabilirsiniz ayrıştırma (), bir tamsayı, bir işlev üreten ayrıştırmaFloat(), ondalık sayı veya işlev üreten numara, bir tamsayı veya ondalık sayı döndürür.

Görev 2

Sertifikanın sonuna kadar geçen süreyi saniye cinsinden alın.

durum: bir hizmet, "12 Şubat 12:33:56 2022 GMT" biçiminde bir sertifika sona erme tarihi verir.

ECMAScript5'te Date.parse () ISO 8601 biçimindeki bir tarihi kabul eder (YYYY-AA-GGTSS:dd:ss.sssZ). AAA DD YYYY SS:dd:ss ZZ formatında bir dize atmak gerekir.

Sorun: Ay değeri sayı olarak değil metin olarak ifade edilir. Bu formattaki veriler Duktape tarafından kabul edilmemektedir.

Çözüm Örneği:

  • Her şeyden önce, bir değer alan bir değişken bildirilir (komut dosyasının tamamı, virgüllerle ayrılmış olarak listelenen değişkenlerin bir bildirimidir).

  • İlk satırda parametredeki tarihi alıyoruz değer ve yöntemi kullanarak boşluklarla ayırın bölmek. Böylece, 0 dizininden başlayan dizinin her öğesinin boşluktan önce ve sonra bir tarih öğesine karşılık geldiği bir dizi elde ederiz. bölünmüş(0) - ay, bölünmüş(1) - sayı, bölünmüş(2) - saat vb. içeren bir dize. Bundan sonra, tarihin her bir öğesine dizideki indeks ile erişilebilir.

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

  • Her ay (kronolojik sırayla), dizideki konumunun indeksine karşılık gelir (0'dan 11'e). Bir metin değerini sayısal bir değere dönüştürmek için ay dizinine bir eklenir (çünkü aylar 1'den başlayarak numaralandırılır). Bu durumda eki bir olan ifade parantez içinde alınır, aksi takdirde sayı değil dizi elde edilir. sonunda yaparız dilim() - diziyi uçtan sadece iki karakter kalacak şekilde kesin (bu, iki basamaklı bir sayı ile aylar için önemlidir).

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

  • Elde edilen değerlerden uygun sırayla normal dizilerin eklenmesiyle ISO formatında bir dizi oluşturuyoruz.

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

Ortaya çıkan formattaki veriler, 1970'ten gelecekte bir noktaya kadar olan saniye sayısıdır. Alınan formattaki verileri tetikleyicilerde kullanmak neredeyse imkansızdır, çünkü Zabbix yalnızca makrolarla çalışmanıza izin verir. {Tarih} и {Zaman}tarih ve saati kullanıcı dostu bir biçimde döndüren.

  • Daha sonra JavaScript'teki geçerli tarihi Unix Zaman Damgası biçiminde alabilir ve şu andan itibaren sertifikanın süresinin dolmasına kadar geçen milisaniye sayısını elde etmek için elde edilen sertifika son kullanma tarihinden çıkartabiliriz.

`now = Date.now();`

  • Zabbix'te saniye elde etmek için alınan değeri bine böleriz.

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

Tetikleyicide ' ifadesini belirtebilirsiniz.son' ardından, örneğin hafta olarak yanıtlamak istediğiniz süre içindeki saniye sayısına karşılık gelen bir dizi rakam gelir. Böylece tetikleyici, sertifikanın bir hafta içinde sona ereceğini bildirecektir.

NOT. Kullanıma dikkat edin ayrıştırma () işlevde dönüşmilisaniyelerin bölünmesinden elde edilen kesirli sayıyı bir tamsayıya dönüştürmek için. Ayrıca kullanabilirsin ayrıştırmaFloat() ve kesirli verileri depolayın.

Raporu izle

Kaynak: habr.com

Yorum ekle