LoginSignup
3
4

More than 5 years have passed since last update.

zabbix3.2のLoadable modulesをGoで開発できる環境を作る

Last updated at Posted at 2017-05-28

Zabbixでは、自作したモジュールをZabbix ServerやZabbix Agentからロードすることが可能な仕様になっています。
そこで、ここでは Go を使ってロード可能モジュール(Loadable modules)を作ってみます。
Zabbix3.2のモジュールを作った時に少しハマったのでメモしておきます :-)

環境

項目 バージョン
OS CentOS 7.2
Zabbix 3.2
Go 1.8.1

GoのZabbixモジュールアダプタ

g2z

Zabbixのネイティブモジュールが作成できるGoバイディングである g2z を使用します。

ドキュメント

インストール

パッケージインストール

(1) 必要なパッケージをインストールします。

[root@localhost ~]# yum -y install git gcc

g2zインストール

(1) g2z をインストールします。Zabbixは3.2を使うのでバージョン3を指定しています。

[root@localhost ~]# go get -v gopkg.in/cavaliercoder/g2z.v3
gopkg.in/cavaliercoder/g2z.v3
# gopkg.in/cavaliercoder/g2z.v3
In file included from $WORK/gopkg.in/cavaliercoder/g2z.v3/_obj/_cgo_export.c:3:0:
go/src/gopkg.in/cavaliercoder/g2z.v3/module.go: 関数 ‘append_metric’ 内:
go/src/gopkg.in/cavaliercoder/g2z.v3/module.go:44:2: 警告: 組み込み関数 ‘memcpy’ の互換性がない暗黙的な宣言です [デフォルトで有効]
  memcpy(list, n, sizeof(ZBX_METRIC));
  ^
# gopkg.in/cavaliercoder/g2z.v3
go/src/gopkg.in/cavaliercoder/g2z.v3/module.go: 関数 ‘append_metric’ 内:
go/src/gopkg.in/cavaliercoder/g2z.v3/module.go:44:2: 警告: 組み込み関数 ‘memcpy’ の互換性がない暗黙的な宣言です [デフォルトで有効]
  memcpy(list, n, sizeof(ZBX_METRIC));
  ^

g2zの修正

修正しなくてはいけない理由

Zabbix 3.2から ZBX_MODULE_API_VERSION_ONE から ZBX_MODULE_API_VERSION に変更されています。
そのため、g2zをインストールしてモジュールをビルドしZabbixへ組み込んだあとに起動すると以下のエラーが発生します。

5603:20170529:003940.573 using configuration file: /etc/zabbix/zabbix_agentd.conf
5603:20170529:003940.577 unsupported module "example.so" version: 1 <- サポートしていないバージョンなので起動できない
5603:20170529:003940.577 loading modules failed, exiting...

Zabbixのソースコードを見てみましょう。

[root@localhost SOURCES]# grep -n 'ZBX_MODULE_API_VERSION' ./zabbix-3.2.6/include/module.h
29:#define ZBX_MODULE_API_VERSION   2 <- バージョンが 2 になっていることが確認できます
32:#define ZBX_MODULE_API_VERSION_ONE   ZBX_MODULE_API_VERSION <- 古いのは新しいので上書きされています
35:/* #if ZBX_MODULE_API_VERSION == X                                                     */

3.2以上でロード可能モジュールを開発する場合は、g2zでもこの修正が必要になります。

修正手順

(1) g2zの module.hZBX_MODULE_API_VERSION2 に修正します。

[root@localhost ~]# vi go/src/gopkg.in/cavaliercoder/g2z.v3/module.h
(snip)
#define ZBX_MODULE_API_VERSION_ONE      2

これが、一番簡単な修正方法かと思います。
または module.hZBX_MODULE_API_VERSION を新しく追加して go/src/gopkg.in/cavaliercoder/g2z.v3/module.gozbx_module_api_version 関数内を修正しても大丈夫だと思います。

//export zbx_module_api_version
func zbx_module_api_version() int {
        return C.ZBX_MODULE_API_VERSION_ONE <- ここ
}

ちなみに、本家にはプルリクがきている模様

モジュールのビルド及び組み込み

ここでは、g2zの例にあるソースをビルドしてZabbix Agentへ組み込んでみます。

(1) 以下のソースコードを使用します。

package main

import (
    g2z "gopkg.in/cavaliercoder/g2z.v3"
    "strings"
)

func main() {
    panic("THIS_SHOULD_NEVER_HAPPEN")
}

func init() {
    g2z.RegisterStringItem("go.echo", "Hello,world", Echo)
}

func Echo(request *g2z.AgentRequest) (string, error) {
    return strings.Join(request.Params, " "), nil
}

(2) ビルドします。

[root@localhost ~]# go build -buildmode=c-shared -o example.so example.go
# gopkg.in/cavaliercoder/g2z.v3
In file included from $WORK/gopkg.in/cavaliercoder/g2z.v3/_obj/_cgo_export.c:3:0:
go/src/gopkg.in/cavaliercoder/g2z.v3/module.go: 関数 ‘append_metric’ 内:
go/src/gopkg.in/cavaliercoder/g2z.v3/module.go:44:2: 警告: 組み込み関数 ‘memcpy’ の互換性がない暗黙的な宣言です [デフォルトで有効]
  memcpy(list, n, sizeof(ZBX_METRIC));
  ^
# gopkg.in/cavaliercoder/g2z.v3
go/src/gopkg.in/cavaliercoder/g2z.v3/module.go: 関数 ‘append_metric’ 内:
go/src/gopkg.in/cavaliercoder/g2z.v3/module.go:44:2: 警告: 組み込み関数 ‘memcpy’ の互換性がない暗黙的な宣言です [デフォルトで有効]
  memcpy(list, n, sizeof(ZBX_METRIC));
  ^

(3) モジュールを任意の場所へ保存します。ここでは /etc/zabbix/modules 配下へ保存します。

[root@localhost ~]# mkdir /etc/zabbix/modules
[root@localhost ~]# mv example.so /etc/zabbix/modules/

(4) Zabbix Agentへ組み込みます。

[root@localhost ~]# vi /etc/zabbix/zabbix_agentd.conf
(snip)
### Option: LoadModulePath
#       Full path to location of agent modules.
#       Default depends on compilation options.
#
# Mandatory: no
# Default:
# LoadModulePath=${libdir}/modules
LoadModulePath=/etc/zabbix/modules

### Option: LoadModule
#       Module to load at agent startup. Modules are used to extend functionality of the agent.
#       Format: LoadModule=<module.so>
#       The modules must be located in directory specified by LoadModulePath.
#       It is allowed to include multiple LoadModule parameters.
#
# Mandatory: no
# Default:
# LoadModule=
LoadModule=example.so

(5) Zabbix Agentを起動します。

[root@localhost ~]# systemctl start zabbix-agent
[root@localhost ~]# systemctl status zabbix-agent
● zabbix-agent.service - Zabbix Agent
   Loaded: loaded (/usr/lib/systemd/system/zabbix-agent.service; disabled; vendor preset: disabled)
   Active: active (running) since 月 2017-05-29 00:50:05 JST; 1min 59s ago
(snip)

動作確認

(1) 動作確認をしてみます。

[root@localhost ~]# zabbix_get -s 127.0.0.1 -k 'go.echo['test', 'hoge']'
test hoge

(2) Discoveryのソースコード例を組み込んで実行してみました。

[root@localhost ~]# zabbix_get -s 127.0.0.1 -k 'go.discovery'
{
    "data":[
    {
        "{#INDEX}":"0"},
    {
        "{#INDEX}":"1"},
    {
        "{#INDEX}":"2"},
    {
        "{#INDEX}":"3"},
    {
        "{#INDEX}":"4"}]}

これで、3.2のモジュールが開発できるようになりました :-)
(独り言)3.4はいつでるんやろ...

参考文献

追記

Goルーチンの処理が入る場合は動かないようです。
https://github.com/cavaliercoder/g2z/issues/5
実際にやってみたら動かなかった(´・_・`)

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4