Модули који се могу учитати нуде опцију за проширење функционалности Zabbix-а усмерену на перформансе.
Можете проширити функционалност Zabbix-а на много начина, на пример, помоћу корисничких параметара, екстерних провера, и system.run[]
Zabbix агентских ставки. Ови функционишу веома добро, али имају један велики недостатак, наиме fork(). Zabbix мора да генерише нови процес сваки пут када обрађује корисничку метрику, што није добро за перформансе. Обично то није велики проблем, међутим, може бити озбиљан проблем приликом праћења уграђених система, са великим бројем праћених параметара или тешким скриптама са сложеном логиком или дугим временом покретања.
Подршка за модуле који се могу учитати нуди начине за проширивање Zabbix агента, сервера и проксија без жртвовања перформанси.
Модул који се може учитати је у основи дељена библиотека коју користи Zabbix демон и учитава се при покретању. Библиотека треба да садржи одређене функције, тако да Zabbix процес може да детектује да је датотека заиста модул који може да учита и са којим може да ради.
Модули који се могу учитати имају бројне предности. Одличне перформансе и способност имплементације било које логике су веома важне, али можда најважнија предност је могућност развоја, коришћења и дељења Zabbix модула. То доприноси одржавању без проблема и помаже у лакшој испоруци нове функционалности и независно од основне базе кода Zabbix-а.
Лиценцирање и дистрибуција модула у бинарном облику регулисани су AGPL-3.0 лиценцом (модули се повезују са Zabbix-ом током извршавања и користе Zabbix заглавља; цео Zabbix код је лиценциран под AGPL-3.0 лиценцом од Zabbix-а 7.0). Zabbix не гарантује компатибилност бинарних датотека.
Стабилност API-ја модула је гарантована током једног циклуса издања Zabbix LTS (дугорочне подршке) (http://www.zabbix.com/life_cycle_and_release_policy). Стабилност Zabbix API-ја није гарантована (технички је могуће позивати Zabbix интерне функције из модула, али нема гаранције да ће такви модули радити).
Да би се дељена библиотека третирала као Zabbix модул, то треба да имплементира и извезе неколико функција. Тренутно их има шест функције у API-ју Zabbix модула, од којих је само један обавезан и осталих пет је опционо.
Једина обавезна функција је zbx_module_api_version():
Ова функција треба да врати верзију API-ја коју имплементира овај модул а да би се модул учитао ова верзија мора да одговара модулу API верзија коју подржава Заббик. Верзија модула АПИ коју подржава Zabbix је 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():
Ова функција треба да изврши неопходну иницијализацију за модул (ако постоји). Ако је успешна, требало би да врати ZBX_MODULE_OK. У супротном, требало би да врати ZBX_MODULE_FAIL. У овом другом случају, Zabbix се неће покренути.
Ова функција треба да врати листу ставки које модул подржава. Свака ставка је дефинисана у ZBX_METRIC структури, погледајте одељак испод за детаље. Листа се завршава ZBX_METRIC структуром са полјем "key" вредности NULL.
Ако модул извози zbx_module_item_list(), онда Zabbix користи ову функцију да би одредио подешавања временског ограничења у Zabbix конфигурационој датотеци која провере ставки које имплементира модул треба да поштују. Овде је параметар "timeout" у секундама.
Ова функција треба да врати функције повратног позива које ће Zabbix сервер користити за извоз историје различитих типова података. Функције повратног позива су обезбеђене као поља ZBX_HISTORY_WRITE_CBS структуре, поља могу бити NULL ако модул није заинтересован за историју одређеног типа.
Ова функција треба да изврши неопходну деиницијализацију (ако постоји) као што је ослобађање додељених ресурса, затварање дескриптора датотека итд.
Све функције се позивају једном при покретању Zabbix-а када се модул учита, са изузетком zbx_module_uninit(), која се позива једном при гашењу Zabbix-а када се модул истовари.
Свака ставка је дефинисана у ZBX_METRIC структури:
Овде је key кључ ставке (нпр. "dummy.random"), flags је или CF_HAVEPARAMS или 0 (у зависности од тога да ли ставка прихвата параметре или не), function је C функција која имплементира ставку (нпр. "zbx_module_dummy_random"), а test_param је листа параметара која ће се користити када се Zabbix агент покрене са заставицом "-p" (нпр. "1,1000", може бити NULL). Пример дефиниције може изгледати овако:
static ZBX_METRIC keys[] =
{
{ "dummy.random", CF_HAVEPARAMS, zbx_module_dummy_random, "1,1000" },
{ NULL }
}
Свака функција која имплементира ставку треба да прихвати два показивач параметра, први типа AGENT_REQUEST и други типа AGENT_RESULT:
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. Погледајте пример "dummy" модула испод за детаље о томе како добити информације из AGENT_REQUEST и како подесити информације у AGENT_RESULT.
Извоз историје путем модула више није подржан од стране Zabbix проксија.
Модул може да одреди функције за извоз података историје по типу: Нумерички (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;
Сваки од њих треба да прихвати низ елемената "history_num" као аргументе. У зависности од типа података историје који се извозе, "history" је низ следећих структура, респективно:
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 сервера на крају поступка синхронизације историје након што се подаци упишу у Zabbix базу података и сачувају у кешу вредности.
У случају интерне грешке у модулу за извоз историје, препоручује се да се модул напише на такав начин да не блокира целокупно праћење док се не опорави, већ да уместо тога одбацује податке и дозвољава Zabbix серверу да настави са радом.
Модули су тренутно предвиђени за изградњу унутар 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 агент, сервер и прокси подржавају два параметра за рад са модулима:
На пример, да бисмо проширили Zabbix агент, могли бисмо додати следеће параметре:
LoadModulePath=/usr/local/lib/zabbix/agent/ LoadModule=mariadb.so LoadModule=apache.so LoadModule=kernel.so LoadModule=/usr/local/lib/zabbix/dummy.so
Приликом покретања агента, он ће учитати модуле mariadb.so, apache.so и kernel.so из директоријума /usr/local/lib/zabbix/agent, док ће dummy.so бити учитан из /usr/local/lib/zabbix. Агент се неће покренути ако модул недостаје, у случају лоших дозвола или ако дељена библиотека није Zabbix модул.
Модули који се могу учитати подржавају Zabbix агент, сервер и прокси. Стога, тип ставке у Zabbix кориснички интерфејс зависи од тога где је модул учитан. Ако је модул учитан у агента, онда тип ставке треба да буде "Zabbix агент" или "Zabbix агент (активан)". Ако је модул учитан у сервер или прокси, онда тип ставке треба да буде "Једноставна провера".
Извоз историје путем Zabbix модула не захтева никакву конфигурацију фронтенда. Ако је модул успешно учитан од стране сервера и пружа функцију zbx_module_history_write_cbs() која враћа барем једну функцију повратног позива која није NULL, онда ће извоз историје бити аутоматски омогућен.
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
Модул је добро документован, може се користити као шаблон за ваше сопствене модуле.
Након што је ./configure покренут у корену Zabbix изворног стабла као описано горе, само покрените 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;
}
Модул извози три нове ставке: - dummy.ping
- увек враћа '1' - dummy.echo[param1]
- враћа први параметар какав јесте, нпр. пример, dummy.echo[ABC]
вратиће ABC - dummy.random[param1, param2]
- враћа случајни број унутар опсег param1-param2, на пример, dummy.random[1,1000000]
Подршка учитавих модула је имплементирана само за Unix платформу. То значи да не ради за Windows агенте.
У неким случајевима модул ће можда морати да прочита конфигурацију везану за модул параметри из zabbix_agentd.conf. Тренутно није подржан. Ако потребан вам је модул да бисте користили неке параметре конфигурације које бисте требали вероватно имплементирати рашчлањивање конфигурационе датотеке специфичне за модул.