""" Rotina verificadora para notificar ferramentas de monitoramento sobre tramites parados sem processamento no barramento Lista todos os tramites e salva em um arquivo a situacao com a data/hora Nas execucoes seguintes, compara as datas com os tramites atuais para definir o tempo que estah parado no barramento Autor: Marcelo Linhares Castro (marlinhares@gmail.com) Original em: https://softwarepublico.gov.br/gitlab/sei/mod-sei-pen Modo de uso: - certifique-se q hah permissao de leitura e escrita na pasta atual - certifique-se q o certificado esteja na pasta atual como certall.pem, ou que o parametro esteja corretamente apontando para o caminho - certifique-se que hah rota para o barramento - execute como indicado abaixo Execute: python pendencias-represadas.py ou, usando argumentos para sobrescrever os valores default de execucao: python pendencias-represadas.py intMaxTimeWarning intMaxTimeCritical strCaminhoCert strURL onde - intMaxTimeWarning: tempo (mins) do tramite parado no barramento para gerar warning - intMaxTimeCritical: tempo (mins) do tramite parado no barramento para gerar critical - strCaminhoCert: caminho completo do certificado para conectar no barramento - strURL: url do barramento para recuperar as pendencias Retornos da rotina: exit 0 - sucesso exit 1 - warning (processo ha no minimo MAXTIME_WARNING parado no barramento) exit 2 - critical (processo ha pelo menos MAXTIME_CRITICAL parado no barramento) """ import json import os import sys from datetime import datetime # tempo (mins) para gerar warning. Programa retorna com exit 1 - Warning do Nagios MAXTIME_WARNING = 60 # tempo (mins) para gerar critical. Programa retorna com exit 2 - Critical do Nagios MAXTIME_CRITICAL = 90 # caminho completo do certificado para conectar no barramento CERT = "./certall.pem" # url para recuperar as pendencias no barramento API_URL = "https://api.conectagov.processoeletronico.gov.br/interoperabilidade/rest/v2/tramites/pendentes" # vamos sobrescrever os valores padrao, caso existam argumentos try: args = sys.argv if( len(sys.argv) > 1): MAXTIME_WARNING = int(args[1]) if( len(sys.argv) > 2): MAXTIME_CRITICAL = int(args[2]) if( len(sys.argv) > 3): CERT = str(args[3]) if( len(sys.argv) > 4): API_URL = str(args[4]) except Exception, e: print('Falha ao ler ou setar parametros: '+ str(e)) exit(4) COMANDO_PENDENCIAS = 'curl -s -S --cert ' + CERT + ' ' + API_URL # buscar as pendencias try: strPends = os.popen(COMANDO_PENDENCIAS).read() tmp = json.loads(strPends) except Exception, e: print('Falha ao ler ou abrir a lista de pendencias do barramento. ' + str(e)) print('Verifique se o certificado eh aceito pelo barrramento. Rode o seguinte comando e ') print('certifique-se que retorne um json valido: ' + COMANDO_PENDENCIAS) exit(4) # transformar pendencias em um json plano (cada elemento um idt unico) jsoPends = {} for t in tmp: j = { str(t['IDT']): { "status": t['status'] } } jsoPends.update(j) # ler arquivo de pendencias anterior if not os.path.isfile('pendencias.json'): with open('pendencias.json', 'w') as json_file: json.dump({'1': '1'}, json_file) try: with open('pendencias.json', 'r') as json_file: jsoAntigos = json.load(json_file) except: print """Excessao ao abrir ou carregar o arquivo pendencias.json. Apague o mesmo e verifique se ha permissao suficiente no diretorio""" exit(4) # apagar tramites ja efetuados do arquivo de pendencias lstApagar = [] for idt in jsoAntigos: if not (idt in jsoPends): lstApagar.append(idt) for idt in lstApagar: jsoAntigos.pop(idt) # agora vamos verificar se ha algo pendente dentro do intervalo de tempo determinado for idt in sorted(jsoPends): dtAtual = datetime.now() if ((idt in jsoAntigos) and (jsoPends[idt]['status'] == jsoAntigos[idt]['status'])): dtAntiga = datetime.strptime( jsoAntigos[idt]['tempo'] , '%Y-%m-%d %H:%M') flDelta = (dtAtual - dtAntiga) flDelta = (flDelta.microseconds + (flDelta.seconds + flDelta.days * 24 * 3600) * 10**6) / 10**6 / 60 if ( flDelta >= MAXTIME_WARNING and flDelta < MAXTIME_CRITICAL ): print "IDT: " + str(idt) + " --- " + str(flDelta) + " minutos parado no barramento" exit(1) elif ( flDelta >= MAXTIME_CRITICAL ): print "IDT: " + str(idt) + " --- " + str(flDelta) + " minutos parado no barramento" exit(2) # vamos atualizar a lista com a data/status atual caso o idt nao exista nela newJson = { "status": jsoPends[idt]['status'], "tempo": dtAtual.strftime('%Y-%m-%d %H:%M') } if( (idt not in jsoAntigos) or (jsoAntigos[idt]['status'] != jsoPends[idt]['status'] ) ): jsoAntigos[idt] = newJson # salvar a data e status dos idts pendentes para comparar na prox execucao with open('pendencias.json', 'w') as json_file: json.dump(jsoAntigos, json_file) # caso tenha chegado ate aqui significa q o processamento esta em dia exit(0)