[comment]: # translation:outdated

[comment]: # ({9c198e1d-39a10c96})
# 1 ローダブルモジュール

[comment]: # ({/9c198e1d-39a10c96})

[comment]: # ({d5349b7c-00b6a45a})
#### 概要

ローダブルモジュールは、Zabbixの機能を拡張するためのパフォーマンス重視のオプションです。

Zabbixの機能を拡張する方法として、すでに以下のようなものがあります。

- [user parameters](userparameters) (agent メトリクス)
- [external checks](/manual/config/item/itemtypes/external)(agent レス監視)
- `system.run[]` Zabbix [agent item](/manual/config/items/itemtypes/zabbix_agent).

これらは非常にうまく動作しますが、1つ大きな欠点があります。それはfork()です。<br>
Zabbixはユーザメトリクスを処理するたびに新しいプロセスを fork する必要があり、これはパフォーマンスに<br>
とって良いことではありません。通常は大きな問題ではありませんが、組み込みシステムの監視、多数の監視パラメータ<br>
複雑なロジックや長い起動時間を持つ重いスクリプトを持つ場合、深刻な問題となる可能性があります。<br>

ローダブルモジュールのサポートは、パフォーマンスを犠牲にすることなく、Zabbixエージェント、server 、proxy を<br>
拡張する方法を提供します。<br>

ローダブルモジュールとは、基本的にZabbixデーモンが使用する共有ライブラリで、起動時にロードされます。<br>
ライブラリには特定の関数が含まれている必要があり、Zabbixプロセスはファイルが本当にロードして動作するモジュールで<br>
あることを検出することができます。<br>

ロード可能なモジュールには多くの利点があります。優れたパフォーマンスや任意のロジックを実装できることも非常に重要ですが、<br>
おそらく最も重要な利点は、Zabbixモジュールを開発、利用、共有できることです。これはトラブルのないメンテナンスに貢献し、<br>
Zabbixのコアコードベースから独立して、より簡単に新しい機能を提供するのに役立ちます。<br>

モジュールのライセンスとバイナリ形式での配布はGPLライセンスに準拠します（モジュールはランタイムにZabbixとリンクし、<br>
Zabbixヘッダーを使用しています。）バイナリ互換性はZabbixによって保証されていません。<br>

モジュールAPIの安定性はZabbix LTS(Long Term Support) [release](http://www.zabbix.com/life_cycle_and_release_policy)の1サイクルにおいて保証されます。<br>
Zabbix APIの安定性は保証されていません(技術的にはモジュールからZabbix内部関数を呼び出すことは可能ですが、そのようなモジュールが<br>
動作する保証はありません)。<br>

[comment]: # ({/d5349b7c-00b6a45a})

[comment]: # ({d4859c64-6a7ad616})
#### モジュールAPI

共有ライブラリをZabbixモジュールとして扱うには、いくつかの関数を実装し、エクスポートする必要があります。<br>
現在、ZabbixモジュールAPIには6つの関数があり、そのうち1つだけが必須で、他の5つはオプションです。

[comment]: # ({/d4859c64-6a7ad616})

[comment]: # ({1d82f642-8ec4ecb3})
##### 必須インターフェース

必須の関数は **zbx_module_api_version()** だけです。

``` {.c}
int zbx_module_api_version(void);
```

この関数は、このモジュールが実装しているAPIバージョンを返し、モジュールをロードするためには、このバージョンが<br>
ZabbixがサポートするモジュールAPIバージョンと一致する必要があります。Zabbix がサポートするモジュール API のバージョンは、<br>
ZBX_MODULE_API_VERSION です。したがって、この関数はこの定数を返す必要があります。この目的で使用されていた古い定数<br>
ZBX_MODULE_API_VERSION_ONEは、ソースの互換性を保つためにZBX_MODULE_API_VERSIONと同じに定義されていますが、<br>
この使用は推奨されません。<br>

[comment]: # ({/1d82f642-8ec4ecb3})

[comment]: # ({65bb6af0-3766a85e})
##### - オプションのインターフェース

オプションのインターフェースは、 以下の通りです。
**zbx\_module\_init()** , **zbx\_module\_item\_list()** ,  **zbx\_module\_item\_timeout()** , **zbx\_module\_history\_write\_cbs()**, **zbx\_module\_uninit()**

``` {.c}
int zbx_module_init(void);
```

この関数は、モジュールに必要な初期化を行います(もしあれば)。成功した場合は、ZBX_MODULE_OK を返します。<br>
失敗した場合、ZBX_MODULE_FAIL を返します。後者の場合、Zabbix は起動しません。<br>

``` {.c}
ZBX_METRIC  *zbx_module_item_list(void);
```

この関数は、モジュールがサポートする item のリストを返す必要があります。
各項目は ZBX_METRIC 構造体で定義されます。リストの最後には、"key "フィールドがNULLのZBX_METRIC構造体を返します。

``` {.c}
void    zbx_module_item_timeout(int timeout);
```

モジュールが **zbx_module_item_list()** をエクスポートしている場合、この関数はZabbixによって使用されます。<br>
モジュールが実装する item チェックが従うべきタイムアウト設定をZabbix設定ファイルで指定するために使用されます。<br>
ここで、"timeout "パラメータは秒単位です。<br>

``` {.c}
ZBX_HISTORY_WRITE_CBS   zbx_module_history_write_cbs(void);
```

この関数は、Zabbix サーバが異なるデータ型の history をエクスポートする際に使用するコールバック関数を返します。<br>
コールバック関数はZBX_HISTORY_WRITE_CBS構造体のフィールドとして提供され、モジュールが特定のタイプの history に<br>
興味がない場合、フィールドはNULLにすることが可能です。<br>

``` {.c}
int zbx_module_uninit(void);
```

この関数は、割り当てられたリソースの解放、ファイルディスクリプタのクローズなど、必要な初期化を行います。

すべての関数は、Zabbix起動時にモジュールがロードされると一度だけ呼び出されます。
zbx_module_uninit() は Zabbix のシャットダウン時にモジュールがアンロードされると一度だけ呼び出されます。

[comment]: # ({/65bb6af0-3766a85e})

[comment]: # ({28f67f16-89241080})
##### item の定義

各 item は、ZBX_METRIC 構造体で定義されます。

``` {.c}
typedef struct
{
    char        *key;
    unsigned    flags;
    int     (*function)();
    char        *test_param;
}
ZBX_METRIC;
```

ここで、**key** は item のキー(例えば "dummy.random") で、**flags** は CF_HAVEPARAMS または 0 <br> 
(item がパラメータを受け入れるかどうかに依存) 、**function** は項目を実装する C 関数です。 <br>
item (例：zbx_module_dummy_random), **test_param** は、Zabbix agent を「-p」フラグで起動したときに <br>
使用されるパラメータリストです(例: 「1,1000」、NULLも可能) <br>

定義例は以下のとおりです。このようになります。

``` {.c}
static ZBX_METRIC keys[] =
{
    { "dummy.random", CF_HAVEPARAMS, zbx_module_dummy_random, "1,1000" },
    { NULL }
}
```

項目を実装する各関数は、2つのポインタパラメータを受け取る必要があります。 <br> 
パラメータを受け取る必要があります。1つ目は AGENT_REQUEST 型、2つ目は タイプAGENT_RESULTです。 <br> 

``` {.c}
int zbx_module_dummy_random(AGENT_REQUEST *request, AGENT_RESULT *result)
{
    ...

    SET_UI64_RESULT(result, from + rand() % (to - from + 1));

    return SYSINFO_RET_OK;
}
```

これらの関数は項目の値が正常に取得された場合は SYSINFO_RET_OK を返します。それ以外の場合は SYSINFO_RET_FAIL を返します。 <br> AGENT_REQUEST から情報を取得する方法と、AGENT_RESULT に情報を設定する方法の詳細については、 <br> 
以下のサンプル "dummy" モジュールを参照してください。<br> 

[comment]: # ({/28f67f16-89241080})

[comment]: # ({d6981240-79a740f6})
##### - history のエクスポートコールバックを提供する

::: noteimportant
モジュール経由の履歴エクスポートはZabbix 4.0.0以降、Zabbixプロキシではサポートされなくなりました。
:::

モジュールはhistory データをエクスポートする関数をタイプ別に指定することができます。<br>
数値(float)、Numeric (unsigned)、Character、Text、Log<br>

``` {.c}
typedef struct
{
    void    (*history_float_cb)(const ZBX_HISTORY_FLOAT *history, int history_num);
    void    (*history_integer_cb)(const ZBX_HISTORY_INTEGER *history, int history_num);
    void    (*history_string_cb)(const ZBX_HISTORY_STRING *history, int history_num);
    void    (*history_text_cb)(const ZBX_HISTORY_TEXT *history, int history_num);
    void    (*history_log_cb)(const ZBX_HISTORY_LOG *history, int history_num);
}
ZBX_HISTORY_WRITE_CBS;
```

それぞれ、"history_num" 要素の "history" 配列を引数として受け取る必要があります。<br>
エクスポートされる history のデータ型に応じて、"history" は以下の構造体の配列となります。<br>

``` {.c}
typedef struct
{
    zbx_uint64_t    itemid;
    int     clock;
    int     ns;
    double      value;
}
ZBX_HISTORY_FLOAT;

typedef struct
{
    zbx_uint64_t    itemid;
    int     clock;
    int     ns;
    zbx_uint64_t    value;
}
ZBX_HISTORY_INTEGER;

typedef struct
{
    zbx_uint64_t    itemid;
    int     clock;
    int     ns;
    const char  *value;
}
ZBX_HISTORY_STRING;

typedef struct
{
    zbx_uint64_t    itemid;
    int     clock;
    int     ns;
    const char  *value;
}
ZBX_HISTORY_TEXT;

typedef struct
{
    zbx_uint64_t    itemid;
    int     clock;
    int     ns;
    const char  *value;
    const char  *source;
    int     timestamp;
    int     logeventid;
    int     severity;
}
ZBX_HISTORY_LOG;
```

コールバックはZabbix server の history 同期プロセスで使用されます。<br>
Zabbixデータベースにデータが書き込まれ、値キャッシュに保存された後、history 同期処理の終了時に使用されます。<br>

:::noteimportant
history エクスポートモジュールに内部エラーが発生した場合、回復するまで監視全体をブロックするのではなく、<br>
代わりにデータを破棄してZabbixサーバの実行を継続させるようにモジュールを記述することを推奨します。<br>
:::

[comment]: # ({/d6981240-79a740f6})

[comment]: # ({761ff5f8-c5011135})
##### モジュールのビルド

現在、モジュールはZabbixのソースツリー内でビルドされることになっています。<br>
なぜなら、モジュールAPIはZabbixヘッダで定義されているいくつかのデータ構造に依存しているからです。<br>

ロード可能なモジュールにとって最も重要なヘッダーは、これらのデータ構造を定義している**include/module.h**です。<br>
**include/module.h**が正しく動作するために必要な他のシステムヘッダは、**stdlib.h**と**stdint.h**です。<br>

この情報を頭に入れれば、モジュールをビルドするための準備はすべて整ったことになります。<br>
モジュールは、**stdlib.h**、**stdint.h**、**module.h** が含まれている必要があり、ビルドスクリプトは、<br>
これらのファイルがインクルードパスにあることを確認する必要があります。<br>
詳細については、以下の "ダミー" モジュールの例を参照してください。<br>

このヘッダには、ロギングとデバッグに使用できる **zabbix_log() ** 関数が定義されています<br>

[comment]: # ({/761ff5f8-c5011135})

[comment]: # ({108ff5e0-321e0a01})
#### 設定パラメータ

Zabbix agent、server、proxyは、モジュールを処理するために2つの[parameters](/manual/appendix/config/zabbix_server)をサポートしています。

- LoadModulePath - ロード可能なモジュールの場所へのフルパスです。<br>
- LoadModule - 起動時にロードするモジュール。モジュールは、LoadModulePath で指定されたディレクトリに配置されているか、<br>
  パスがモジュール名より前にある必要があります。先行するパスが絶対パス（'/' で始まる）の場合、LoadModulePath は無視されます。<br>
  複数の LoadModule パラメータを含めることができます。<br>

例えば、Zabbixエージェントを拡張する場合、以下のように追加することができます。

    LoadModulePath=/usr/local/lib/zabbix/agent/ 
    LoadModule=mariadb.so
    LoadModule=apache.so
    LoadModule=kernel.so
    LoadModule=/usr/local/lib/zabbix/dummy.so

エージェントの起動時に、/usr/local/lib/zabbix/agent ディレクトリから mariadb.so, apache.so, kernel.so モジュールをロードし、<br> /usr/local/lib/zabbix からは dummy.so をロードします。モジュールが見つからない場合、不正なパーミッションの場合、<br>
共有ライブラリがZabbixモジュールでない場合、失敗します。

[comment]: # ({/108ff5e0-321e0a01})

[comment]: # ({2299cc99-39cdb2c0})
#### フロントエンドの設定

ローダブルモジュールはZabbix agent、server、proxyでサポートされているため、Zabbixフロントエンドの item タイプは
モジュールがロードされる場所に依存します。モジュールが agent にロードされている場合、item のタイプは
"Zabbix agent" または "Zabbix agent(active)" になります。モジュールが server または proxy にロードされている場合、
item のタイプは "シンプルチェック" になります。

Zabbixモジュールによる history のエクスポートには、フロントエンドの設定は必要ありません。
モジュールが server に正常にロードされ、少なくとも1つの非NULLコールバック関数を返す **zbx_module_history_take_cbs()** 関数を
提供する場合、history のエクスポートが自動的に有効化されます。

[comment]: # ({/2299cc99-39cdb2c0})

[comment]: # ({a7ef8e18-d5f54a51})
#### - ダミーモジュール

ZabbixにはC言語で書かれたサンプルモジュールが含まれています。このモジュールはsrc/modules/dummyにあります:

    alex@alex:~trunk/src/modules/dummy$ ls -l
    -rw-rw-r-- 1 alex alex 9019 Apr 24 17:54 dummy.c
    -rw-rw-r-- 1 alex alex   67 Apr 24 17:54 Makefile
    -rw-rw-r-- 1 alex alex  245 Apr 24 17:54 README

このモジュールはドキュメントが充実しており、独自のモジュールのテンプレートとして使用することができます。

上記のようにZabbixソースツリーのルートで./configureを実行した後、**make**を実行し、**dummy.so**をビルドしてください。

``` {.c}
/*
** Zabbix
** Copyright (C) 2001-2020 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
**/

#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdint.h>

#include "module.h"

/* the variable keeps timeout setting for item processing */
static int  item_timeout = 0;

/* module SHOULD define internal functions as static and use a naming pattern different from Zabbix internal */
/* symbols (zbx_*) and loadable module API functions (zbx_module_*) to avoid conflicts                       */
static int  dummy_ping(AGENT_REQUEST *request, AGENT_RESULT *result);
static int  dummy_echo(AGENT_REQUEST *request, AGENT_RESULT *result);
static int  dummy_random(AGENT_REQUEST *request, AGENT_RESULT *result);

static ZBX_METRIC keys[] =
/*  KEY         FLAG        FUNCTION    TEST PARAMETERS */
{
    {"dummy.ping",      0,      dummy_ping, NULL},
    {"dummy.echo",      CF_HAVEPARAMS,  dummy_echo, "a message"},
    {"dummy.random",    CF_HAVEPARAMS,  dummy_random,   "1,1000"},
    {NULL}
};

/******************************************************************************
 *                                                                            *
 * Function: zbx_module_api_version                                           *
 *                                                                            *
 * Purpose: returns version number of the module interface                    *
 *                                                                            *
 * Return value: ZBX_MODULE_API_VERSION - version of module.h module is       *
 *               compiled with, in order to load module successfully Zabbix   *
 *               MUST be compiled with the same version of this header file   *
 *                                                                            *
 ******************************************************************************/
int zbx_module_api_version(void)
{
    return ZBX_MODULE_API_VERSION;
}

/******************************************************************************
 *                                                                            *
 * Function: zbx_module_item_timeout                                          *
 *                                                                            *
 * Purpose: set timeout value for processing of items                         *
 *                                                                            *
 * Parameters: timeout - timeout in seconds, 0 - no timeout set               *
 *                                                                            *
 ******************************************************************************/
void    zbx_module_item_timeout(int timeout)
{
    item_timeout = timeout;
}

/******************************************************************************
 *                                                                            *
 * Function: zbx_module_item_list                                             *
 *                                                                            *
 * Purpose: returns list of item keys supported by the module                 *
 *                                                                            *
 * Return value: list of item keys                                            *
 *                                                                            *
 ******************************************************************************/
ZBX_METRIC  *zbx_module_item_list(void)
{
    return keys;
}

static int  dummy_ping(AGENT_REQUEST *request, AGENT_RESULT *result)
{
    SET_UI64_RESULT(result, 1);

    return SYSINFO_RET_OK;
}

static int  dummy_echo(AGENT_REQUEST *request, AGENT_RESULT *result)
{
    char    *param;

    if (1 != request→nparam)
    {
        /* set optional error message */
        SET_MSG_RESULT(result, strdup("Invalid number of parameters."));
        return SYSINFO_RET_FAIL;
    }

    param = get_rparam(request, 0);

    SET_STR_RESULT(result, strdup(param));

    return SYSINFO_RET_OK;
}

/******************************************************************************
 *                                                                            *
 * Function: dummy_random                                                     *
 *                                                                            *
 * Purpose: a main entry point for processing of an item                      *
 *                                                                            *
 * Parameters: request - structure that contains item key and parameters      *
 *              request→key - item key without parameters                    *
 *              request→nparam - number of parameters                        *
 *              request→params[N-1] - pointers to item key parameters        *
 *              request→types[N-1] - item key parameters types:              *
 *                  REQUEST_PARAMETER_TYPE_UNDEFINED (key parameter is empty) *
 *                  REQUEST_PARAMETER_TYPE_ARRAY (array)                      *
 *                  REQUEST_PARAMETER_TYPE_STRING (quoted or unquoted string) *
 *                                                                            *
 *             result - structure that will contain result                    *
 *                                                                            *
 * Return value: SYSINFO_RET_FAIL - function failed, item will be marked      *
 *                                 as not supported by zabbix                 *
 *               SYSINFO_RET_OK - success                                     *
 *                                                                            *
 * Comment: get_rparam(request, N-1) can be used to get a pointer to the Nth  *
 *          parameter starting from 0 (first parameter). Make sure it exists  *
 *          by checking value of request→nparam.                             *
 *          In the same manner get_rparam_type(request, N-1) can be used to   *
 *          get a parameter type.                                             *
 *                                                                            *
 ******************************************************************************/
static int  dummy_random(AGENT_REQUEST *request, AGENT_RESULT *result)
{
    char    *param1, *param2;
    int from, to;

    if (2 != request→nparam)
    {
        /* set optional error message */
        SET_MSG_RESULT(result, strdup("Invalid number of parameters."));
        return SYSINFO_RET_FAIL;
    }

    param1 = get_rparam(request, 0);
    param2 = get_rparam(request, 1);

    /* there is no strict validation of parameters and types for simplicity sake */
    from = atoi(param1);
    to = atoi(param2);

    if (from > to)
    {
        SET_MSG_RESULT(result, strdup("Invalid range specified."));
        return SYSINFO_RET_FAIL;
    }

    SET_UI64_RESULT(result, from + rand() % (to - from + 1));

    return SYSINFO_RET_OK;
}

/******************************************************************************
 *                                                                            *
 * Function: zbx_module_init                                                  *
 *                                                                            *
 * Purpose: the function is called on agent startup                           *
 *          It should be used to call any initialization routines             *
 *                                                                            *
 * Return value: ZBX_MODULE_OK - success                                      *
 *               ZBX_MODULE_FAIL - module initialization failed               *
 *                                                                            *
 * Comment: the module won't be loaded in case of ZBX_MODULE_FAIL             *
 *                                                                            *
 ******************************************************************************/
int zbx_module_init(void)
{
    /* initialization for dummy.random */
    srand(time(NULL));

    return ZBX_MODULE_OK;
}

/******************************************************************************
 *                                                                            *
 * Function: zbx_module_uninit                                                *
 *                                                                            *
 * Purpose: the function is called on agent shutdown                          *
 *          It should be used to cleanup used resources if there are any      *
 *                                                                            *
 * Return value: ZBX_MODULE_OK - success                                      *
 *               ZBX_MODULE_FAIL - function failed                            *
 *                                                                            *
 ******************************************************************************/
int zbx_module_uninit(void)
{
    return ZBX_MODULE_OK;
}

/******************************************************************************
 *                                                                            *
 * Functions: dummy_history_float_cb                                          *
 *            dummy_history_integer_cb                                        *
 *            dummy_history_string_cb                                         *
 *            dummy_history_text_cb                                           *
 *            dummy_history_log_cb                                            *
 *                                                                            *
 * Purpose: callback functions for storing historical data of types float,    *
 *          integer, string, text and log respectively in external storage    *
 *                                                                            *
 * Parameters: history     - array of historical data                         *
 *             history_num - number of elements in history array              *
 *                                                                            *
 ******************************************************************************/
static void dummy_history_float_cb(const ZBX_HISTORY_FLOAT *history, int history_num)
{
    int i;

    for (i = 0; i < history_num; i++)
    {
        /* do something with history[i].itemid, history[i].clock, history[i].ns, history[i].value, ... */
    }
}

static void dummy_history_integer_cb(const ZBX_HISTORY_INTEGER *history, int history_num)
{
    int i;

    for (i = 0; i < history_num; i++)
    {
        /* do something with history[i].itemid, history[i].clock, history[i].ns, history[i].value, ... */
    }
}

static void dummy_history_string_cb(const ZBX_HISTORY_STRING *history, int history_num)
{
    int i;

    for (i = 0; i < history_num; i++)
    {
        /* do something with history[i].itemid, history[i].clock, history[i].ns, history[i].value, ... */
    }
}

static void dummy_history_text_cb(const ZBX_HISTORY_TEXT *history, int history_num)
{
    int i;

    for (i = 0; i < history_num; i++)
    {
        /* do something with history[i].itemid, history[i].clock, history[i].ns, history[i].value, ... */
    }
}

static void dummy_history_log_cb(const ZBX_HISTORY_LOG *history, int history_num)
{
    int i;

    for (i = 0; i < history_num; i++)
    {
        /* do something with history[i].itemid, history[i].clock, history[i].ns, history[i].value, ... */
    }
}

/******************************************************************************
 *                                                                            *
 * Function: zbx_module_history_write_cbs                                     *
 *                                                                            *
 * Purpose: returns a set of module functions Zabbix will call to export      *
 *          different types of historical data                                *
 *                                                                            *
 * Return value: structure with callback function pointers (can be NULL if    *
 *               module is not interested in data of certain types)           *
 *                                                                            *
 ******************************************************************************/
ZBX_HISTORY_WRITE_CBS   zbx_module_history_write_cbs(void)
{
    static ZBX_HISTORY_WRITE_CBS    dummy_callbacks =
    {
        dummy_history_float_cb,
        dummy_history_integer_cb,
        dummy_history_string_cb,
        dummy_history_text_cb,
        dummy_history_log_cb,
    };

    return dummy_callbacks;
}
```

このモジュールでは、新たに次の3つの項目をエクスポートします。

-   `dummy.ping` - 常に '1' を返します。
-   `dummy.echo[param1]` - 1番目のパラメータをそのまま返します。
    例えば `dummy.echo[ABC]` は ABC を返します。
-   `dummy.random[param1, param2]` - 1番目の引数と2番目の引数の間の任意の整数を返します。例えば
    `dummy.random[1,1000000]`

[comment]: # ({/a7ef8e18-d5f54a51})

[comment]: # ({8bc3abc6-77f24ad1})
#### 制限事項

ローダブルモジュールのサポートは、Unix プラットフォームにのみ実装されています。<br>
つまり、Windows agent では動作しません。

場合によっては、モジュールに関連する設定パラメータを *zabbix_agentd.conf* から読み込む必要があります。<br>
現在、これはサポートされていません。モジュールで設定パラメータを使用する必要がある場合は、モジュール固有の設定ファイルのパース を実装する必要があります。

[comment]: # ({/8bc3abc6-77f24ad1})
