Você está visualizando a documentação da versão de desenvolvimento, que pode estar incompleta.
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, no entanto, pode ser um problema sério 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 carregar e trabalhar com ele.

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 base principal do Zabbix.

O licenciamento e a distribuição de módulos em formato binário são regidos pela licença AGPL-3.0 (os módulos são vinculados ao Zabbix em tempo de execução e usam os headers do Zabbix; todo o código do Zabbix é licenciado sob 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, esta 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 este propósito agora está definida como igual a ZBX_MODULE_API_VERSION para preservar a compatibilidade do 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 do 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 de 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é se recuperar, mas descarte os dados e permita que o Zabbix server continue em execução.

Compilando módulos

Atualmente, os módulos devem ser compilados dentro da árvore de fontes 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 será 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 é carregado. Se o módulo for carregado no agent, então o tipo de item deve ser "Zabbix agent" ou "Zabbix agent (ativo)". Se o módulo for 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 necessita 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.

Módulo de exemplo

O Zabbix inclui um módulo de exemplo escrito em linguagem C. O módulo está localizado em 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

O módulo está bem documentado e pode ser usado como um template para seus próprios módulos.

Após executar ./configure na raiz do código-fonte do Zabbix, conforme descrito acima, basta executar make para compilar o dummy.so.

/*
       ** Zabbix
       ** Copyright (C) 2001-2020 Zabbix SIA
       **
       ** Este programa é um software livre; você pode redistribuí-lo e/ou modificá-lo
       ** sob os termos da Licença Pública Geral GNU conforme publicada pela
       ** Free Software Foundation; tanto a versão 2 da Licença, ou
       ** (a seu critério) qualquer versão posterior.
       **
       ** Este programa é distribuído na esperança de que seja útil,
       ** mas SEM QUALQUER GARANTIA; sem mesmo a garantia implícita de
       ** COMERCIALIZAÇÃO ou ADEQUAÇÃO A UM DETERMINADO FIM. Veja a
       ** Licença Pública Geral GNU para mais detalhes.
       **
       ** Você deve ter recebido uma cópia da Licença Pública Geral GNU
       ** junto com este programa; se não, escreva para a 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"
       
       /* a variável mantém a configuração de timeout para o processamento do item */
       static int  item_timeout = 0;
       
       /* o módulo DEVE definir funções internas como static e usar um padrão de nomenclatura diferente dos símbolos internos do Zabbix (zbx_*) e das funções da API de módulos carregáveis (zbx_module_*) para evitar conflitos */
       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[] =
       /*  CHAVE         FLAG        FUNÇÃO      PARÂMETROS DE TESTE */
       {
           {"dummy.ping",      0,      dummy_ping, NULL},
           {"dummy.echo",      CF_HAVEPARAMS,  dummy_echo, "a message"},
           {"dummy.random",    CF_HAVEPARAMS,  dummy_random,   "1,1000"},
           {NULL}
       };
       
       /******************************************************************************
        *                                                                            *
        * Função: zbx_module_api_version                                             *
        *                                                                            *
        * Objetivo: retorna o número da versão da interface do módulo                *
        *                                                                            *
        * Valor de retorno: ZBX_MODULE_API_VERSION - versão do module.h com o qual o *
        *                  módulo foi compilado, para carregar o módulo com sucesso  *
        *                  o Zabbix DEVE ser compilado com a mesma versão deste      *
        *                  arquivo de cabeçalho                                      *
        *                                                                            *
        ******************************************************************************/
       int zbx_module_api_version(void)
       {
           return ZBX_MODULE_API_VERSION;
       }
       
       /******************************************************************************
        *                                                                            *
        * Função: zbx_module_item_timeout                                            *
        *                                                                            *
        * Objetivo: define o valor de timeout para o processamento dos items         *
        *                                                                            *
        * Parâmetros: timeout - timeout em segundos, 0 - sem timeout definido        *
        *                                                                            *
        ******************************************************************************/
       void    zbx_module_item_timeout(int timeout)
       {
           item_timeout = timeout;
       }
       
       /******************************************************************************
        *                                                                            *
        * Função: zbx_module_item_list                                               *
        *                                                                            *
        * Objetivo: retorna a lista de chaves de item suportadas pelo módulo         *
        *                                                                            *
        * Valor de retorno: lista de chaves de item                                  *
        *                                                                            *
        ******************************************************************************/
       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)
           {
               /* define mensagem de erro opcional */
               SET_MSG_RESULT(result, strdup("Número inválido de parâmetros."));
               return SYSINFO_RET_FAIL;
           }
       
           param = get_rparam(request, 0);
       
           SET_STR_RESULT(result, strdup(param));
       
           return SYSINFO_RET_OK;
       }
       
       /******************************************************************************
        *                                                                            *
        * Função: dummy_random                                                       *
        *                                                                            *
        * Objetivo: ponto de entrada principal para o processamento de um item       *
        *                                                                            *
        * Parâmetros: request - estrutura que contém a chave do item e parâmetros    *
        *              request->key - chave do item sem parâmetros                   *
        *              request->nparam - número de parâmetros                        *
        *              request->params[N-1] - ponteiros para os parâmetros da chave  *
        *              request->types[N-1] - tipos dos parâmetros da chave:          *
        *                  REQUEST_PARAMETER_TYPE_UNDEFINED (parâmetro vazio)        *
        *                  REQUEST_PARAMETER_TYPE_ARRAY (array)                      *
        *                  REQUEST_PARAMETER_TYPE_STRING (string entre aspas ou não) *
        *                                                                            *
        *             result - estrutura que conterá o resultado                     *
        *                                                                            *
        * Valor de retorno: SYSINFO_RET_FAIL - função falhou, o item será marcado    *
        *                                 como não suportado pelo zabbix             *
        *               SYSINFO_RET_OK - sucesso                                     *
        *                                                                            *
        * Comentário: get_rparam(request, N-1) pode ser usado para obter um ponteiro *
        *          para o N-ésimo parâmetro a partir de 0 (primeiro parâmetro).      *
        *          Certifique-se de que ele existe verificando o valor de            *
        *          request->nparam. Da mesma forma, get_rparam_type(request, N-1)    *
        *          pode ser usado para obter o tipo do parâmetro.                    *
        *                                                                            *
        ******************************************************************************/
       static int  dummy_random(AGENT_REQUEST *request, AGENT_RESULT *result)
       {
           char    *param1, *param2;
           int from, to;
       
           if (2 != request->nparam)
           {
               /* define mensagem de erro opcional */
               SET_MSG_RESULT(result, strdup("Número inválido de parâmetros."));
               return SYSINFO_RET_FAIL;
           }
       
           param1 = get_rparam(request, 0);
           param2 = get_rparam(request, 1);
       
           /* não há validação estrita de parâmetros e tipos para simplificar */
           from = atoi(param1);
           to = atoi(param2);
       
           if (from > to)
           {
               SET_MSG_RESULT(result, strdup("Intervalo especificado inválido."));
               return SYSINFO_RET_FAIL;
           }
       
           SET_UI64_RESULT(result, from + rand() % (to - from + 1));
       
           return SYSINFO_RET_OK;
       }
       
       /******************************************************************************
        *                                                                            *
        * Função: zbx_module_init                                                    *
        *                                                                            *
        * Objetivo: a função é chamada na inicialização do agent                     *
        *          Deve ser usada para chamar rotinas de inicialização               *
        *                                                                            *
        * Valor de retorno: ZBX_MODULE_OK - sucesso                                  *
        *               ZBX_MODULE_FAIL - falha na inicialização do módulo           *
        *                                                                            *
        * Comentário: o módulo não será carregado em caso de ZBX_MODULE_FAIL         *
        *                                                                            *
        ******************************************************************************/
       int zbx_module_init(void)
       {
           /* inicialização para dummy.random */
           srand(time(NULL));
       
           return ZBX_MODULE_OK;
       }
       
       /******************************************************************************
        *                                                                            *
        * Função: zbx_module_uninit                                                  *
        *                                                                            *
        * Objetivo: a função é chamada no desligamento do agent                      *
        *          Deve ser usada para liberar recursos utilizados, se houver        *
        *                                                                            *
        * Valor de retorno: ZBX_MODULE_OK - sucesso                                  *
        *               ZBX_MODULE_FAIL - função falhou                              *
        *                                                                            *
        ******************************************************************************/
       int zbx_module_uninit(void)
       {
           return ZBX_MODULE_OK;
       }
       
       /******************************************************************************
        *                                                                            *
        * Funções: dummy_history_float_cb                                            *
        *            dummy_history_integer_cb                                        *
        *            dummy_history_string_cb                                         *
        *            dummy_history_text_cb                                           *
        *            dummy_history_log_cb                                            *
        *                                                                            *
        * Objetivo: funções de callback para armazenar dados históricos dos tipos    *
        *          float, integer, string, text e log, respectivamente, em           *
        *          armazenamento externo                                             *
        *                                                                            *
        * Parâmetros: history     - array de dados históricos                        *
        *             history_num - número de elementos no array history             *
        *                                                                            *
        ******************************************************************************/
       static void dummy_history_float_cb(const ZBX_HISTORY_FLOAT *history, int history_num)
       {
           int i;
       
           for (i = 0; i < history_num; i++)
           {
               /* faça algo com 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++)
           {
               /* faça algo com 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++)
           {
               /* faça algo com 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++)
           {
               /* faça algo com 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++)
           {
               /* faça algo com history[i].itemid, history[i].clock, history[i].ns, history[i].value, ... */
           }
       }
       
       /******************************************************************************
        *                                                                            *
        * Função: zbx_module_history_write_cbs                                       *
        *                                                                            *
        * Objetivo: retorna um conjunto de funções do módulo que o Zabbix chamará    *
        *          para exportar diferentes tipos de dados históricos                *
        *                                                                            *
        * Valor de retorno: estrutura com ponteiros para funções de callback (pode   *
        *               ser NULL se o módulo não estiver interessado em dados de     *
        *               certos tipos)                                                *
        *                                                                            *
        ******************************************************************************/
       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 módulo exporta três novos items:

  • dummy.ping - sempre retorna '1'
  • dummy.echo[param1] - retorna o primeiro parâmetro como está, por exemplo, dummy.echo[ABC] retornará ABC
  • dummy.random[param1, param2] - retorna um número aleatório dentro do intervalo param1-param2, por exemplo, dummy.random[1,1000000]

Limitações

O suporte a módulos carregáveis está 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 a partir 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.