Ово је корак-по-корак водич о томе како да направите једноставан додатак који се може учитати за Zabbix агент 2.
Такође можете користити пример репозиторијума као шаблон или водич за креирање сопствених додатака.
Овај туторијал показује како да креирате нови учитавајући додатак MyIP. Додатак ће имплементирати један кључ ставке, myip, који враћа екстерну IP адресу домаћина на којем се покреће Zabbix агент 2.
go.mod
у директоријуму додатка да бисте пратили зависности додатка:golang.zabbix.com/sdk
):Замените $LATEST_COMMIT_HASH
са најновијим HEAD
хешом комита из golang.zabbix.com/sdk
репозиторијума у одговарајућој грани издања. На пример:
Имајте на уму да верзирање golang.zabbix.com/sdk
тренутно није подржано, али се то може променити у будућности.
Додатне зависности се могу инсталирати по потреби помоћу go get
.
main.go
за изворни код додатка:Сада је почетно подешавање завршено и додатак је спреман за развој.
Модул golang.zabbix.com/sdk
, инсталиран у претходном кораку, пружа неопходан оквир за развој додатака и осигурава да сви додатци имају конзистентну структуру.
Почните дефинисањем главног тока извршавања додатка. Додајте следећи код у main.go
:
package main
func main() {
err := run()
if err != nil {
panic(err)
}
}
func run() error {
return nil
}
Овим се успоставља основни ток извршавања за додатак.Функција run ће касније садржати основну логику додатка.
Додатак Zabbix агента 2 биће представљен структуром која имплементира интерфејсе из пакета golang.zabbix.com/sdk/plugin
:
Можете сами имплементирати ове интерфејсе или користити подразумеване које пружа Zabbix Go SDK, модификујући их по потреби. Овај туторијал користи подразумеване имплементације.
Сада увезите пакет додатак и креирајте структуру myIP
која уграђује структуру plugin.Base
:
Структура myIP тренутно задовољава интерфејс Accessor. Метод за имплементацију једног од функционалних интерфејса додатка, Exporter
, биће додат касније у туторијалу.
Дефинисање кључева ставкиВаш додатак треба кључеве ставки да би прикупљао податке и пружао их Zabbix серверу или проксију.
plugin.RegisterMetrics()
унутар функције run()
:func run() error {
p := &myIP{}
// Региструјте `myip` ставку кључа.
err := plugin.RegisterMetrics(
p,
"MyIP",// Назив додатка
"myip",// Назив кључа ставке
"Враћа IP адресу хоста.", // Опис кључа ставке
)
if err != nil {
return errs.Wrap(err, "неуспешно регистровање метрика")
}
return nil
}
Да бисте регистровали неколико кључева ставки, поновите параметре назив метрике и опис за сваку метрику. На пример:
plugin.RegisterMetrics(&impl, "Myip", "metric.one", "Опис метрике један.", "metric.two", "Опис метрике два.")
Руковалац олакшава комуникацију између агента и додатка.
run()
и додајте код за креирање и подешавање руковаоца:func run() error {
p := &myIP{}
// Региструјте ставку `myip` key.
err := plugin.RegisterMetrics(
p,
"MyIP",// Назив додатка"
myip",// Назив кључа ставке"
Враћа IP адресу домаћина.", // Опис кључа ставке
)
if err != nil {
return errs.Wrap(err, "неуспешно регистровање метрике")
}
// Креирајте нови handler.
h, err := container.NewHandler("MyIP") // Назив додатка
if err != nil {
return errs.Wrap(err, "неуспешно креирање новог руковаоца")
}
// Подесите евидентирање да бисте прослеђивали логове са додатка агенту.
// Доступно преко p.Logger.Infof, p.Logger.Debugf, итд.
p.Logger = h
// Покрените извршавање додатка.
// Блокира док се не прими захтев за прекид од агента.
err = h.Execute()
if err != nil {
return errs.Wrap(err, "није успело извршавање обрађивача додатка")
}
return nil
}
Прикупљање података се врши путем интерфејса за извоз, који описује метод Export
:
func Export(
key string,// Кључ ставке који треба прикупити.
params []string,// Аргументи који се прослеђују кључу ставке (`myip[arg1, arg2]`).
context ContextProvider // Метаподаци о прикупљању података о кључу ставке.
) (any, error)
import (
"io"
"net/http"
)
Export
за структуру myIP
:func (p *myIP) Export(
key string, params []string, context plugin.ContextProvider,
) (any, error) {
// Додатак може да користи различиту логику прикупљања података на основу параметра `key`.
// Ова имплементација само проверава да ли је дати `key` подржан.
if key != "myip" {
return nil, errs.Errorf("непознати кључ ставке %q", key)
}
// Лог ће бити прослеђен агенту 2 log.
p.Infof(
"примљен захтев за обраду %q кључа са %d параметара",
key,
len(params),
)
// Прикупите податке и вратите их.
resp, err := http.Get("https://api.ipify.org")
if err != nil {
return nil, errs.Wrap(err, "није успело добијање IP адресе")
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errs.Wrap(err, "није успело читање тела одговора")
}
return string(body), nil
}
Ово би требало да креира извршну датотеку myip
у тренутном директоријуму.
echo "Plugins.MyIP.System.Path=$PATH_TO_THE_MYIP_PLUGIN_EXECUTABLE" > /etc/zabbix_agent2.d/plugins.d/myip.conf
Замените $PATH_TO_THE_MYIP_PLUGIN_EXECUTABLE
путањом до myip
креиране у кораку 5.
Назив додатка у називу параметра конфигурације (MyIP у овом туторијалу) мора се подударати са називом додатка дефинисаним у функцији plugin.RegisterMetrics().
myip
, покрените:Излаз би требало да садржи екстерну IP адресу вашег хоста и да изгледа слично овоме:
myip [s|192.0.2.0]
Овим сте креирали једноставан додатак за Zabbix агент 2 који се може учитати. Честитамо!
package main
import (
"io"
"net/http"
"golang.zabbix.com/sdk/errs"
"golang.zabbix.com/sdk/plugin"
"golang.zabbix.com/sdk/plugin/container"
)
var _ plugin.Exporter = (*myIP)(nil)
type myIP struct {
plugin.Base
}
func main() {
err := run()
if err != nil {
panic(err)
}
}
func run() error {
p := &myIP{}
// Региструјте кључ ставке `myip`.
err := plugin.RegisterMetrics(
p,
"MyIP", // Plugin name
"myip", // Item key name
"Returns the host's IP address.", // Item key description
)
if err != nil {
return errs.Wrap(err, "failed to register metrics")
}
// Креирај нови обрађивач
h, err := container.NewHandler("MyIP") // Plugin name
if err != nil {
return errs.Wrap(err, "failed to create new handler")
}
// Подесите евидентирање да бисте прослеђивали логове са додатка агенту.
// Доступно преко p.Logger.Infof, p.Logger.Debugf, etc.
p.Logger = h
// Покрените извршавање додатка.
// Блокира док се не прими захтев за прекид од агента.
err = h.Execute()
if err != nil {
return errs.Wrap(err, "failed to execute plugin handler")
}
return nil
}
func (p *myIP) Export(
key string, params []string, context plugin.ContextProvider,
) (any, error) {
// Додатак може да користи различиту логику прикупљања података на основу параметра `key`.
//Ова имплементација само проверава да ли је наведени "кључ" подржан.
if key != "myip" {
return nil, errs.Errorf("unknown item key %q", key)
}
//Дневник ће бити прослеђен дневнику агента 2.
p.Infof(
"received request to handle %q key with %d parameters",
key,
len(params),
)
// Прикупите податке и вратите их.
resp, err := http.Get("https://api.ipify.org")
if err != nil {
return nil, errs.Wrap(err, "failed to get IP address")
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errs.Wrap(err, "failed to read response body")
}
return string(body), nil
}