可加载模块为扩展Zabbix功能提供了一种注重性能的选项。
您可以通过多种方式extend来扩展Zabbix功能,例如, 使用user parameters、 external checks, 以及通过执行system.run[]
脚本的Zabbix agent items。 这些方法通常运行良好,但有一个主要缺点,即fork()。Zabbix每次处理用户指标时都必须派生一个新进程,这对性能不利。通常情况下这并不是大问题,但在监控嵌入式系统、监控参数数量庞大、脚本逻辑复杂或启动时间较长的情况下,这可能会成为一个严重的问题。
支持可加载模块提供了一种在不牺牲性能的前提下扩展Zabbix Zabbix agent、 服务器和proxy的方法。
可加载模块本质上是一个共享库,被Zabbix守护进程使用,并在启动时加载。该库应包含某些特定函数,以便Zabbix进程能够识别该file确实是一个可以加载和使用的模块。
可加载模块具有多项优势。卓越的性能和实现任意逻辑的能力非常重要,但也许最重要的优势是能够开发、使用和共享Zabbix模块。这有助于无故障维护,并帮助更轻松、独立于Zabbix核心代码库地交付新功能。
模块的许可和二进制形式的分发受AGPL-3.0许可证的约束(模块在运行时与Zabbix链接并使用Zabbix头文件;整个Zabbix代码自Zabbix 7.0起均受AGPL-3.0许可证的保护)。Zabbix不保证二进制兼容性。
模块API的稳定性在一个Zabbix长期支持(LTS,Long Term Support)release周期内得到保证。Zabbix API的稳定性不作保证(从技术上讲,模块中可以调用Zabbix的内部函数,但无法保证此类模块能够正常工作)。
为了让一个共享库被视为 Zabbix 模块,它需要实现并export若干函数。当前 Zabbix 模块的API中有六个函数,其中仅有一个是必需的,其余五个是可选的。
唯一必选的函数是 zbx_module_api_version():
该函数应返回此模块实现的 API version,并且为了加载该模块,此 version 必须与 Zabbix 支持的模块 API version 相匹配。Zabbix 支持的模块 API 版本为 ZBX_MODULE_API_VERSION。因此,该函数应返回此常量。旧常量 ZBX_MODULE_API_VERSION_ONE 曾用于此目的,现在已定义为等同于 ZBX_MODULE_API_VERSION 以保持源代码兼容性,但不建议使用。
可选函数包括 zbx_module_init()、
zbx_module_item_list()、zbx_module_item_timeout()、
zbx_module_history_write_cbs() 和 zbx_module_uninit():
This function should perform the necessary initialization for the module (if any). If successful, it should return ZBX_MODULE_OK. Otherwise, it should return ZBX_MODULE_FAIL. In the latter case Zabbix will not start.
{.c}
ZBX_METRIC *zbx_module_item_list(void);
This function should return a list of items supported by the module. Each item is defined in a ZBX_METRIC structure, see the section below for details. The list is terminated by a ZBX_METRIC structure with "key" field of NULL.
{.c}
void zbx_module_item_timeout(int timeout);
If module exports zbx_module_item_list() then this function is used by Zabbix to specify the timeout settings in Zabbix configuration file that the item checks implemented by the module should obey. Here, the "timeout" parameter is in seconds.
{.c}
ZBX_HISTORY_WRITE_CBS zbx_module_history_write_cbs(void);
This function should return callback functions Zabbix server will use to export history of different data types. Callback functions are provided as fields of ZBX_HISTORY_WRITE_CBS structure, fields can be NULL if module is not interested in the history of certain type.
{.c}
int zbx_module_uninit(void);
该函数应执行必要的反初始化操作(如果有的话),例如释放已分配的资源、关闭 file 描述符等。
所有函数在 Zabbix 启动加载模块时调用一次,而 zbx_module_uninit() 除外,它在 Zabbix 关闭卸载模块时调用一次。
每个 监控项 都在 ZBX_METRIC 结构中定义:
Here, key is the item key (e.g., "dummy.random"), flags is either CF_HAVEPARAMS or 0 (depending on whether the item accepts parameters or not), function is a C function that implements the item (e.g., "zbx_module_dummy_random"), and test_param is the parameter list to be used when Zabbix agent is started with the "-p" flag (e.g., "1,1000", can be NULL). An example definition may look like this:
{.c}
static ZBX_METRIC keys[] =
{
{ "dummy.random", CF_HAVEPARAMS, zbx_module_dummy_random, "1,1000" },
{ NULL }
}
Each function that implements an item should accept two pointer parameters, the first one of type AGENT_REQUEST and the second one of type AGENT_RESULT:
{.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。有关如何从 Agent_REQUEST 获取信息以及如何在 Agent_RESULT 中设置信息的详细信息,请参见下面的示例 "dummy" 模块。
通过模块的 export 历史数据方式已不再被 Zabbix proxy 支持。
模块可以按类型指定用于 export 历史数据的函数:数值(float)、数值(无符号)、字符、文本和日志:
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;
Each of them should take "history" array of "history_num" elements as arguments. Depending on history data type to be exported, "history" is an array of the following structures, respectively:
{.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 数据库并保存在 value cache 中后,回调将被 Zabbix server 历史同步进程在历史同步过程结束时使用。
如果历史 export 模块发生内部错误,建议模块设计为不阻塞整个监控直到恢复,而是丢弃数据并允许 Zabbix server 继续运行。
模块目前应在 Zabbix 源代码树内构建,因为模块 API 依赖于一些在 Zabbix 头文件中定义的数据结构。
对于可加载模块而言,最重要的头文件是 include/module.h,它定义了这些数据结构。帮助 include/module.h 正常工作的其他必要系统头文件包括 stdlib.h 和 stdint.h。
有了以上信息后,模块的构建准备工作已经就绪。模块应包含 stdlib.h、stdint.h 和 module.h,并且构建脚本应确保这些文件位于包含路径中。有关详细信息,请参见下面的示例“dummy”模块。
另一个有用的头文件是 include/zbxcommon.h,它定义了 zabbix_log() 函数,可用于日志记录和调试目的。
Zabbix agent、server 和 proxy 支持两种 parameters 来处理模块:
例如,要扩展 Zabbix agent,我们可以添加以下参数:
LoadModulePath=/usr/local/lib/zabbix/agent/
LoadModule=mariadb.so
LoadModule=apache.so
LoadModule=kernel.so
LoadModule=/usr/local/lib/zabbix/dummy.so
在 agent 启动时,它将从 /usr/local/lib/zabbix/agent 目录加载 mariadb.so、apache.so 和 kernel.so 模块,而 dummy.so 将从 /usr/local/lib/zabbix 加载。如果模块缺失、权限错误或共享库不是 Zabbix 模块,则 agent 将无法启动。
可加载模块受 Zabbix agent、服务器和 proxy 支持。 因此,Zabbix 前端中的 监控项 类型取决于模块加载的位置。如果模块加载到 agent 中, 则 监控项 类型应为 "Zabbix agent" 或 "Zabbix agent (active)"。 如果模块加载到 server 或 proxy 中,则 监控项 类型应为 "Simple check"。
通过 Zabbix 模块进行的历史 export 不需要任何前端配置。如果模块被服务器成功加载, 并且提供了返回至少一个非 NULL 回调函数的 zbx_module_history_write_cbs() 函数, 则历史 export 将自动启用。
Zabbix包含一个用C语言编写的示例模块。该模块 位于 src/modules/dummy 目录下
alex@alex:~trunk/src/modules/dummy$ ls -l
-rw-rw-r-- 1 alex alex 9019 4月 24 17:54 dummy.c
- rw-rw-r-- 1 alex alex 67 4月 24 17:54 Makefile
-rw-rw-r-- 1 alex alex 245 4月 24 17:54 README
该模块文档完善,可作为您自定义模块的模板 模块
在Zabbix源代码树的根目录中执行完./configure run后 如上所述,只需run make 命令即可构建 dummy.so。
/*
** 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;
}
该模块导出三个新的监控项:
可加载模块的支持仅在 Unix 平台上实现。 这意味着它在 Windows 上不可用 agents。
在某些情况下,模块可能需要从 zabbix_agentd.conf 中读取与模块相关的配置参数。 当前不支持此功能。如果你希望你的模块使用某些配置参数,你应该实现对模块专用配置文件的解析功能。