Модули који се могу учитати нуде опцију за проширење функционалности 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.
History export via module is no longer supported by Zabbix proxy.
Module can specify functions to export history data by type: Numeric (float), Numeric (unsigned), Character, Text and Log:
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:
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;
Callbacks will be used by Zabbix server history syncer processes in the end of history sync procedure after data is written into Zabbix database and saved in value cache.
In case of internal error in history export module, it is recommended that module is written in such a way that it does not block whole monitoring until it recovers but discards data instead and allows Zabbix server to continue running.
Модули су тренутно предвиђени за изградњу унутар 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 and proxy support two parameters to deal with modules:
For example, to extend Zabbix agent we could add the following parameters:
LoadModulePath=/usr/local/lib/zabbix/agent/
LoadModule=mariadb.so
LoadModule=apache.so
LoadModule=kernel.so
LoadModule=/usr/local/lib/zabbix/dummy.so
Upon agent startup it will load the mariadb.so, apache.so and kernel.so modules from the /usr/local/lib/zabbix/agent directory while dummy.so will be loaded from /usr/local/lib/zabbix. The agent will fail to start if a module is missing, in case of bad permissions or if a shared library is not a Zabbix module.
Zabbix агент, сервер и проки подржавају модуле који се могу учитати. Стога, тип ставке у Zabbix корисничком интерфејсу зависи од тога где се модул налази натоварен. Ако је модул учитан у агента, онда тип ставке треба да буде "Zabbix агент" или "Zabbix агент (активан)". Ако је модул учитано на сервер или прокси, онда би тип ставке требао бити "Једноставно провери".
За извоз историје преко Zabbix модула није потребан никакав кориснички интерфејс конфигурацију. Ако је сервер успешно учитао модул и пружа zbx_module_history_write_cbs() функцију која враћа најмање једна функција повратног позива која није NULL, тада ће бити извоз историје омогућено аутоматски.
Zabbix includes a sample module written in C language. The module is located under 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
The module is well documented, it can be used as a template for your own modules.
After ./configure has been run in the root of Zabbix source tree as described above, just run make in order to build 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;
}
The module exports three new items:
dummy.ping
- always returns '1'dummy.echo[param1]
- returns the first parameter as it is, for example, dummy.echo[ABC]
will return ABCdummy.random[param1, param2]
- returns a random number within the range of param1-param2, for example, dummy.random[1,1000000]
Подршка учитавих модула је имплементирана само за Unix платформу. То значи да не ради за Windows агенте.
У неким случајевима модул ће можда морати да прочита конфигурацију везану за модул параметри из zabbix_agentd.conf. Тренутно није подржан. Ако потребан вам је модул да бисте користили неке параметре конфигурације које бисте требали вероватно имплементирати рашчлањивање конфигурационе датотеке специфичне за модул.