ما مشکلات عملی را در Zabbix با استفاده از جاوا اسکریپت حل می کنیم

ما مشکلات عملی را در Zabbix با استفاده از جاوا اسکریپت حل می کنیم
تیخون اوسکوف، مهندس تیم ادغام Zabbix

Zabbix یک پلت فرم قابل تنظیم است که برای نظارت بر هر نوع داده استفاده می شود. از اولین نسخه های Zabbix، مدیران نظارت توانایی اجرای اسکریپت های مختلف را از طریق اعمال برای بررسی گره های شبکه هدف در همان زمان، راه‌اندازی اسکریپت‌ها منجر به مشکلات متعددی از جمله نیاز به پشتیبانی از اسکریپت‌ها، تحویل آن‌ها به گره‌های ارتباطی و پراکسی‌ها و همچنین پشتیبانی از نسخه‌های مختلف شد.

جاوا اسکریپت برای Zabbix

در آوریل 2019، Zabbix 4.2 با پیش پردازش جاوا اسکریپت معرفی شد. بسیاری از مردم در مورد ایده کنار گذاشتن اسکریپت‌های نوشتن که داده‌ها را به جایی می‌برد، هضم می‌کنند و در قالبی که Zabbix درک می‌کند ارائه می‌کنند و بررسی‌های ساده‌ای انجام می‌دهند که داده‌هایی را دریافت می‌کنند که برای ذخیره و پردازش توسط Zabbix آماده نیستند، و سپس این جریان داده را با استفاده از ابزار Zabbix و JavaScript پردازش کنید. در ارتباط با اکتشافات سطح پایین و موارد وابسته که در Zabbix 3.4 ظاهر شدند، مفهوم نسبتاً انعطاف‌پذیری برای مرتب‌سازی و مدیریت داده‌های دریافتی به دست آوردیم.

در Zabbix 4.4، به عنوان ادامه منطقی پیش پردازش در جاوا اسکریپت، یک روش اعلان جدید ظاهر شده است - Webhook که می توان از آن برای ادغام آسان اعلان های Zabbix با برنامه های شخص ثالث استفاده کرد.

جاوا اسکریپت و Duktapes

چرا جاوا اسکریپت و دوکتیپ انتخاب شدند؟ گزینه های مختلفی برای زبان ها و موتورها در نظر گرفته شد:

  • Lua - Lua 5.1
  • Lua - LuaJIT
  • جاوا اسکریپت - Duktape
  • جاوا اسکریپت – JerryScript
  • پایتون جاسازی شده
  • پرل جاسازی شده

معیارهای اصلی انتخاب عبارت بودند از شیوع، سهولت ادغام موتور با محصول، مصرف کم منابع و عملکرد کلی موتور، و ایمنی وارد کردن کد به این زبان در نظارت. بر اساس ترکیب شاخص ها، جاوا اسکریپت بر روی موتور Duktape برنده شد.

ما مشکلات عملی را در Zabbix با استفاده از جاوا اسکریپت حل می کنیم

معیارهای انتخاب و تست عملکرد

ویژگی های Duktape:

- استاندارد ECMAScript E5/E5.1
- ماژول های Zabbix برای Duktape:

  • Zabbix.log() - به شما امکان می دهد پیام هایی با سطوح مختلف جزئیات را مستقیماً در گزارش سرور Zabbix بنویسید، که این امکان را فراهم می کند تا خطاها را به عنوان مثال در یک Webhook با وضعیت سرور مرتبط کنید.
  • CurlHttpRequest() - به شما امکان می دهد درخواست های HTTP را به شبکه ارسال کنید، که استفاده از Webhook بر اساس آن است.
  • atob() و btoa() - به شما امکان می دهد رشته ها را در قالب Base64 رمزگذاری و رمزگشایی کنید.

نکته. Duktape با استانداردهای ACME مطابقت دارد. Zabbix از نسخه 2015 اسکریپت استفاده می کند. تغییرات بعدی جزئی هستند، بنابراین می توان آنها را نادیده گرفت..

جادوی جاوا اسکریپت

تمام جادوی جاوا اسکریپت در تایپ پویا و ریختن نوع است: رشته، عددی و بولی.

این بدان معنی است که لازم نیست از قبل اعلام شود که متغیر باید چه نوع مقداری را برگرداند.

در عملیات ریاضی، مقادیر برگردانده شده توسط عملگرهای تابع به اعداد تبدیل می شوند. استثنای چنین عملیاتی جمع است، زیرا اگر حداقل یکی از عبارت ها یک رشته باشد، تبدیل رشته برای همه عبارت ها اعمال می شود.

نکته. روش‌های مسئول چنین تبدیل‌هایی معمولاً در نمونه‌های اولیه شیء پیاده‌سازی می‌شوند. ارزش и رشته. ارزش هنگام تبدیل عددی و همیشه قبل از متد فراخوانی می شود رشته. روش ارزش باید مقادیر اولیه را برگرداند، در غیر این صورت نتیجه آن نادیده گرفته می شود.

یک متد بر روی یک شیء فراخوانی می شود ارزش. اگر یافت نشد یا مقدار اولیه را برنگرداند، متد فراخوانی می شود رشته. اگر روش رشته پیدا نشد، در حال جستجو ارزش در نمونه اولیه شی، و همه چیز تکرار می شود تا زمانی که پردازش مقدار به پایان برسد و همه مقادیر در عبارت به یک نوع ریخته شوند.. اگر شی یک متد را پیاده سازی کند رشته، که یک مقدار اولیه را برمی گرداند، سپس این است که برای تبدیل رشته استفاده می شود. با این حال، نتیجه اعمال این روش لزوماً یک رشته نیست.

به عنوان مثال، اگر برای برای شی 'اعتراض' روش تعریف شده است رشته,

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

روش رشته دقیقاً یک رشته را برمی‌گرداند، و وقتی یک رشته را با یک عدد اضافه می‌کنیم، یک رشته چسب‌دار دریافت می‌کنیم:

`obj + 1 // '2001'` 

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

اما اگر بازنویسی کنید رشته، به طوری که روش یک عدد را برمی گرداند، با اضافه شدن شیء، یک عملیات ریاضی با تبدیل عددی انجام می شود و نتیجه جمع ریاضی به دست می آید.

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

`obj + 1 // '2001'`

در این حالت اگر جمع را با رشته انجام دهیم تبدیل رشته انجام می شود و یک رشته چسب به دست می آید.

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

این دلیل تعداد زیادی از اشتباهات کاربران مبتدی جاوا اسکریپت است.

روش رشته می توانید تابعی بنویسید که مقدار فعلی شی را 1 افزایش دهد.

ما مشکلات عملی را در Zabbix با استفاده از جاوا اسکریپت حل می کنیم
اجرای اسکریپت به شرطی که متغیر برابر با 3 و همچنین برابر با 4 باشد.

هنگامی که با یک بازیگر (==) مقایسه می شود، این روش هر بار اجرا می شود رشته با تابع افزایش ارزش بر این اساس، با هر مقایسه بعدی، ارزش افزایش می یابد. با استفاده از مقایسه غیر بازیگران (===) می توان از این امر جلوگیری کرد.

ما مشکلات عملی را در Zabbix با استفاده از جاوا اسکریپت حل می کنیم
مقایسه بدون ریخته گری نوع

نکته. از مقایسه بازیگران بی جهت استفاده نکنید.

برای اسکریپت‌های پیچیده، مانند Webhooks با منطق پیچیده، که نیاز به مقایسه با نوع ریخته‌گری دارند، توصیه می‌شود برای مقادیری که متغیرها را برمی‌گردانند و ناسازگاری‌ها و خطاها را کنترل می‌کنند، چک‌هایی از قبل بنویسید.

رسانه وب هوک

در اواخر سال 2019 و اوایل سال 2020، تیم یکپارچه سازی Zabbix به طور فعال در حال توسعه Webhooks و ادغام های خارج از جعبه است که با توزیع Zabbix ارائه می شود.

ما مشکلات عملی را در Zabbix با استفاده از جاوا اسکریپت حل می کنیم
پیوند به مستندات

پیش پردازش

  • ظهور پیش پردازش در جاوا اسکریپت امکان کنار گذاشتن اکثر اسکریپت های خارجی را فراهم کرد و در حال حاضر در Zabbix می توانید هر مقداری را دریافت کرده و آن را به مقدار کاملاً متفاوت تبدیل کنید.
  • پیش پردازش در Zabbix توسط کد جاوا اسکریپت اجرا می شود که وقتی به بایت کد کامپایل می شود، به تابعی تبدیل می شود که یک مقدار را به عنوان پارامتر می گیرد. ارزش به عنوان یک رشته (رشته می تواند شامل یک رقم و یک عدد باشد).
  • از آنجایی که خروجی یک تابع است، در پایان اسکریپت مورد نیاز است برگشت.
  • امکان استفاده از ماکروهای سفارشی در کد وجود دارد.
  • منابع را می توان نه تنها در سطح سیستم عامل، بلکه از نظر برنامه ای نیز محدود کرد. مرحله پیش پردازش حداکثر 10 مگابایت رم و محدودیت زمان اجرا 10 ثانیه اختصاص دارد.

ما مشکلات عملی را در Zabbix با استفاده از جاوا اسکریپت حل می کنیم

نکته. مقدار وقفه 10 ثانیه بسیار زیاد است، زیرا جمع آوری هزاران مورد شرطی داده در 1 ثانیه طبق یک سناریوی پیش پردازش نسبتاً "سنگین" می تواند Zabbix را کند کند. بنابراین، استفاده از پیش پردازش برای اجرای اسکریپت های جاوا اسکریپت کامل از طریق عناصر به اصطلاح داده سایه (اقلام ساختگی) که فقط برای انجام پیش پردازش اجرا می شوند، توصیه نمی شود..

می توانید کد خود را از طریق آزمایش پیش پردازش یا با استفاده از ابزار بررسی کنید 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 ثانیه "هک" می کند و در ثانیه آخر شروع به بررسی و محاسبه می کند. این یک صف ایجاد می کند و بر عملکرد تأثیر می گذارد. بنابراین توصیه می شود در صورت لزوم از فواصل ثابت استفاده کنید.

در این مشکل، راه حل بهینه یک پیش پردازش جاوا اسکریپت یک خطی است که درجه فارنهایت را به درجه سانتیگراد تبدیل می کند:

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

این سریع و آسان است، شما نیازی به ایجاد اقلام داده غیر ضروری و نگه داشتن سابقه روی آنها ندارید و همچنین می توانید از فواصل منعطف برای بررسی استفاده کنید.

ما مشکلات عملی را در Zabbix با استفاده از جاوا اسکریپت حل می کنیم

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

اما اگر در یک موقعیت فرضی لازم باشد عنصر داده دریافتی اضافه شود، مثلاً با هر ثابتی که در ماکرو تعریف شده است، باید در نظر گرفته شود که پارامتر ارزش به یک رشته گسترش می یابد. در عملیات اضافه کردن رشته، دو رشته به سادگی در یک رشته ترکیب می شوند.

ما مشکلات عملی را در Zabbix با استفاده از جاوا اسکریپت حل می کنیم

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

برای به دست آوردن نتیجه یک عملیات ریاضی، لازم است انواع مقادیر به دست آمده را به فرمت عددی تبدیل کنید. برای این کار می توانید از تابع استفاده کنید parseInt()، که یک عدد صحیح، یک تابع تولید می کند parseFloat()، که یک اعشار یا یک تابع تولید می کند عدد، که یک عدد صحیح یا اعشاری را برمی گرداند.

وظیفه 2

زمان را در ثانیه تا پایان گواهی دریافت کنید.

وضعیت: یک سرویس تاریخ انقضای گواهی را در قالب "12 فوریه 12:33:56 2022 GMT" صادر می کند.

در ECMAScript5 date.parse() تاریخ را در قالب ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ) می پذیرد. لازم است یک رشته به آن با فرمت 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 به شما امکان می دهد فقط با ماکروها کار کنید. {تاریخ} и {زمان}، که تاریخ و زمان را در قالب کاربر پسند برمی گرداند.

  • سپس می‌توانیم تاریخ جاری در جاوا اسکریپت را با فرمت Unix Timestamp دریافت کنیم و آن را از تاریخ انقضای گواهی حاصل کم کنیم تا تعداد میلی‌ثانیه از هم‌اکنون تا زمان انقضای گواهی به دست آید.

`now = Date.now();`

  • مقدار دریافتی را بر هزار تقسیم می کنیم تا در Zabbix به ثانیه برسیم.

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

در ماشه، می توانید عبارت ' را مشخص کنیدآخربه دنبال آن مجموعه‌ای از ارقام مربوط به تعداد ثانیه‌های دوره‌ای است که می‌خواهید به آن پاسخ دهید، مثلاً در هفته. بنابراین، ماشه اطلاع می دهد که گواهی در یک هفته منقضی می شود.

نکته. به کاربرد توجه کنید parseInt() در عمل برگشتبرای تبدیل عدد کسری حاصل از تقسیم میلی ثانیه به یک عدد صحیح. همچنین می توانید استفاده کنید parseFloat() و داده های کسری را ذخیره کنید.

گزارش تماشا کنید

منبع: www.habr.com

اضافه کردن نظر