Como obter status das Functions que pertencem às Function Apps do Azure e enviar os status para o Zabbix

magnorsantos

MagnoRSantos

Posted on August 14, 2023

Como obter status das Functions que pertencem às Function Apps do Azure e enviar os status para o Zabbix

Para funcionamento é necessário estar logado no Azure autorizando o dispositivo onde estão os arquivos de monitoramento com um usuário que tenha permissões para verificar status das functions no Azure.

az login --use-device-code
Enter fullscreen mode Exit fullscreen mode

Abaixo instruções de realização do login pelo Azure CLI.

Pré-requisitos

Az cli

Python 3.6 ou superior

Zabbix Sender (necessário para envio das informações ao zabbix usando agendamento de execução pelo sistema operacional)

Enter fullscreen mode Exit fullscreen mode

1 - Criar no diretório home do seu usuário o diretório statusfuncapp e dentro dele o diretório logstatus:

mkdir -p statusfuncapp/{logstatus}

O diretório logstatus apenas irá gravar um arquivo texto de log do status atual de cada function verificada.

2 - Criar no diretório statusfuncapp o arquivo listfunctionapp.json que conterá as informações sobre as functions app e function a serem monitoradas. Digite no terminal conforme abaixo:

nano listfunctionapp.json

Observações:
Abaixo uma explicação sobre cada um dos campos do arquivo json a seguir:
subscriptionId — Id da Subscription no azure que a function app pertence

resourcegroup — Nome do Resource Group no azure que a function app pertence

functionapp — Nome da Function App

function — Nome da Function

zabbixkey — Nome único para cada function a ser criado como chave no zabbix (zabbix key)

Abaixo o conteúdo do arquivo:

{
    "azurefunction": [
        {
            "subscriptionId": "xxxxxxx-yyyy-zzzz-wwww-kkkkkkkkkkkk",
            "resourcegroup": "RGTesteFunc",
            "functionapp": "namefunctionapp1",
            "function": "namefunction1",
            "zabbixkey": "key.nomefunctionapp1.function"
        },
        {
            "subscriptionId": "xxxxxxx-yyyy-zzzz-wwww-kkkkkkkkkkkk",
            "resourcegroup": "RGTesteFunc",
            "functionapp": "namefunctionapp2",
            "function": "namefunction2",
            "zabbixkey": "key.nomefunctionapp2.function"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Podem ser adicionadas várias functions a serem monitoradas, apenas seguir esse estrutura acima do json.

3 - Criar no diretório statusfuncapp o arquivo vfuncapp.py que conterá o script python com a instruções de obter as informações das functions conforme existentes no arquivo listfunctionapp.json.

import json
import os
import io
import sys
import csv
import socket
from datetime import datetime

### Funcao de limpeza do log
def limpaLog():
    pathLog = r"/home/user/statusfuncapp/logfunctionapp.log"

    ### cria/escreve arquivo de log MongoDB
    with io.open(pathLog, 'w', encoding='utf-8') as f:
      f.write(str(''))


### Funcao de gravacao do log
def gravaLog(msglog):
    pathLog = r"/home/user/statusfuncapp/logfunctionapp.log"
    datahora = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    ### cria/escreve arquivo de log MongoDB
    with io.open(pathLog, 'a', encoding='utf-8') as f:
      f.write(str('\n=====================================\n'))
      f.write(str(datahora + '\n' + msglog))


### Funcao de leitura do arquivo json com as informacoes das functions
def readJson():

    ### variaveis
    msg = ''  
    pathJsonFunction = r'/home/user/statusfuncapp/listfunctionapp.json'
    i = 0

    ### chamada da funcao de limpeza do log file
    limpaLog()

    ### codigo de leitura do json com as functions
    ### nesse trecho ocorre o processamento dos dados
    with open(pathJsonFunction) as file:
         data = json.load(file)

         for functions in data["azurefunction"]:
            v_subscription = str(data["azurefunction"][i]["subscriptionId"])
            v_resourcegroup = str(data["azurefunction"][i]["resourcegroup"])
            v_functionappname = str(data["azurefunction"][i]["functionapp"])
            v_functionname = str(data["azurefunction"][i]["function"])
            v_keyzabbix = str(data["azurefunction"][i]["zabbixkey"])
            #print(f"{v_functionappname} - {v_functionname}")


            try:
              ## Monta o comando de execucao via az cli
              cmd = 'az functionapp function show --subscription ' + v_subscription + ' -g ' + v_resourcegroup + ' -n ' + v_functionappname + ' --function-name ' + v_functionname

              ## Executa e pega o retorno em formato json
              retorno = os.popen(cmd).read()
              #print(retorno)

              ## Monta dicionario do json e exibe somente o valor requerido
              data_dict = json.loads(retorno)
              statusFunction = str(data_dict["isDisabled"])
              #print(data_dict["isDisabled"])

              ### Verifica os status da function
              ### conforme o retorno do campo isDisabled
              if(statusFunction == 'True'):
                statusAux = 'Disable'
              elif (statusFunction == 'False'):
                statusAux = 'Enabled'
              else:
                statusAux = 'Desconhecido'

            except:
              msg = msg + f'Erro functionApp: {v_functionappname} - function name: {v_functionname}\n'
              statusAux = 'Error'

            #msg = f'FunctionApp : {v_functionApp}, FunctionName : {v_functionName} ,Status : {statusAux}'
            strcsvAux = f'{v_functionappname},{v_functionname},{statusAux},{v_keyzabbix}'
            #print(strcsvAux)

            msg = msg + strcsvAux + '\n'

            ### chamada das funcoes de gravacao status e envio ao zabbix server
            gravaStatusFunction(v_functionappname, statusAux)
            zabbixSenderStatus(v_keyzabbix, statusAux)

            i = i + 1

    gravaLog(msg)
    #print(msg)


### Funcao de gravacao do status das functions
def gravaStatusFunction(functionApp, fstatus):

    ### variaveis do local de gravacao dos status
    strResult = r"/home/user/statusfuncapp/logstatus"
    strResult = os.path.join(strResult, functionApp + '.txt')
    pathCsvResult = strResult

    with open(pathCsvResult, 'w', encoding='utf-8') as csvf:
        csvf.write(fstatus)


### Funcao de envio das informacoes de status das functions via zabbix_sender
def zabbixSenderStatus(zbxChave, zbxStatus):

    ### variaveis server e host monitorado   
    server = 'ip_server_zabbix'
    myhost = socket.gethostname() #nome da maquina local

    zbxsendercmd = f'zabbix_sender -z {server} -s {myhost} -k {zbxChave} -o {zbxStatus}'   
    retornozbx = os.popen(zbxsendercmd).read()

    gravaLog(zbxsendercmd + '\n' + retornozbx)
    print(zbxsendercmd)
    print(retornozbx)


### INICIO DA APLICACAO
if __name__ == "__main__":
   readJson()

Enter fullscreen mode Exit fullscreen mode

Após a criação dos arquivos na estrutura acima é necessário criar um agendamento para execução do mesmo via cron no Linux.

Como é um script que não necessita de execução via root pode ser criado o agendamento no cron do usuário logado no Linux mesmo, abaixo um exemplo:

## verifica status da function na functionapp azure roda a cada 6 minutos
*/6 * * * * /usr/bin/python3 /home/user/statusfuncapp/vfuncapp.py
Enter fullscreen mode Exit fullscreen mode

Após o procedimento é necessário criar no zabbix os itens para cada uma das functions a serem monitoradas.

Exemplo item para a function app “namefunctionapp1” e function “namefunction1” .

Nome do item no zabbix: “key.namefunctionapp1.function”

💖 💪 🙅 🚩
magnorsantos
MagnoRSantos

Posted on August 14, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related