Crear un plugin (tutorial)

Això és un tutorial passa a passa per crear un plugin carregable senzill per l'agent 2 de Zabbix.

Què fareu

Durant aquest tutorial, afegireu un nou connector carregable MyIP. El connector implementarà una mètrica anomenada myip, que retorna l'adreça IP externa de l'equip on s'executa l'agent Zabbix 2.

Part 1: Escrivint el codi Go

En aquesta secció aprendreu a escriure el codi del connector que afegeix una mètrica nova a l'agent Zabbix 2.

  1. Creeu un directori nou myip a /usr/local/zabbix/go/plugins/.

  2. Creeu el fitxer main.go dins del directori myip i definiu el nom del vostre paquet Go.

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

package main

Mantingueu el fitxer obert per afegir més línies tal com es descriu a les passes següents.

  1. Especifiqueu els paquets que voleu importar. Aquests són els paquets que admeten el connector.

/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. Definiu l'estructura del plugin. Incorporeu l'estructura plugin.Base per accedir a la funcionalitat estàndard del plugin.

/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. Implementació de la interfície Export del plugin. La interfície Export fa una enquesta i retorna un valor.

/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. Afegir registre d'esdeveniments. El registre de missatges apareixerà al registre de l'agent 2 de Zabbix agent. Podeu emprar una de les funcions de registre disponible per als plugins: 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))
       }

7.Implementeu la lògica del plugin bàsic. Aquesta lògica obté la resposta de l'URL especificat i la llegeix, després retorna l'adreça IP com a resposta i tanca la petició. En cas d'error en executar la consulta GET o llegir una resposta, retorna l'error.

/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. Registreu la mètrica. L'agent Zabbix 2 inicia l'execució de la funció init() a l'inici. Aquesta funció cridarà al mètode plugin.RegisterMetrics (estructura, nom del plugin, nom de mètrica, descripció) per obtindre les dades del plugin.

Descripció del paràmetre del mètode plugin.RegisterMetrics:

  • estructura - un punter a la implementació del plugin; concedeix accés a l'estructura del plugin, inclosa la llista d'interfícies de plugins disponibles (per exemple, &impl).
  • nom - nom del plugin; ha de ser únic (per exemple, "Myip").
  • nom de la mètrica - nom de la mètrica (per exemple, "myip"). Aquesta és la clau d'element que s'empra per recopilar dades d'un plugin.
  • descripció - descripció mètrica; ha de començar amb majúscula i acabar amb un punt (per exemple, ""Retorna l'adreça IP externa de l'equip on s'executa l'agent.").

Per registrar diverses mètriques, repetiu els paràmetres nom de la mètrica i descripció per a cada mètrica. Per exemple: plugin.RegisterMetrics(&impl, "Myip", "metric.one", "Metric one description.", "metric.two", "metric two description.")

/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. Definiu la funció main(), que implementarà el gestor del plugin Zabbix per crear i iniciar el plugin.

És obligatori definir aquesta funció.

/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()))
                  }
              }

Part 2: Muntant el plugin

En aquesta secció aprendreu a compilar el plugin.

  1. Per crear arxius Go per gestionar i descarregar dependències automàticament, executeu aquest script de bash des de CLI (assegureu-vos d'especificar correctament el nom de la branca a la línia 3 go get...).
go mod init myip
       GOPROXY=direct go get git.zabbix.com/ap/plugin-support/plugin@release/6.4
       go mod tidy
       go build

La sortida s'assemblarà a:

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. Creeu un executable myip per al plugin carregable.

  2. Especifiqueu la ruta del fitxer de configuració del plugin al paràmetre Plugins.Myip.System.Path del fitxer de configuració de l'agent 2 del Zabbix.

El nom del plugin al nom del paràmetre de configuració (Myip en aquest tutorial) ha de coincidir amb el nom del plugin definit a la funció plugin.RegisterMetrics().

echo 'Plugins.Myip.System.Path=/usr/local/zabbix/go/plugins/myip/myip' > /etc/zabbix_agent2.d/plugins.d/myip.conf
  1. Proveu la mètrica:
zabbix_agent2 -t myip

La resposta ha de contindre una adreça IP externa del vostre equip.

En cas d'error, comproveu si l'usuari zabbix té permisos per accedir al directori /usr/local/zabbix/go/plugins/myip.