1 Ielādējamie moduļi

Pārskats

Ielādējamie moduļi piedāvā uz veiktspēju orientētu iespēju paplašināt Zabbix funkcionalitāti.

Jūs varat paplašināt Zabbix funkcionalitāti daudzos veidos, piemēram, ar lietotāja parametriem, ārējām pārbaudēm un Zabbix aģents vienumiem system.run. Tie darbojas ļoti labi, taču tiem ir viens būtisks trūkums, proti, fork(). Zabbix ir jāizveido jauns process katru reizi, kad tas apstrādā lietotāja metriku, un tas nav labi veiktspējai. Parasti tā nav liela problēma, tomēr tā var kļūt par nopietnu jautājumu, uzraugot iegultās sistēmas, ja ir liels skaits uzraugāmo parametru vai tiek izmantoti smagnēji skripti ar sarežģītu loģiku vai ilgu palaišanas laiku.

Ielādējamo moduļu atbalsts piedāvā veidus, kā paplašināt Zabbix aģents, serveris un starpniekserveris, nezaudējot veiktspēju.

Ielādējamais modulis būtībā ir koplietojama bibliotēka, ko izmanto Zabbix dēmons un kas tiek ielādēta palaišanas laikā. Bibliotēkai ir jāsatur noteiktas funkcijas, lai Zabbix process varētu noteikt, ka fails patiešām ir modulis, ko tas var ielādēt un izmantot.

Ielādējamiem moduļiem ir vairākas priekšrocības. Liela veiktspēja un iespēja īstenot jebkādu loģiku ir ļoti svarīgas, taču, iespējams, vissvarīgākā priekšrocība ir iespēja izstrādāt, izmantot un koplietot Zabbix moduļus. Tas veicina bezproblēmu uzturēšanu un palīdz vieglāk nodrošināt jaunu funkcionalitāti neatkarīgi no Zabbix pamata koda bāzes.

Moduļu licencēšanu un izplatīšanu binārā formā regulē AGPL-3.0 licence (moduļi izpildlaikā tiek sasaistīti ar Zabbix un izmanto Zabbix galvenes; viss Zabbix kods ir licencēts saskaņā ar AGPL-3.0 licenci kopš Zabbix 7.0). Binārā saderība Zabbix netiek garantēta.

Moduļu API stabilitāte tiek garantēta viena Zabbix LTS (Long Term Support) izlaiduma cikla laikā. Zabbix API stabilitāte netiek garantēta (tehniski no moduļa ir iespējams izsaukt Zabbix iekšējās funkcijas, taču nav garantijas, ka šādi moduļi darbosies).

Moduļa API

Lai koplietojamo bibliotēku varētu uzskatīt par Zabbix moduli, tai jāievieš un jāeksportē vairākas funkcijas. Pašlaik Zabbix moduļa API ir sešas funkcijas, no kurām tikai viena ir obligāta, bet pārējās piecas ir neobligātas.

Obligātā saskarne

Vienīgā obligātā funkcija ir zbx_module_api_version():

int zbx_module_api_version(void);

Šai funkcijai jāatgriež šī moduļa ieviestā API versija, un, lai moduli varētu ielādēt, šai versijai jāsakrīt ar Zabbix atbalstīto moduļa API versiju. Zabbix atbalstītā moduļa API versija ir ZBX_MODULE_API_VERSION. Tāpēc šai funkcijai jāatgriež šī konstante. Vecā konstante ZBX_MODULE_API_VERSION_ONE, kas tika izmantota šim nolūkam, tagad ir definēta kā vienāda ar ZBX_MODULE_API_VERSION, lai saglabātu pirmkoda saderību, taču tās lietošana nav ieteicama.

Neobligātā saskarne

Neobligātās funkcijas ir zbx_module_init(), zbx_module_item_list(), zbx_module_item_timeout(), zbx_module_history_write_cbs() un zbx_module_uninit():

int zbx_module_init(void);

Šai funkcijai jāveic modulim nepieciešamā inicializācija (ja tāda ir). Veiksmes gadījumā tai jāatgriež ZBX_MODULE_OK. Pretējā gadījumā tai jāatgriež ZBX_MODULE_FAIL. Pēdējā gadījumā Zabbix nestartēsies.

ZBX_METRIC  *zbx_module_item_list(void);

Šai funkcijai jāatgriež moduļa atbalstīto vienumu saraksts. Katrs vienums ir definēts ZBX_METRIC struktūrā; sīkāku informāciju skatiet tālāk esošajā sadaļā. Saraksts beidzas ar ZBX_METRIC struktūru, kuras lauka "key" vērtība ir NULL.

void    zbx_module_item_timeout(int timeout);

Ja modulis eksportē zbx_module_item_list(), tad Zabbix izmanto šo funkciju, lai norādītu Zabbix konfigurācijas failā iestatīto noildzi, kas jāievēro moduļa realizētajām vienumu pārbaudēm. Šeit parametrs "timeout" ir sekundēs.

ZBX_HISTORY_WRITE_CBS   zbx_module_history_write_cbs(void);

Šai funkcijai jāatgriež atgriezeniskā izsaukuma funkcijas, ko Zabbix serveris izmantos dažādu datu tipu vēstures eksportēšanai. Atgriezeniskā izsaukuma funkcijas ir norādītas kā ZBX_HISTORY_WRITE_CBS struktūras lauki; lauki var būt NULL, ja moduli neinteresē noteikta tipa vēsture.

int zbx_module_uninit(void);

Šai funkcijai jāveic nepieciešamā deinicializācija (ja tāda ir), piemēram, jāatbrīvo piešķirtie resursi, jāaizver failu deskriptori utt.

Visas funkcijas tiek izsauktas vienu reizi Zabbix palaišanas laikā, kad modulis tiek ielādēts, izņemot zbx_module_uninit(), kas tiek izsaukta vienu reizi Zabbix apturēšanas laikā, kad modulis tiek izlādēts.

Vienumu definēšana

Katrs vienums tiek definēts ZBX_METRIC struktūrā:

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

Šeit key ir vienuma atslēga (piemēram, "dummy.random"), flags ir vai nu CF_HAVEPARAMS, vai 0 (atkarībā no tā, vai vienums pieņem parametrus), function ir C funkcija, kas realizē vienumu (piemēram, "zbx_module_dummy_random"), un test_param ir parametru saraksts, kas jāizmanto, kad Zabbix aģents tiek palaists ar karodziņu "-p" (piemēram, "1,1000", var būt NULL). Definīcijas piemērs var izskatīties šādi:

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

Katrai funkcijai, kas realizē vienumu, jāpieņem divi rādītāja parametri: pirmais ar tipu AGENT_REQUEST un otrais ar tipu 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;
}

Šīm funkcijām jāatgriež SYSINFO_RET_OK, ja vienuma vērtība tika veiksmīgi iegūta. Pretējā gadījumā tām jāatgriež SYSINFO_RET_FAIL. Sīkāku informāciju par to, kā iegūt informāciju no AGENT_REQUEST un kā iestatīt informāciju AGENT_RESULT, skatiet tālāk esošajā moduļa "dummy" piemērā.

Vēstures eksportēšanas atgriezenisko izsaukumu nodrošināšana

Vēstures eksportēšana, izmantojot moduli, vairs netiek atbalstīta Zabbix starpniekserverī.

Modulis var norādīt funkcijas vēstures datu eksportēšanai pēc tipa: Numeric (float), Numeric (unsigned), Character, Text un 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;

Katrai no tām kā argumenti jāpieņem "history" masīvs ar "history_num" elementiem. Atkarībā no eksportējamā vēstures datu tipa "history" ir attiecīgi šādu struktūru masīvs:

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;

Atgriezeniskie izsaukumi tiks izmantoti Zabbix servera vēstures sinhronizētāja procesos vēstures sinhronizācijas procedūras beigās pēc tam, kad dati ir ierakstīti Zabbix datubāzē un saglabāti vērtību kešatmiņā.

Ja vēstures eksportēšanas modulī rodas iekšēja kļūda, ieteicams moduli izstrādāt tā, lai tas nebloķētu visu uzraudzību līdz atkopšanai, bet tā vietā atmestu datus un ļautu Zabbix serverim turpināt darbību.

Moduļu veidošana

Pašlaik moduļus ir paredzēts veidot Zabbix pirmkoda kokā, jo moduļa API ir atkarīgs no dažām datu struktūrām, kas ir definētas Zabbix galvenēs.

Svarīgākā galvene ielādējamiem moduļiem ir include/module.h, kas definē šīs datu struktūras. Citas nepieciešamās sistēmas galvenes, kas palīdz include/module.h darboties pareizi, ir stdlib.h un stdint.h.

Ņemot vērā šo informāciju, viss ir gatavs moduļa veidošanai. Modulim jāiekļauj stdlib.h, stdint.h un module.h, un veidošanas skriptam jānodrošina, ka šie faili ir iekļaušanas ceļā. Sīkāku informāciju skatiet tālāk redzamajā "dummy" moduļa piemērā.

Vēl viena noderīga galvene ir include/zbxcommon.h, kas definē funkciju zabbix_log(), kuru var izmantot žurnalēšanai un atkļūdošanai.

Konfigurācijas parametri

Zabbix aģents, serveris un starpniekserveris atbalsta divus parametrus, lai strādātu ar moduļiem:

  • LoadModulePath – pilns ceļš uz ielādējamo moduļu atrašanās vietu
  • LoadModule – modulis(-ļi), ko ielādēt startēšanas laikā. Moduļiem jāatrodas direktorijā, kas norādīta ar LoadModulePath, vai arī ceļam jābūt norādītam pirms moduļa nosaukuma. Ja iepriekš norādītais ceļš ir absolūts (sākas ar '/'), tad LoadModulePath tiek ignorēts. Ir atļauts iekļaut vairākus LoadModule parametrus.

Piemēram, lai paplašinātu Zabbix aģentu, mēs varētu pievienot šādus parametrus:

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

Aģenta startēšanas laikā tas ielādēs moduļus mariadb.so, apache.so un kernel.so no direktorija /usr/local/lib/zabbix/agent, savukārt dummy.so tiks ielādēts no /usr/local/lib/zabbix. Aģentu neizdosies palaist, ja kāds modulis trūkst, ir nepareizas piekļuves tiesības vai ja koplietojamā bibliotēka nav Zabbix modulis.

Lietotāja saskarnes konfigurācija

Ielādējamie moduļi tiek atbalstīti Zabbix aģentā, serverī un starpniekserverī. Tāpēc vienuma tips Zabbix lietotāja saskarnē ir atkarīgs no tā, kur modulis ir ielādēts. Ja modulis ir ielādēts aģentā, tad vienuma tipam jābūt "Zabbix aģents" vai "Zabbix aģents (aktīvs)". Ja modulis ir ielādēts serverī vai starpniekserverī, tad vienuma tipam jābūt "Vienkārša pārbaude".

Vēstures eksportam caur Zabbix moduļiem nav nepieciešama nekāda lietotāja saskarnes konfigurācija. Ja moduli serveris ir veiksmīgi ielādējis un tas nodrošina funkciju zbx_module_history_write_cbs(), kas atgriež vismaz vienu callback funkciju, kas nav NULL, tad vēstures eksports tiks iespējots automātiski.

Demonstrācijas modulis

Zabbix ietver C valodā rakstītu moduļa paraugu. Modulis atrodas mapē 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

Modulis ir labi dokumentēts, to var izmantot kā veidni saviem moduļiem.

Pēc tam, kad Zabbix pirmkoda koka saknē ir izpildīts ./configure, kā aprakstīts iepriekš, vienkārši palaidiet make, lai izveidotu 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;
}

Modulis eksportē trīs jaunus vienumus:

  • dummy.ping - vienmēr atgriež '1'
  • dummy.echo[param1] - atgriež pirmo parametru tādu, kāds tas ir, piemēram, dummy.echo[ABC] atgriezīs ABC
  • dummy.random[param1, param2] - atgriež nejaušu skaitli param1-param2 diapazonā, piemēram, dummy.random[1,1000000]

Ierobežojumi

Ielādējamo moduļu atbalsts ir ieviests tikai Unix platformai. Tas nozīmē, ka tas nedarbojas Windows aģentiem.

Dažos gadījumos modulim var būt nepieciešams nolasīt ar moduli saistītus konfigurācijas parametrus no zabbix_agentd.conf. Pašlaik tas netiek atbalstīts. Ja jums ir nepieciešams, lai jūsu modulis izmantotu kādus konfigurācijas parametrus, jums, iespējams, vajadzētu ieviest modulim specifiska konfigurācijas faila parsēšanu.