Criando seu próprio LLD customizado no Zabbix
Um guia completo para criar um Low-Level Discovery customizado no Zabbix.
De tempos em tempos me vejo na necessidade de desenvolver alguma rotina para monitoramento que envolva o uso de uma regra de descoberta customizada no Zabbix. Isso eventualmente acontece por necessidades específicas que a ferramenta pode ainda não ser capaz de executar.
Após uma necessidade específica de um colega da comunidade Zabbix Brasil, resolvi fazer este post para dar uma ideia geral de como funciona o recurso de LLD (descoberta de baixo nível) do Zabbix e de como você pode fazer a sua própria regra customizada, baseada nas suas necessidades.
Para este exemplo, usarei Powershell, visando os colegas que administram ambientes Microsoft. Porém, pode usar qualquer linguagem que o seu sistema operacional suporte, haja visto que o script que criaremos será executado pelo próprio host a ser monitorado, e não no servidor Zabbix em si.
O LLD
O recurso de LLD, para quem não sabe, permite que o Zabbix “crie, de forma dinâmica, itens, triggers e gráficos para todos os objetos descobertos no dispositivo monitorado”. Você pode encontrar esta definição e mais informações na documentação oficial da ferramenta.
O processo de descoberta automática funciona da seguinte forma: uma rotina é executada e lista os objetos a serem descobertos em uma saída no formato JSON. Baseado nessa saída, os itens, triggers e gráficos serão criados a partir dos protótipos que você criará. Estes protótipos utilizarão as saídas do formato JSON como parâmetros para a criação desses elementos de monitoramento.
A documentação do LLD está bem clara e objetiva. Inclusive, com versão em português.
O Script
Vamos supor aqui que nós precisemos saber o tamanho de cada arquivo existente em uma determinada pasta. Poderiam ser arquivos de um sistema, cujos tamanhos precisam ser monitorados individualmente.
Dica: o Powershell ISE ou o Visual Studio Code são ótimas IDEs para você desenvolver seus scripts.
Primeiro, vamos criar uma forma de listar estes arquivos e o seu tamanho. Para isto, vamos mandar listar os arquivos da pasta simplesmente e ver o que temos em retorno:
1
Get-ChildItem C:\Temp
Opa! Só com esse simples cmdlet já conseguimos listar os arquivos do diretório e os seus respectivos tamanhos.
Agora vamos testar como fazemos para imprimir somente o tamanho de arquivo específico. Digamos que nós queiramos saber o tamanho do arquivo lalala.zip
:
1
Get-ChildItem C:\Temp\lalala.zip
Imprimindo propriedades de um arquivo específico
Conseguimos listar informações do arquivo em questão, mas juntamente com outros dados que não são importantes para o que queremos. Com uma saída dessa forma, não conseguiremos monitorar somente o tamanho. Sendo assim, vamos imprimir somente o tamanho do arquivo em si. Para isto, vamos colocar o comando entre parênteses e fixar que somente queremos os dados referentes à coluna Lenght
, que é o tamanho do arquivo.
1
(Get-ChildItem C:\Temp\lalala.zip).Lenght
Exibe somente o valor do tamanho
Ótimo! Conseguimos então que o script somente imprima o dado que desejamos. Agora temos que encontrar uma forma de que o script trabalhe dinamicamente, de forma que para cada arquivo na pasta, o comando powershell seja diferente.
Para isso nós podemos utilizar o mesmo conceito do Lnux Bash, que usa as variáveis $1
, $2
e assim por diante para os parâmetros que serão passados para um script. A única diferença é que no powershell esse array inicia-se em 0
com o nome $args[x]
, onde x
é a posição do parâmetro a ser informado.
No comando abaixo, por exemplo, abc
é $args[0]
e 123
é $args[1]
.
1
Write-host abc 123
Levando isso em conta, vamos substituir o nome do caminho no script pelo nome da variável $args[0]
. Sendo assim, quando executarmos o script passando o nome do arquivo como parâmetro, ele nos trará o dado do arquivo informado. Veja que o início do caminho está fixado, mas poderia ser completamente dinâmico.
1
(Get-ChildItem C:\Temp\$args[0]).Lenght
Isto posto, salve esse script e execute-o via powershell, passando o nome do arquivo como parâmetro para saber o tamanho do arquivo em questão.
1
C:\temp\monit-arquivos.ps1 lalala.zip
Mostrando tamanho usando arquivo como parâmetro do script
Estruturando o script
Agora que já sabemos como fazer a coleta dos dados que vamos monitorar, vamos estruturar o script de modo a fazer com que ele tanto faça o monitoramento dos itens descobertos quanto a descoberta (LLD) propriamente dito. Eu, particularmente, gosto da lógica em que caso o script não receba nenhum parâmetro válido, faça o LLD como último recurso.
Sendo assim, vamos estruturar essa rotina de modo a efetuar o monitoramento de um arquivo específico quando eu passar um parâmetro tamanho. Dessa forma, se o primeiro parâmetro ($args[0]
) que o script receber for a string tamanho, ele imprimirá o tamanho do arquivo declarado como segundo parâmetro ($args[1]
).
A primeira parte do script fica como abaixo:
1
2
3
4
5
6
# Script para monitorar tamanho de arquivos em uma pasta
# Se o primeiro parâmetro for a string "tamanho"
If ($args\[0\] -eq "tamanho") {
(Get-ChildItem "C:\Temp\"$args[1]).Length
}
Agora salve o script e execute-o para checar se está funcionando conforme o esperado. Passaremos o primeiro parâmetro como tamanho
e o segundo com o nome do arquivo.
1
C:\Temp\monit-arquivos.ps1 tamanho lalala.zip
Informando ação e arquivo como parâmetros
Ótimo! Agora vamos para a segunda parte, que é onde faremos o LLD propriamente dito. O bloco abaixo varre todos os arquivos do diretório informado e imprime em formato JSON o nome de cada arquivo, identificado pela macro {#NOMEARQUIVO}
. Essa macro (que podem ser várias) é uma variável que será utilizada pelo Zabbix para dar nome aos itens, triggers e etc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Se não, efetua LLD
Else {
# Preenche o array arquivos com a lista de arquivos na pasta
$arquivos = (Get-ChildItem "C:\temp\").Name
# Define o contador em 0
$i = 0
# Inicia JSON
Write-Host "{"
Write-Host " `"data`":["
# Para cada nome de arquivo
Foreach ($arquivo in $arquivos) {
# Contador para não imprimir vírgula após o último elemento
$i++
# Se o nome de arquivo da vez não for vazio
If($arquivo -ne "") {
Write-Host -NoNewline " {""{#NOMEARQUIVO}"":""$arquivo""}"
# Se não for o último elemento, imprima "," ao final
If ($i -lt $arquivos.Count) {
Write-Host ","
}
}
}
Write-Host
Write-Host " ]"
Write-Host "}"
}
Execute o script para ver a saída em formato JSON, que você pode validar em qualquer validador desses na internet. Aqui usei o JSONLint.
Feito isto, junte as duas partes do script e estamos prontos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Script para monitorar tamanho de arquivos em uma pasta
# Se o primeiro parâmetro for a string "tamanho"
If ($args[0] -eq "tamanho") {
(Get-ChildItem "C:\Temp\"$args[1]).Length
}
# Se não, efetua LLD
Else
{
# Preenche o array arquivos com a lista de arquivos na pasta
$arquivos = (Get-ChildItem "C:\temp\").Name
# Define o contador em 0
$i = 0
# Inicia JSON
Write-Host "{"
Write-Host " `"data`":["
# Para cada nome de arquivo
Foreach ($arquivo in $arquivos)
{
# Contador para não imprimir vírgula após o último elemento
$i++
# Se o nome de arquivo da vez não for vazio
If($arquivo -ne "") {
Write-Host -NoNewline " {""{#NOMEARQUIVO}"":""$arquivo""}"
# Se não for o último elemento, imprima "," ao final
If ($i -lt $arquivos.Count) {
Write-Host ","
}
}
}
Write-Host
Write-Host " ]"
Write-Host "}"
}
O Host
Feita esta parte, vamos adicionar o script ao arquivo de configuração do host a ser monitorado, criando uma chave monit-arquivos
via UserParameter. O parâmetro de usuário nada mais é do que criar uma chave de monitoramento customizada, que quando executada chamará o comando/script declarado no arquivo de configuração.
Encontre o arquivo de configuração do seu host e adicione a seguinte linha (no meu teste estou com script salvo em C:\Temp
):
1
UserParameter=monit-arquivos[*],powershell.exe -NoProfile -ExecutionPolicy Bypass -file "C:\Zabbix\monit-arquivos.ps1" "$1" "$2"
Essa tag diz que estamos criando uma chave com o nome monit-arquivos, que aceitará parâmetros ($1
e $2
) e que quando chamada executará o comando que está após a vírgula. Caso tenha dúvidas, pesquise sobre os outros parâmetros de powershell que estão sendo utilizados nessa linha.
Note que os parâmetros estão declarados como $1
e $2
, que é o padrão do arquivo de configuração do Zabbix. Isso nada tem a ver com a liguagem utilizada no seu script.
Para testar, execute o comando abaixo em um prompt de comando.
1
powershell.exe -NoProfile -ExecutionPolicy Bypass -file "C:\Zabbix\monit-arquivos.ps1"
Feito isso, salve o arquivo e reinicie o agente do Zabbix no host. Você agora pode testar uma coleta usando este item diretamente do servidor Zabbix, executando o comando abaixo. Note a sintaxe utilizada na chave de monitoramento que criamos.
1
zabbix_get -k monit-arquivos[tamanho,lalala.zip]
O Zabbix
Agora vamos criar o nosso processo de descoberta. Crie um template novo (ou edite um host) e vá até a aba Regras de Descoberta. Clique na opção Criar regra de descoberta
.
Na tela seguinte, dê um nome para a sua regra de descoberta e informe o nome da chave igual colocamos no parâmetro de usuário, no arquivo de configuração do Zabbix. Estamos configurando aqui de quanto em quanto tempo o Zabbix fará o processo de descoberta, que nada mais é que executar o script que criamos sem informar nenhum parâmetro.
Feito isto, vá até a opção de protótipos de itens e adicione o item de monitoramento em si. Aqui adicionaremos a chave que criamos e passaremos os parâmetros que testamos anteriormente.
Agora aguarde o tempo que você estipulou para a coleta e cheque em Dados recentes
se as coletas estão sendo feitas corretamente. Erros podem ser checados tanto no arquivo de log do agente quanto do servidor.
Espero que este artigo seja útil. Grande abraço!