Esta página foi traduzida automaticamente. Se você notar um erro, selecione-o e pressione Ctrl+Enter para reportá-lo aos editores.

1 Módulos carregáveis

Visão geral

Módulos carregáveis oferecem uma opção orientada para desempenho para estender a funcionalidade do Zabbix.

Você pode estender a funcionalidade do Zabbix de várias maneiras, por exemplo, com parâmetros de usuário, verificações externas, e system.run[] itens de agent do Zabbix. Esses métodos funcionam muito bem, mas têm uma grande desvantagem, que é o fork(). O Zabbix precisa criar um novo processo toda vez que lida com uma métrica de usuário, o que não é bom para o desempenho. Normalmente, isso não é um grande problema, mas pode ser uma questão séria ao monitorar sistemas embarcados, ter um grande número de parâmetros monitorados ou scripts pesados com lógica complexa ou tempo de inicialização longo.

O suporte a módulos carregáveis oferece maneiras de estender o agent, server e proxy do Zabbix sem sacrificar o desempenho.

Um módulo carregável é basicamente uma biblioteca compartilhada usada pelo daemon do Zabbix e carregada na inicialização. A biblioteca deve conter certas funções, para que um processo do Zabbix possa detectar que o arquivo é realmente um módulo que pode ser carregado e utilizado.

Módulos carregáveis têm vários benefícios. Ótimo desempenho e capacidade de implementar qualquer lógica são muito importantes, mas talvez a vantagem mais importante seja a capacidade de desenvolver, usar e compartilhar módulos do Zabbix. Isso contribui para uma manutenção sem problemas e ajuda a entregar novas funcionalidades de forma mais fácil e independente do código principal do Zabbix.

O licenciamento e a distribuição de módulos em forma binária são regidos pela licença AGPL-3.0 (os módulos são vinculados ao Zabbix em tempo de execução e utilizam os headers do Zabbix; todo o código do Zabbix é licenciado sob a licença AGPL-3.0 desde o Zabbix 7.0). A compatibilidade binária não é garantida pelo Zabbix.

A estabilidade da API de módulos é garantida durante um ciclo de release LTS (Long Term Support) do Zabbix. A estabilidade da API do Zabbix não é garantida (tecnicamente é possível chamar funções internas do Zabbix a partir de um módulo, mas não há garantia de que tais módulos funcionarão).

API do módulo

Para que uma biblioteca compartilhada seja tratada como um módulo Zabbix, ela deve implementar e exportar várias funções. Atualmente, existem seis funções na API do módulo Zabbix, das quais apenas uma é obrigatória e as outras cinco são opcionais.

Interface obrigatória

A única função obrigatória é zbx_module_api_version():

int zbx_module_api_version(void);

Esta função deve retornar a versão da API implementada por este módulo e, para que o módulo seja carregado, essa versão deve corresponder à versão da API do módulo suportada pelo Zabbix. A versão da API do módulo suportada pelo Zabbix é ZBX_MODULE_API_VERSION. Portanto, esta função deve retornar esta constante. A antiga constante ZBX_MODULE_API_VERSION_ONE usada para esse fim agora é definida como igual a ZBX_MODULE_API_VERSION para preservar a compatibilidade de código-fonte, mas seu uso não é recomendado.

Interface opcional

As funções opcionais são zbx_module_init(), zbx_module_item_list(), zbx_module_item_timeout(), zbx_module_history_write_cbs() e zbx_module_uninit():

int zbx_module_init(void);

Esta função deve realizar a inicialização necessária para o módulo (se houver). Se for bem-sucedida, deve retornar ZBX_MODULE_OK. Caso contrário, deve retornar ZBX_MODULE_FAIL. Neste último caso, o Zabbix não será iniciado.

ZBX_METRIC  *zbx_module_item_list(void);

Esta função deve retornar uma lista de items suportados pelo módulo. Cada item é definido em uma estrutura ZBX_METRIC, veja a seção abaixo para detalhes. A lista é terminada por uma estrutura ZBX_METRIC com o campo "key" igual a NULL.

void    zbx_module_item_timeout(int timeout);

Se o módulo exportar zbx_module_item_list(), então esta função é usada pelo Zabbix para especificar as configurações de timeout no arquivo de configuração do Zabbix que as verificações de item implementadas pelo módulo devem obedecer. Aqui, o parâmetro "timeout" está em segundos.

ZBX_HISTORY_WRITE_CBS   zbx_module_history_write_cbs(void);

Esta função deve retornar funções de callback que o servidor Zabbix usará para exportar o histórico de diferentes tipos de dados. As funções de callback são fornecidas como campos da estrutura ZBX_HISTORY_WRITE_CBS, os campos podem ser NULL se o módulo não estiver interessado no histórico de determinado tipo.

int zbx_module_uninit(void);

Esta função deve realizar a desinicialização necessária (se houver), como liberar recursos alocados, fechar descritores de arquivos, etc.

Todas as funções são chamadas uma vez na inicialização do Zabbix quando o módulo é carregado, com exceção de zbx_module_uninit(), que é chamada uma vez no desligamento do Zabbix quando o módulo é descarregado.

Definindo items

Cada item é definido em uma estrutura ZBX_METRIC:

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

Aqui, key é a chave do item (por exemplo, "dummy.random"), flags é CF_HAVEPARAMS ou 0 (dependendo se o item aceita parâmetros ou não), function é uma função C que implementa o item (por exemplo, "zbx_module_dummy_random"), e test_param é a lista de parâmetros a ser usada quando o agent Zabbix é iniciado com a flag "-p" (por exemplo, "1,1000", pode ser NULL). Uma definição de exemplo pode ser assim:

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

Cada função que implementa um item deve aceitar dois parâmetros ponteiros, o primeiro do tipo AGENT_REQUEST e o segundo do tipo 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;
       }

Essas funções devem retornar SYSINFO_RET_OK, se o valor do item foi obtido com sucesso. Caso contrário, devem retornar SYSINFO_RET_FAIL. Veja o exemplo do módulo "dummy" abaixo para detalhes sobre como obter informações de AGENT_REQUEST e como definir informações em AGENT_RESULT.

Fornecendo callbacks de exportação de histórico

A exportação de histórico via módulo não é mais suportada pelo Zabbix proxy.

O módulo pode especificar funções para exportar dados de histórico por tipo: Numérico (float), Numérico (sem sinal), Caractere, Texto e 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;

Cada uma delas deve receber o array "history" de "history_num" elementos como argumentos. Dependendo do tipo de dado de histórico a ser exportado, "history" é um array das seguintes estruturas, respectivamente:

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;

Os callbacks serão usados pelos processos history syncer do Zabbix server no final do procedimento de sincronização de histórico, após os dados serem gravados no banco de dados do Zabbix e salvos no value cache.

Em caso de erro interno no módulo de exportação de histórico, recomenda-se que o módulo seja escrito de forma que não bloqueie todo o monitoramento até que se recupere, mas descarte os dados e permita que o Zabbix server continue rodando.

Compilando módulos

Atualmente, os módulos devem ser compilados dentro da árvore de código-fonte do Zabbix, porque a API do módulo depende de algumas estruturas de dados que são definidas nos headers do Zabbix.

O header mais importante para módulos carregáveis é include/module.h, que define essas estruturas de dados. Outros headers de sistema necessários que ajudam include/module.h a funcionar corretamente são stdlib.h e stdint.h.

Com essas informações em mente, tudo está pronto para o módulo ser compilado. O módulo deve incluir stdlib.h, stdint.h e module.h, e o script de compilação deve garantir que esses arquivos estejam no caminho de inclusão. Veja o exemplo do módulo "dummy" abaixo para mais detalhes.

Outro header útil é include/zbxcommon.h, que define a função zabbix_log(), que pode ser usada para fins de log e depuração.

Parâmetros de configuração

O agent, server e proxy do Zabbix suportam dois parâmetros para lidar com módulos:

  • LoadModulePath – caminho completo para o local dos módulos carregáveis
  • LoadModule – módulo(s) a serem carregados na inicialização. Os módulos devem estar localizados em um diretório especificado por LoadModulePath ou o caminho deve preceder o nome do módulo. Se o caminho precedente for absoluto (começar com '/') então LoadModulePath é ignorado. É permitido incluir múltiplos parâmetros LoadModule.

Por exemplo, para estender o agent do Zabbix, poderíamos adicionar os seguintes parâmetros:

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

Ao iniciar, o agent irá carregar os módulos mariadb.so, apache.so e kernel.so do diretório /usr/local/lib/zabbix/agent, enquanto dummy.so será carregado de /usr/local/lib/zabbix. O agent não irá iniciar se um módulo estiver faltando, em caso de permissões incorretas ou se uma biblioteca compartilhada não for um módulo do Zabbix.

Configuração do frontend

Módulos carregáveis são suportados pelo agent, server e proxy do Zabbix. Portanto, o tipo de item no frontend do Zabbix depende de onde o módulo está carregado. Se o módulo estiver carregado no agent, então o tipo de item deve ser "Zabbix agent" ou "Zabbix agent (ativo)". Se o módulo estiver carregado no server ou proxy, então o tipo de item deve ser "Verificação simples".

A exportação de histórico através de módulos do Zabbix não precisa de nenhuma configuração no frontend. Se o módulo for carregado com sucesso pelo server e fornecer a função zbx_module_history_write_cbs() que retorna pelo menos uma função de callback diferente de NULL, então a exportação de histórico será habilitada automaticamente.

1 Módulo fictício

O Zabbix inclui um módulo de exemplo escrito em linguagem C. O módulo é localizado em src/modules/dummy:

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

O módulo está bem documentado, pode ser usado como modelo para o seu próprio módulos.

Depois que ./configure foi executado na raiz da árvore de origem do Zabbix como descrito acima, basta executar make para compilar 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;
       }

Limitações

O suporte a módulos carregáveis é implementado apenas para a plataforma Unix. Isso significa que não funciona para agents Windows.

Em alguns casos, um módulo pode precisar ler parâmetros de configuração relacionados ao módulo do zabbix_agentd.conf. Isso não é suportado atualmente. Se você precisar que seu módulo use alguns parâmetros de configuração, provavelmente deverá implementar a análise de um arquivo de configuração específico do módulo.