プラグインを作成する (チュートリアル)

これは、Zabbixエージェント2 用のシンプルでロード可能なプラグインを作成するためのステップバイステップのチュートリアルです。

作成するもの

このチュートリアルでは、新しいロード可能なプラグインMyIPを追加します。このプラグインは、Zabbixエージェント2が稼働しているホストの外部IPアドレスを返すmyipという1つのメトリックを実装します。

Part 1: Goコードを書く

このセクションでは、Zabbixエージェント2 に新しいメトリクスを追加するプラグインを作成する方法を学習します。

  1. /usr/local/zabbix/go/plugins/に新しいディレクトリmyip を作成します。

  2. myipディレクトリ内にファイルmain.goを作成し、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を実装します。 エクスポートインターフェースはポーリングを実行し、値を返します。

/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. ロギングを追加します。 ログメッセージはZabbixエージェント2のログに表示されます。 プラグインで利用可能なログ機能の1つを使用できます: 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.")。

複数のメトリクスを登録するには、メトリクスごとにパラメーター、メトリクス名説明を繰り返します。
例: 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. 新しいプラグインハンドラーインスタンスを作成する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()))
           }
       }

Part 2: プラグインのビルド

このセクションでは、プラグインをコンパイルする方法を学習します。

  1. 依存関係を処理するためのGoファイルを作成し、依存関係をダウンロードするには、CLIからこのbashスクリプトを自動的に実行します。
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. Zabbixエージェント2の設定ファイルのPlugins.Myip.System.Pathパラメーターにプラグイン設定ファイルへのパスを指定します。

設定パラメーター名のプラグイン名(このチュートリアルでは 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ディレクトリにアクセスする権限があるかどうかを確認してください。