ทิฆอน ยูสคอฟ, วิศวกรทีมบูรณาการ 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 มีการพิจารณาตัวเลือกต่าง ๆ สำหรับภาษาและเอ็นจิ้น:
- หลัว - หลัว 5.1
- หลัว-หลัวจิต
- Javascript - ดุ๊กเทป
- จาวาสคริปต์ – JerryScript
- งูหลามฝังตัว
- Perl ฝังตัว
เกณฑ์การคัดเลือกหลัก ได้แก่ ความแพร่หลาย ความง่ายในการรวมเครื่องยนต์เข้ากับผลิตภัณฑ์ การใช้ทรัพยากรต่ำและประสิทธิภาพโดยรวมของเครื่องยนต์ และความปลอดภัยของการนำโค้ดในภาษานี้เข้าสู่การตรวจสอบ จากการรวมกันของตัวบ่งชี้ JavaScript ชนะในเอ็นจิ้น Duktape
เกณฑ์การคัดเลือกและการทดสอบประสิทธิภาพ
คุณสมบัติของ Duktape:
- มาตรฐาน
— โมดูล Zabbix สำหรับ Duktape:
- Zabbix.log() - ช่วยให้คุณเขียนข้อความที่มีรายละเอียดในระดับต่างๆ ลงในบันทึกเซิร์ฟเวอร์ Zabbix ได้โดยตรง ซึ่งทำให้สามารถเชื่อมโยงข้อผิดพลาดได้ เช่น ใน Webhook กับสถานะเซิร์ฟเวอร์
- CurlHttpRequest() - อนุญาตให้คุณส่งคำขอ HTTP ไปยังเครือข่ายซึ่งใช้ Webhook เป็นพื้นฐาน
- atob() และ btoa() - ให้คุณเข้ารหัสและถอดรหัสสตริงในรูปแบบ Base64
หมายเหตุ. Duktape เป็นไปตามมาตรฐาน ACME Zabbix ใช้สคริปต์เวอร์ชัน 2015 การเปลี่ยนแปลงที่ตามมาเป็นเรื่องเล็กน้อย ดังนั้นจึงสามารถละเว้นได้.
JavaScript เมจิค
ความมหัศจรรย์ทั้งหมดของ JavaScript อยู่ที่การพิมพ์แบบไดนามิกและการแคสต์ประเภท: สตริง ตัวเลข และบูลีน
ซึ่งหมายความว่าไม่จำเป็นต้องประกาศล่วงหน้าว่าตัวแปรประเภทใดควรส่งคืนค่า
ในการดำเนินการทางคณิตศาสตร์ ค่าที่ส่งกลับโดยตัวดำเนินการฟังก์ชันจะถูกแปลงเป็นตัวเลข ข้อยกเว้นสำหรับการดำเนินการดังกล่าวคือ การเพิ่ม เนื่องจากหากเงื่อนไขอย่างน้อยหนึ่งเงื่อนไขเป็นสตริง การแปลงสตริงจะถูกนำไปใช้กับเงื่อนไขทั้งหมด
หมายเหตุ. วิธีการที่รับผิดชอบสำหรับการแปลงดังกล่าวมักจะนำไปใช้ในต้นแบบแม่ของออบเจกต์ มูลค่าของ и ถึงสตริง. มูลค่าของ เรียกว่าระหว่างการแปลงตัวเลขและก่อนเมธอดเสมอ ถึงสตริง. วิธี มูลค่าของ ต้องส่งคืนค่าดั้งเดิม มิฉะนั้นผลลัพธ์จะถูกละเว้น
มีการเรียกใช้เมธอดบนวัตถุ มูลค่าของ. หากไม่พบหรือไม่ส่งคืนค่าดั้งเดิม วิธีการนี้จะถูกเรียก ถึงสตริง. ถ้าใช้วิธี ถึงสตริง ไม่พบ ค้นหา มูลค่าของ ในต้นแบบของวัตถุและทุกอย่างจะถูกทำซ้ำจนกว่าการประมวลผลค่าจะเสร็จสิ้นและค่าทั้งหมดในนิพจน์จะถูกส่งไปยังประเภทเดียวกัน. หากวัตถุใช้เมธอด ถึงสตริงซึ่งส่งคืนค่าดั้งเดิม จากนั้นจะใช้สำหรับการแปลงสตริง อย่างไรก็ตาม ผลลัพธ์ของการใช้เมธอดนี้ไม่จำเป็นต้องเป็นสตริง
ตัวอย่างเช่น ถ้าสำหรับสำหรับวัตถุ 'obj' มีการกำหนดวิธีการ ถึงสตริง,
`var obj = { toString() { return "200" }}`
วิธี ถึงสตริง คืนค่าเป็นสตริง และเมื่อเพิ่มสตริงด้วยตัวเลข เราจะได้สตริงที่ติดกาว:
`obj + 1 // '2001'`
`obj + 'a' // ‘200a'`
แต่ถ้าเขียนใหม่ ถึงสตริงเพื่อให้เมธอดส่งคืนตัวเลข เมื่อมีการเพิ่มวัตถุ การดำเนินการทางคณิตศาสตร์พร้อมการแปลงตัวเลขจะดำเนินการและจะได้ผลลัพธ์ของการบวกทางคณิตศาสตร์
`var obj = { toString() { return 200 }}`
`obj + 1 // '2001'`
ในกรณีนี้ หากเราทำการเพิ่มเติมด้วยสตริง การแปลงสตริงจะดำเนินการ และเราจะได้สตริงที่ติดกาว
`obj + 'a' // ‘200a'`
นี่เป็นสาเหตุของข้อผิดพลาดจำนวนมากโดยผู้ใช้ JavaScript มือใหม่
วิธีการ ถึงสตริง คุณสามารถเขียนฟังก์ชันที่จะเพิ่มมูลค่าปัจจุบันของวัตถุทีละ 1
การดำเนินการของสคริปต์โดยมีเงื่อนไขว่าตัวแปรเท่ากับ 3 และเท่ากับ 4 ด้วย
เมื่อเปรียบเทียบกับการโยน (==) เมธอดจะถูกดำเนินการในแต่ละครั้ง ถึงสตริง พร้อมฟังก์ชั่นเพิ่มมูลค่า ดังนั้นเมื่อเปรียบเทียบแต่ละครั้งมูลค่าจะเพิ่มขึ้น สิ่งนี้สามารถหลีกเลี่ยงได้โดยใช้การเปรียบเทียบแบบไม่ร่าย (===)
การเปรียบเทียบโดยไม่มีการหล่อแบบ
หมายเหตุ. อย่าใช้การเปรียบเทียบนักแสดงโดยไม่จำเป็น.
สำหรับสคริปต์ที่ซับซ้อน เช่น Webhooks ที่มีตรรกะที่ซับซ้อน ซึ่งต้องมีการเปรียบเทียบกับการแคสต์ประเภท ขอแนะนำให้เขียนการตรวจสอบล่วงหน้าสำหรับค่าที่ส่งคืนตัวแปรและจัดการความไม่สอดคล้องกันและข้อผิดพลาด
สื่อเว็บฮุค
ในช่วงปลายปี 2019 และต้นปี 2020 ทีมผสานรวม Zabbix ได้พัฒนา Webhooks และการผสานรวมแบบสำเร็จรูปที่มาพร้อมกับการกระจาย Zabbix อย่างแข็งขัน
ไม่ลงรอยกัน จิระ จิรา เซอร์วิส เคาน์เตอร์ Mattermost ทีมไมโครซอฟท์ ตรงข้าม อปท หน้าที่ เสน่ห์ดึงดูด Redmine ServiceNow ซิงก์4 หย่อน Telegram ซัมแมด Zendesk
เชื่อมโยงไปยัง
กระบวนการเตรียมการผลิต
- การถือกำเนิดของการประมวลผลล่วงหน้าใน JavaScript ทำให้สามารถละทิ้งสคริปต์ภายนอกส่วนใหญ่ได้ และในปัจจุบันใน Zabbix คุณสามารถรับค่าใดๆ และแปลงเป็นค่าที่แตกต่างไปจากเดิมอย่างสิ้นเชิง
- การประมวลผลล่วงหน้าใน Zabbix ดำเนินการโดยโค้ด JavaScript ซึ่งเมื่อคอมไพล์เป็น bytecode แล้ว จะถูกแปลงเป็นฟังก์ชันที่ใช้ค่าเดียวเป็นพารามิเตอร์ ความคุ้มค่า เป็นสตริง (สตริงสามารถมีทั้งตัวเลขและตัวเลข)
- เนื่องจากเอาต์พุตเป็นฟังก์ชัน จึงจำเป็นต้องต่อท้ายสคริปต์ กลับ.
- คุณสามารถใช้มาโครแบบกำหนดเองในโค้ดได้
- ทรัพยากรสามารถถูกจำกัดได้ไม่เฉพาะในระดับระบบปฏิบัติการเท่านั้น แต่ยังรวมถึงทางโปรแกรมด้วย ขั้นตอนการประมวลผลล่วงหน้าได้รับการจัดสรร RAM สูงสุด 10 เมกะไบต์และจำกัดเวลารัน 10 วินาที
หมายเหตุ. ค่าการหมดเวลา 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;`
รวดเร็วและง่ายดาย คุณไม่จำเป็นต้องสร้างรายการข้อมูลที่ไม่จำเป็นและเก็บประวัติไว้ และคุณยังสามารถใช้ช่วงเวลาที่ยืดหยุ่นสำหรับการตรวจสอบได้อีกด้วย
`return (parseInt(value) + parseInt("{$EXAMPLE.MACRO}"));`
แต่ถ้าในสถานการณ์สมมติ จำเป็นต้องเพิ่มองค์ประกอบข้อมูลที่ได้รับ ตัวอย่างเช่น ด้วยค่าคงที่ใดๆ ที่กำหนดไว้ในมาโคร จะต้องคำนึงถึงว่าพารามิเตอร์ ความคุ้มค่า ขยายเป็นสตริง ในการดำเนินการเพิ่มสตริง สองสตริงจะถูกรวมเป็นหนึ่งเดียว
`return (value + "{$EXAMPLE.MACRO}");`
ในการรับผลลัพธ์ของการดำเนินการทางคณิตศาสตร์จำเป็นต้องแปลงประเภทของค่าที่ได้รับเป็นรูปแบบตัวเลข สำหรับสิ่งนี้คุณสามารถใช้ฟังก์ชัน แยกวิเคราะห์ ()ซึ่งสร้างฟังก์ชันจำนวนเต็ม แยกวิเคราะห์ลอย ()ซึ่งสร้างทศนิยมหรือฟังก์ชัน จำนวนซึ่งส่งคืนจำนวนเต็มหรือทศนิยม
ภารกิจที่ 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 อนุญาตให้คุณทำงานกับมาโครเท่านั้น {วันที่} и {เวลา}ซึ่งส่งคืนวันที่และเวลาในรูปแบบที่ใช้งานง่าย
- จากนั้นเราสามารถรับวันที่ปัจจุบันใน JavaScript ในรูปแบบ Unix Timestamp และลบออกจากวันที่หมดอายุของใบรับรองเพื่อให้ได้จำนวนมิลลิวินาทีนับจากนี้ไปจนกว่าใบรับรองจะหมดอายุ
`now = Date.now();`
- เราหารมูลค่าที่ได้รับด้วยหนึ่งพันเพื่อรับวินาทีใน Zabbix
`return parseInt((Date.parse(ISOdate) - now) / 1000);`
ในทริกเกอร์ คุณสามารถระบุนิพจน์ 'ล่าสุด' ตามด้วยชุดตัวเลขที่สอดคล้องกับจำนวนวินาทีในช่วงเวลาที่คุณต้องการตอบกลับ เช่น ในสัปดาห์ ดังนั้นทริกเกอร์จะแจ้งว่าใบรับรองจะหมดอายุในหนึ่งสัปดาห์
หมายเหตุ. ใส่ใจการใช้งาน แยกวิเคราะห์ () ในการทำงาน กลับเพื่อแปลงจำนวนเศษส่วนที่เกิดจากการหารมิลลิวินาทีให้เป็นจำนวนเต็ม คุณยังสามารถใช้ แยกวิเคราะห์ลอย () และเก็บข้อมูลเศษส่วน.
ที่มา: will.com