Módulos carregáveis oferecem uma opção voltada para o desempenho para estender o Zabbix funcionalidade.
Já existem maneiras de estender a funcionalidade do Zabbix por meio de:
system.run[]
Zabbix agente item.Eles funcionam muito bem, mas têm uma grande desvantagem, ou seja, fork(). Zabbix tem que bifurcar um novo processo toda vez que lida com uma métrica de usuário, que é não é bom para o desempenho. Normalmente não é grande coisa, mas pode ser um problema sério ao monitorar sistemas embarcados, tendo um grande número de parâmetros monitorados ou scripts pesados com lógica complexa ou tempo de inicialização longo.
O suporte de módulos carregáveis oferece maneiras de estender o agente Zabbix, servidor e proxy sem sacrificar o desempenho.
Um módulo carregável é basicamente uma biblioteca compartilhada usada pelo daemon do Zabbix e carregado na inicialização. A biblioteca deve conter certas funções, então que um processo Zabbix pode detectar que o arquivo é de fato um módulo que pode carregar e trabalhar.
Os 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 o mais vantagem importante é a capacidade de desenvolver, usar e compartilhar Zabbix módulos. Contribui para uma manutenção sem problemas e ajuda a fornecer nova funcionalidade mais fácil e independente da base de código central do Zabbix.
O licenciamento e distribuição de módulos em formato binário são regidos pela GPL licença (os módulos estão se conectando com o Zabbix em tempo de execução e estão usando o Zabbix cabeçalhos; atualmente todo o código Zabbix está licenciado sob licença GPL). A compatibilidade binária não é garantida pelo Zabbix.
A estabilidade da API do módulo é garantida durante um Zabbix LTS (Long Term Suporte) lançamento ciclo. A estabilidade da API Zabbix não é garantida (tecnicamente é possível chamar funções internas do Zabbix a partir de um módulo, mas há nenhuma garantia de que tais módulos funcionarão).
Para que uma biblioteca compartilhada seja tratada como um módulo Zabbix, é deve implementar e exportar várias funções. Atualmente existem seis funções na API do módulo Zabbix, sendo apenas uma obrigatória e os outros cinco são opcionais.
A única função obrigatória é zbx_module_api_version():
Esta função deve retornar a versão da API implementada por este módulo e para que o módulo seja carregado esta versão deve corresponder ao módulo Versão da API suportada pelo Zabbix. Versão da API do módulo suportada por Zabbix é ZBX_MODULE_API_VERSION. Então esta função deve retornar isso constante. Constante antiga ZBX_MODULE_API_VERSION_ONE usada para isso O objetivo agora está definido para igualar ZBX_MODULE_API_VERSION para preservar compatibilidade de fonte, mas seu uso não é recomendado.
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():
Esta função deve realizar a inicialização necessária para o módulo (caso existam). Se for bem-sucedido, deve retornar ZBX_MODULE_OK. Caso contrário isto deve retornar ZBX_MODULE_FAIL. Neste último caso, o Zabbix não começar.
Esta função deve retornar uma lista de itens 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 campo "chave" de NULL.
Se o módulo exportar zbx_module_item_list() então esta função é usado pelo Zabbix para especificar as configurações de tempo limite na configuração do Zabbix arquivo que as verificações de itens implementadas pelo módulo devem obedecer. Aqui, o parâmetro "timeout" está em segundos.
Esta função deve retornar funções de callback que o servidor Zabbix usará para histórico de exportação de diferentes tipos de dados. As funções de retorno de chamada são fornecidas como campos da estrutura ZBX_HISTORY_WRITE_CBS, os campos podem ser NULL se módulo não está interessado na história de determinado tipo.
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 é chamado uma vez no desligamento do Zabbix quando o módulo é descarregado.
Cada item é definido em uma estrutura ZBX_METRIC:
estrutura typedef
{
caractere *chave;
bandeiras não assinadas;
int(*função)();
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), função é uma função C que implementa o item (por exemplo, "zbx_module_dummy_random") e test_param é o lista de parâmetros a ser usada quando o agente Zabbix é iniciado com o "-p" sinalizador (por exemplo, "1,1000", pode ser NULL). Uma definição de exemplo pode parecer esta:
chaves ZBX_METRIC estáticas[] =
{
{ "dummy.random", CF_HAVEPARAMS, zbx_module_dummy_random, "1.1000" },
{ NULO }
}
Cada função que implementa um item deve aceitar dois ponteiros parâmetros, o primeiro do tipo AGENT_REQUEST e o segundo do tipo digite AGENTE_RESULTADO:
int zbx_module_dummy_random(AGENT_REQUEST *solicitação, AGENT_RESULT *resultado)
{
...
SET_UI64_RESULT(resultado, de + rand() % (para - de + 1));
retornar SYSINFO_RET_OK;
}
Essas funções devem retornar SYSINFO_RET_OK, se o valor do item foi obtido com sucesso. Caso contrário, eles devem retornar SYSINFO_RET_FAIL. Veja o exemplo de módulo "dummy" abaixo para obter detalhes sobre como obter informações de AGENT_REQUEST e como definir informações em AGENTE_RESULT.
::: não importante A exportação de histórico via módulo não é mais suportada pelo proxy Zabbix desde o Zabbix 4.0.0. :::
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:
estrutura typedef
{
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 um deles deve ter o array "history" de elementos "history_num" como argumentos. Dependendo do tipo de dados do histórico a ser exportado, "histórico" é uma matriz das seguintes estruturas, respectivamente:
estrutura typedef
{
zbx_uint64_t itemid;
relógio interno;
int ns;
valor duplo;
}
ZBX_HISTORY_FLOAT;
estrutura typedef
{
zbx_uint64_t itemid;
relógio interno;
int ns;
valor zbx_uint64_t;
}
ZBX_HISTORY_INTEGER;
estrutura typedef
{
zbx_uint64_t itemid;
relógio interno;
int ns;
const char *valor;
}
ZBX_HISTORY_STRING;
estrutura typedef
{
zbx_uint64_t itemid;
relógio interno;
int ns;
const char *valor;
}
ZBX_HISTORY_TEXT;
estrutura typedef
{
zbx_uint64_t itemid;
relógio interno;
int ns;
const char *valor;
const char *fonte;
int timestamp;
int logeventid;
gravidade int;
}
ZBX_HISTORY_LOG;
Callbacks serão usados pelos processos de sincronização de histórico do servidor Zabbix no fim do procedimento de sincronização do histórico após os dados serem gravados no banco de dados Zabbix e salvo no cache de valor.
Atualmente, os módulos devem ser construídos dentro da árvore de origem do Zabbix, porque a API do módulo depende de algumas estruturas de dados que são definidas nos cabeçalhos do Zabbix.
O cabeçalho mais importante para módulos carregáveis é include/module.h, que define essas estruturas de dados. Outros cabeçalhos de sistema necessários que ajudar include/module.h a funcionar corretamente são stdlib.h e stdint.h.
Com essas informações em mente, está tudo pronto para que o módulo seja construído. O módulo deve incluir stdlib.h, stdint.h e module.h, e o script de compilação deve garantir que esses arquivos sejam no caminho de inclusão. Veja o exemplo de módulo "fictício" abaixo para obter detalhes.
Outro cabeçalho útil é include/log.h, que define zabbix_log() função, que pode ser usada para registro e depuração propósitos.
Agent, servidor e proxy Zabbix suportam dois parâmetros para lidar com módulos:
Por exemplo, para estender o agente Zabbix, podemos adicionar o seguinte parâmetros:
LoadModulePath=/usr/local/lib/zabbix/agent/
LoadModule=mariadb.so
LoadModule=apache.so
LoadModule=kernel.so
LoadModule=/usr/local/lib/zabbix/dummy.so
Após a inicialização do agent, ele carregará o mariadb.so, apache.so e kernel.so módulos do diretório /usr/local/lib/zabbix/agent enquanto dummy.so será carregado de /usr/local/lib/zabbix. Ele falhará se um módulo for ausente, em caso de permissões ruins ou se uma biblioteca compartilhada não for um Módulo Zabbix.
Módulos carregáveis são suportados pelo agente Zabbix, servidor e proxy. Portanto, o tipo de item no frontend do Zabbix depende de onde o módulo está carregado. Se o módulo estiver carregado no agente, o tipo de item deve ser "agente Zabbix" ou "agente Zabbix (ativo)". Se o módulo estiver carregado no servidor ou proxy, então o tipo de item deve ser "Simple Verifica".
A exportação de histórico através dos módulos Zabbix não precisa de nenhum frontend configuração. Se o módulo for carregado com sucesso pelo servidor e fornece a função zbx_module_history_write_cbs() que retorna pelo menos uma função de retorno de chamada não NULL, a exportação do histórico será habilitado automaticamente.
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;
}
O suporte de módulos carregáveis é implementado apenas para a plataforma Unix. Isso significa que não funciona para agentes do Windows.
Em alguns casos, um módulo pode precisar ler a configuração relacionada ao módulo parâmetros de zabbix_agentd.conf. Não é suportado atualmente. Se você precisa que seu módulo use alguns parâmetros de configuração que você deve provavelmente implementa a análise de um arquivo de configuração específico do módulo.