Створення плагіна (посібник)

Це покроковий посібник зі створення простого завантажуваного плагіна для Zabbix agent 2.

Що ви створите

Під час цього уроку ви додасте новий завантажуваний плагін MyIP. Плагін реалізує 1 метрику під назвою myip, яка повертає зовнішню IP-адресу хоста, на якому запущено Zabbix Agent 2.

Частина 1: Написання коду на Go

У цьому розділі ви дізнаєтеся, як написати плагін, який додає нову метрику до Zabbix агента 2.

  1. Створіть новий каталог myip в /usr/local/zabbix/go/plugins/.

  2. Створіть файл main.go всередині каталогу myip і визначте ім'я вашого Go пакету.

/usr/local/zabbix/go/plugins/myip/main.go

package main

Тримайте файл відкритим, щоб додати нові рядки, як описано в наступних кроках.

  1. Вкажіть пакети для імпорту. Це пакети, які підтримують плагін.

/usr/local/zabbix/go/plugins/myip/main.go

package main
       
       import (
       "fmt"
       "io/ioutil"
       "net/http"
       "git.zabbix.com/ap/plugin-support/plugin/container"
       "git.zabbix.com/ap/plugin-support/plugin"
       )
  1. Визначте структуру плагіна. Додайте структуру plugin.Base, щоб отримати доступ до стандартного функціоналу плагіна.

/usr/local/zabbix/go/plugins/myip/main.go

package main
       
       import (
       "fmt"
       "io/ioutil"
       "net/http"
       "git.zabbix.com/ap/plugin-support/plugin/container"
       "git.zabbix.com/ap/plugin-support/plugin"
       )
       
       type Plugin struct {
       plugin.Base
       }
       
       var impl Plugin
  1. Реалізуйте інтерфейс плагіна [Export] (/devel/plugins/interfaces). Інтерфейс експорту виконує опитування і повертає значення.

/usr/local/zabbix/go/plugins/myip/main.go

package main
       
       import (
       "fmt"
       "io/ioutil"
       "net/http"
       "git.zabbix.com/ap/plugin-support/plugin/container"
       "git.zabbix.com/ap/plugin-support/plugin"
       )
       
       type Plugin struct {
       plugin.Base
       }
       
       var impl Plugin
       
       func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error)
  1. Додайте логування. Повідомлення журналу з'являться в log файлі Zabbix Agent 2. Ви можете використовувати одну з функцій логування, доступних для плагінів: Critf(), Errf(), Infof(), Warningf(), Debugf(), Tracef().

/usr/local/zabbix/go/plugins/myip/main.go

package main
       
       import (
       "fmt"
       "io/ioutil"
       "net/http"
       "git.zabbix.com/ap/plugin-support/plugin/container"
       "git.zabbix.com/ap/plugin-support/plugin"
       )
       
       type Plugin struct {
       plugin.Base
       }
       
       var impl Plugin
       
       func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error){
       p.Infof("received request to handle %s key with %d parameters", key, len(params))
       }
  1. Реалізуйте основну логіку плагіна. Ця логіка отримує відповідь за вказаною URL-адресою і читає її, потім повертає IP-адресу як відповідь і закриває запит. У разі помилки при виконанні GET-запиту або читанні відповіді, замість неї повертається помилка.

/usr/local/zabbix/go/plugins/myip/main.go

package main
       
       import (
       "fmt"
       "io/ioutil"
       "net/http"
       "git.zabbix.com/ap/plugin-support/plugin/container"
       "git.zabbix.com/ap/plugin-support/plugin"
       )
       
       type Plugin struct {
       plugin.Base
       }
       
       var impl Plugin
       
       func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error){
       p.Infof("received request to handle %s key with %d parameters", key, len(params))
       resp, err := http.Get("https://api.ipify.org")
       if err != nil {
       return nil, err
       }
       
       defer resp.Body.Close()
       
       body, err := ioutil.ReadAll(resp.Body)
       if err != nil {
       return nil, err
       }
       
       return string(body), nil
       }
  1. Зареєструйте метрику. Zabbix агент 2 ініціює виконання функції init() при запуску. Ця функція викличе метод plugin.RegisterMetrics(structure, plugin name, metric name, description) для отримання даних плагіна.

Опис параметрів методу plugin.RegisterMetrics:

  • structure - вказівник на реалізацію плагіна; надає доступ до структури плагіна, включаючи список доступних інтерфейсів плагіна (наприклад, &impl) .- name - назва плагіна; має бути унікальною (наприклад, "Myip ").
  • metric name - назва метрики (наприклад, "myip "). Це ключ елемента, який використовується для збору даних з плагіна.
  • description - опис метрики; має починатися з великої літери і закінчуватися крапкою (наприклад, ""Return the external IP address of the host where agent is running.").

:: notetip Щоб зареєструвати кілька метрик, повторіть параметри metric name та description для кожної метрики. Наприклад: plugin.RegisterMetrics(&impl, "Myip", "metric.one", "Опис першої метрики.", "metric.two", "Опис другої метрики."). :::

/usr/local/zabbix/go/plugins/myip/main.go

package main
       
       import (
       "fmt"
       "io/ioutil"
       "net/http"
       "git.zabbix.com/ap/plugin-support/plugin/container"
       "git.zabbix.com/ap/plugin-support/plugin"
       )
       
       type Plugin struct {
       plugin.Base
       }
       
       var impl Plugin
       
       func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error){
       p.Infof("received request to handle %s key with %d parameters", key, len(params))
       resp, err := http.Get("https://api.ipify.org")
       if err != nil {
       return nil, err
       }
       
       defer resp.Body.Close()
       
       body, err := ioutil.ReadAll(resp.Body)
       if err != nil {
       return nil, err
       }
       
       return string(body), nil
       }
       
       func init() {
       plugin.RegisterMetrics(&impl, "Myip", "myip", "Return the external IP address of the host where agent is running.")
       }
  1. Визначте функцію main(), яка створить новий екземпляр обробника плагіна, призначить його для ведення журналу плагіном, а потім виконає обробник плагіна.

Визначення функції main() є обов'язковим.

/usr/local/zabbix/go/plugins/myip/main.go

package main
       
       import (
       "fmt"
       "io/ioutil"
       "net/http"
       "git.zabbix.com/ap/plugin-support/plugin/container"
       "git.zabbix.com/ap/plugin-support/plugin"
       )
       
       type Plugin struct {
       plugin.Base
       }
       
       var impl Plugin
       
       func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error){
       p.Infof("received request to handle %s key with %d parameters", key, len(params))
       resp, err := http.Get("https://api.ipify.org")
       if err != nil {
       return nil, err
       }
       
       defer resp.Body.Close()
       
       body, err := ioutil.ReadAll(resp.Body)
       if err != nil {
       return nil, err
       }
       
       return string(body), nil
       }
       
       func init() {
       plugin.RegisterMetrics(&impl, "Myip", "myip", "Return the external IP address of the host where agent is running.")
       }
       
       func main() {
       h, err := container.NewHandler(impl.Name())
       if err != nil {
       panic(fmt.Sprintf("failed to create plugin handler %s", err.Error()))
       }
       impl.Logger = &h
       
       err = h.Execute()
       if err != nil {
       panic(fmt.Sprintf("failed to execute plugin handler %s", err.Error()))
       }
       }

Частина 2: Створення плагіна

У цьому розділі ви дізнаєтеся, як скомпілювати плагін.

  1. Щоб створити файли Go для обробки залежностей і автоматично завантажити залежності, виконайте цей сценарій bash із CLI.
go mod init myip
       GOPROXY=direct go get git.zabbix.com/ap/plugin-support/plugin@branchname
       go mod tidy
       go build

Переконайтеся, що вказали правильну назву гілки, тобто замініть branchname (див. рядок 2) на одне з наступного:

  • release/* - для гілки стабільного релізу, де "*" є версією релізу (тобто 6.4)
  • master - для головної гілки
  • <commit hash> - для конкретної версії коміту (використовуйте спеціальний хеш коміту)

Результат має бути подібним до цього:

go: creating new go.mod: module myip
       go: to add module requirements and sums:
           go mod tidy
       go: finding module for package git.zabbix.com/ap/plugin-support/plugin/container
       go: finding module for package git.zabbix.com/ap/plugin-support/plugin
       go: found git.zabbix.com/ap/plugin-support/plugin in git.zabbix.com/ap/plugin-support v0.0.0-20220608100211-35b8bffd7ad0
       go: found git.zabbix.com/ap/plugin-support/plugin/container in git.zabbix.com/ap/plugin-support v0.0.0-20220608100211-35b8bffd7ad0
  1. Створіть виконуваний файл myip для завантажуваного плагіна.

  2. Вкажіть шлях до файлу конфігурації плагіна в параметрі Plugins.Myip.System.Path файлу конфігурації Zabbix agent 2.

Ім’я плагіна в назві параметра конфігурації (Myip у цьому підручнику) має відповідати імені плагіна, визначеному у функції plugin.RegisterMetrics().

echo 'Plugins.Myip.System.Path=/usr/local/zabbix/go/plugins/myip/myip' > /etc/zabbix_agent2.d/plugins.d/myip.conf
  1. Протестуйте метрику
zabbix_agent2 -t myip

Відповідь має містити зовнішню IP-адресу вашого хосту.

У разі помилки перевірте, чи має користувач zabbix права доступу до каталогу /usr/local/zabbix/go/plugins/myip.