Integrazione Webhook di OpenStack Monasca
2016-03-25
Machine-translated from English. Read the English original
Bene, sono sicuro che tutti voi sapete cosa sono i webhook, ma li ho scoperti solo il mese scorso in preparazione per un'altra integrazione di Helion OpenStack.
Ecco la mia comprensione semplificata: sono "Notifiche Push".
Con l'avvento delle intertubes siamo diventati molto intelligenti molto in fretta e abbiamo iniziato a utilizzare tutti questi pazzi protocolli UDP e TCP per la comunicazione M2M. Poiché la larghezza di banda non era mai un problema (sto scherzando), l'efficienza non era mai il primo requisito.
Molte soluzioni di monitoraggio si sono orientate verso HTTP come protocollo preferito e hanno semplicemente interrogato le risorse di loro interesse attendendo una risposta. Monasca fornisce un'API RESTful se si desidera utilizzare questo approccio.
Tuttavia, con il cloud arrivano le sfide della scalabilità. E quando si cerca di interrogare centinaia di migliaia di servizi in pochi secondi, l'efficienza è molto importante. Arrivano allora i webhook per salvare la situazione.
A differenza del polling 'vecchio stile' e inefficiente che richiede un HTTP GET seguito da un HTTP POST anche quando non c'è nulla da segnalare, i webhook richiedono un singolo HTTP POST e si attivano solo quando c'è qualcosa di degno di essere inviato a casa!!!
Quindi, per riassumere: sono frequenti HTTP GET/POST contro infrequenti HTTP POST. C'è una leggenda metropolitana che gira in rete secondo cui quando Github ha introdotto i Webhook ha ridotto il carico sui loro server da parte degli utenti che monitoravano le nuove modifiche al codice di 66 volte. [Non ho alcun dato a supporto]
Come li configuriamo – semplice, specialmente se hai letto il mio blog precedente sull'integrazione SMTP. Facciamo prima la parte della GUI – tutto questo potrebbe essere fatto dalla CLI ma richiederebbe che leggessi di più.
Nota: La GUI della Console delle Operazioni è specifica per la distribuzione Helion OpenStack. Se non si utilizza Helion, sarà necessario utilizzare la CLI di Monasca.
Configurazione Webhook in HOS Monasca
-
Accedi alla Console delle Operazioni Helion come utente amministratore della cloud

-
Seleziona l'opzione Metodi di Notifica dal menu 'hamburger' nell'angolo in alto a sinistra dello schermo.

-
Crea un nuovo metodo di notifica, selezionando Webhook e inserisci i dettagli dell'URL a cui desideri inviare le notifiche tramite HTTP POST.

E questo è tutto ciò che c'è da fare con i webhook. Ma aspetta, 'come testiamo e verifichiamo questo' penso tu... beh, continua a leggere.
Crea un Allarme di Test
Torniamo al nostro menu 'hamburger' e questa volta seleziona Creazione Allarme e crea un nuovo allarme come segue – vogliamo falsi allarmi qui – quindi userò cpu.idle come metrica e imposterò valori assurdi –

Crea Nuova Definizione di Allarme
Inizialmente potrebbero apparire 2 Allarmi Sconosciuti poiché questa è la prima volta che questo allarme viene eseguito e non ha uno stato precedente. Tuttavia, sii paziente, tra qualche minuto dovresti vedere la dashboard illuminarsi come mostrato di seguito.

Attendi qualche minuto (5)
Ora puoi selezionare gli allarmi per maggiori dettagli.

Guarda gli Allarmi

Visualizza Dettagli Allarme
E naturalmente, quello per cui tutti abbiamo aspettato – allarmi webhook!!!
Doh! Come testiamo gli Allarmi Webhook…
Molte soluzioni di monitoraggio di livello enterprise ancora oggi non supportano i webhook – questi ragazzi non capiscono l'agile e si chiedono perché i pesci più piccoli li superino.
Di nuovo, non consiglio di fare nulla di ciò che stai per vedere su sistemi di produzione – questo è puramente per testare e verificare i webhook. Inoltre, si prega di notare che ho aperto una porta sul firewall del piano di controllo HOS per consentirmi di utilizzare il mio nodo di deploy come server webhook in esecuzione sulla porta 3001. [Vedi il post SMTP precedente se desideri testare questo NEL TUO LAB]
Nota: A tutti i programmatori là fuori mi scuso ora per tutte le regole che sto violando, scarsa programmazione ecc. siate gentili, ho assemblato questi esempi grazie a tutte le vostre pubblicazioni 🙂
Ho fornito due script di esempio di seguito, uno per NodeJS e uno per Python. Python perché molti utenti OpenStack saranno familiari con esso. NodeJS perché volevo una scusa per giocarci – è bello! Non sto coprendo come configurare i tuoi ambienti python o node qui, ci sono molti blog su questi argomenti. Virtual Environment (virtualenv) è il tuo amico se usi python – usalo.
Esempio Python
Copia il seguente script python in un file e salvalo come webhook.py. Questo script attende le notifiche webhook e quando le riceve le scrive in un file di log. Questo potrebbe essere utilizzato da soluzioni di monitoraggio legacy per analizzare gli avvisi – non è di livello enterprise però – solo un esempio.
webhook.py
# Author: Graham Joseph Land
# Blog: allthingscloud.eu
# Twitter: @allthingsclowd
# Email: graham@ the above domain
# Date: 24/03/2016
#
# Name: webhook.py
# Version: 0.1
# Purpose: This script listens for webhook notifications and then writes them to a logfile
#
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import json
import logging
import logging.handlers
# log file for this script
log_file = '/home/stack/monitoring/venv/webhook/webhook.log'
log_max_size = 25165824 # 24 MB
log_level = logging.INFO
#log_level = logging.DEBUG # DEBUG is quite verbose
log = logging.getLogger('log')
log.setLevel(log_level)
log_handler = logging.handlers.RotatingFileHandler(log_file,
maxBytes=log_max_size,
backupCount=4)
f = logging.Formatter("%(asctime)s %(filename)s %(levelname)s %(message)s",
"%B %d %H:%M:%S")
log_handler.setFormatter(f)
log.addHandler(log_handler)
class webhookReceiver(BaseHTTPRequestHandler):
def do_POST(self):
"""
receives post, handles it
"""
log.info('<<<<<<<<< Alert Start >>>>>>>>')
message = 'OK'
self.rfile._sock.settimeout(5)
data_string = self.rfile.read(int(self.headers['Content-Length']))
self.send_response(200)
self.send_header("Content-type", "text")
self.send_header("Content-length", str(len(message)))
self.end_headers()
self.wfile.write(message)
# parse data
text = json.loads(data_string)
text = json.dumps(text, indent=2)
log.info(text)
log.info('<<<<<<<<< Alert End >>>>>>>>')
def log_message(self, formate, *args):
"""
disable printing to stdout/stderr for every post
"""
return
def main():
"""
the main event.
"""
try:
server = HTTPServer(('', 3001), webhookReceiver)
log.info('started web server...')
server.serve_forever()
except KeyboardInterrupt:
log.info('ctrl-c pressed, shutting down.')
server.socket.close()
if __name__ == '__main__':
Esegui lo script e segui il file di log – ora torna indietro e genera di nuovo gli avvisi e vedi cosa succede..

Ecco fatto – webhook – "semplice"!
Per escludere problemi con Monasca, potresti anche testare questo script utilizzando un comando curl come segue:
curl -H "Content-Type: application/json" -X POST -d '{"alarm_id": "1234","alarm_definition_id": "freddef","alarm_name": "fire alarm","alarm_description": "alarmDescription","alarm_timestamp": "timestamp","state": "Critical","old_state": "oldState","message": "this is the message","tenant_id": "tenant1234","metrics": "1234"}' --trace-ascii debugdump.txt http://172.16.60.9:3000/openstack/alerts
Esempio NodeJS
Nota che sto utilizzando un endpoint webhook diverso rispetto a quello usato nell'esempio python.

C'è una struttura di file leggermente più complessa richiesta per l'applicazione di esempio NodeJS.
Utilizziamo il principale app server.js che poi richiama l'app 'route' webhook.js che elaborerà il webhook al ricevimento.
(venv)stack@helion-cp1-c0-m1-mgmt:~/monitoring/nodejs$ tree -I node_modules
.
|-- routers
| `-- webhook.js
`-- server.js
Copia le due app sottostanti in file corrispondenti denominati utilizzando la stessa struttura di directory mostrata sopra.
server.js
var bodyParser = require( 'body-parser' ),
express = require( 'express' ),
app = express();
var webhook = require( './routers/webhook' );
app.use( bodyParser.json() );
app.use( bodyParser.urlencoded({
extended: true
}) );
app.get( '/', function ( req, res, next ) {
res.send( 'Hooks listener running' );
});
app.use( '/openstack/alerts', webhook );
app.listen( 3001 );
e nella sottodirectory routers
webhook.js
var express = require( 'express' ),
bodyParser = require('body-parser'),
router = express.Router();
router.use(bodyParser.json());
router.post( '/', function ( req, res, next ) {
console.log(req.body);
res.status(200).json({message: 'Monasca Hook received!'})
});
module.exports = router;
Lancia l'app e testa prima con curl –
stack@helion-cp1-c0-m1-mgmt:~$ curl -H "Content-Type: application/json" -X POST -d '{"alarm_id": "1234","alarm_definition_id": "freddef","alarm_name": "fire alarm","alarm_description": "alarmDescription","alarm_timestamp": "timestamp","state": "Critical","old_state": "oldState","message": "this is the message","tenant_id": "tenant1234","metrics": "1234"}' --trace-ascii debugdump.txt http://172.16.60.9:3001/openstack/alerts
{"message":"Monasca Hook received!"}stack@helion-cp1-c0-m1-mgmt:~$
Il risultato dovrebbe assomigliare a questo
(venv)stack@helion-cp1-c0-m1-mgmt:~/monitoring/nodejs$ nodejs server.js
{ alarm_id: '1234',
alarm_definition_id: 'freddef',
alarm_name: 'fire alarm',
alarm_description: 'alarmDescription',
alarm_timestamp: 'timestamp',
state: 'Critical',
old_state: 'oldState',
message: 'this is the message',
tenant_id: 'tenant1234',
metrics: '1234' }
E infine, invia un allarme da Monasca come dettagliato in precedenza per vedere le notifiche webhook arrivare ed essere elaborate dall'app.

[Note: Risoluzione dei problemi di consegna delle notifiche]
- Se non vedi ancora alcun traffico ORA E il tuo file
/var/log/monasca/notification/notification.logè vuoto, prova a riconfigurare monasca
cd ~/scratch/ansible/next/hos/ansible
ansible-playbook -i hosts/verb_hosts monasca-reconfigure.yml
-
Quando riconfiguri le definizioni di allarme esistenti assicurati di selezionare ENTRAMBI la casella di controllo delle notifiche E i singoli metodi di notifica richiesti.

-
Usa TCPDUMP per verificare se il traffico webhook sta lasciando le interfacce di uno dei tre nodi controller [cerca il numero di porta webhook].
Originally published on allthingscloud.eu (2016-03-25).