[comment]: # translation:outdated

[comment]: # ({9fdce9e3-39a10c96})
# 6 Módulos carregáveis

[comment]: # ({/9fdce9e3-39a10c96})

[comment]: # ({0f03e08e-00b6a45a})
#### - Visão geral

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:

- [parâmetros do usuário](parâmetros do usuário) (métricas do agente)
- [verificações externas](/manual/config/items/itemtypes/external)
    (monitoramento sem agente)
- `system.run[]` Zabbix [agente
    item](/manual/config/items/itemtypes/zabbix_agent).

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](http://www.zabbix.com/life_cycle_and_release_policy)
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).

[comment]: # ({/0f03e08e-00b6a45a})

[comment]: # ({15849c0e-6a7ad616})
#### - API do módulo

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.

[comment]: # ({/15849c0e-6a7ad616})

[comment]: # ({3b67a8e4-8ec4ecb3})
##### - Interface obrigatória

A única função obrigatória é **zbx\_module\_api\_version()**:

``` {.c}
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 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.

[comment]: # ({/3b67a8e4-8ec4ecb3})

[comment]: # ({2facc75e-3766a85e})
##### - 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()**:

``` {.c}
int zbx_module_init(void);
```

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.

``` {.c}
ZBX_METRIC *zbx_module_item_list(void);
```

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.

``` {.c}
void zbx_module_item_timeout(int timeout);
```

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.

``` {.c}
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
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.

``` {.c}
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 é chamado
uma vez no desligamento do Zabbix quando o módulo é descarregado.

[comment]: # ({/2facc75e-3766a85e})

[comment]: # ({841386ad-89241080})
##### - Definindo itens

Cada item é definido em uma estrutura ZBX\_METRIC:

``` {.c}
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:

``` {.c}
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:

``` {.c}
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.

[comment]: # ({/841386ad-89241080})

[comment]: # ({6fcec731-79a740f6})
##### - Fornecendo retornos de chamada de exportação de histórico

::: 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:

``` {.c}
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:

``` {.c}
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.

[comment]: # ({/6fcec731-79a740f6})

[comment]: # ({30228960-c5011135})
##### - Construindo módulos

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.

[comment]: # ({/30228960-c5011135})

[comment]: # ({c61b93ec-321e0a01})
#### - Parâmetros de configuração

Agent, servidor e proxy Zabbix suportam dois
[parâmetros](/manual/appendix/config/zabbix_server) para lidar com
módulos:

- LoadModulePath – caminho completo para a localização dos módulos carregáveis
- LoadModule – módulo(s) para carregar na inicialização. Os módulos devem ser
    localizado em um diretório especificado por LoadModulePath ou o caminho deve
    preceder o nome do módulo. Se o caminho anterior for absoluto (começa
    com '/') então LoadModulePath é ignorado. É permitido incluir
    vários parâmetros LoadModule.

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.

[comment]: # ({/c61b93ec-321e0a01})

[comment]: # ({1e164ff5-39cdb2c0})
#### - Configuração de front-end

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.

[comment]: # ({/1e164ff5-39cdb2c0})

[comment]: # ({2fc1b66f-d5f54a51})
#### - 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**.

``` {.c}
/*
** 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;
}
```

[comment]: # ({/2fc1b66f-d5f54a51})

[comment]: # ({72df9dc4-77f24ad1})
#### - Limitações

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.

[comment]: # ({/72df9dc4-77f24ad1})
