AWS CloudWatch: Log e Alarm
Lo scenario
Questo articolo descrive un semplice caso d'uso di AWS CloudWatch per le sue funzioni di logging e notifica.
Spesso è necessario essere informati del malfunzionamento di un servizio: una soluzione banale è scrivere un programma che controlli periodicamente lo stato di una certa risorsa e segnali eventuali anomalie.
La soluzione più ingenua ha due problemi elementari relativi al programma di controllo:
- non può risiedere sulla stessa risorsa che deve essere controllata perché naturalmente, in caso di disservizio, anche il programma di controllo non funzionerebbe e, di conseguenza, non verrebbe recapitata alcuna notifica, impedendo di essere informati dell'anomalia della risorsa da controllare;
- anche se posto su di una risorsa esterna a quella ospitante l'attività da controllare, il programma di controllo non può limitarsi a notificare lo stato della risorsa osservata soltanto in presenza di una anomalia, perché se il programma di controllo stesso, per qualche ragione, dovesse smettere di funzionare, non arriverebbero le comunicazioni né del suo malfunzionamento, né per il caso di contemporanea anomalia del sistema controllato stesso, facendo quindi erroneamente apparire il tutto come in una condizione di normalità.
Una soluzione è utilizzare un servizio esterno di grande affidabilità, meglio ancora se include molta logica per la soluzione di questo problema.
Con AWS CloudWatch e le sue funzionalità di Log e Alarm, è possibile ridurre al minimo la logica da programmare, avendo a disposizione un sistema molto robusto e flessibile: come potete immaginare, il risultato del nostro lavoro potrà essere utilizzato da ulteriori servizi, AWS nativi o nostri.
Preparare CloudWatch: Log
Fotografia di Elijah O'Donell / Unsplash
Su CloudWatch, nella sezione Log, si crea prima un group e, internamente al gruppo, uno stream.
Ora ipotizzo di controllare in qualche modo lo stato della mia risorsa, per esempio una volta al minuto e, in caso di buon esito, invio un log (usando naturalmente un utente AWS IAM opportunamente abilitato all'uso di CloudWatch). Per farlo, posso per esempio basarmi sul piccolo modulo Node.js di esempio che ho scritto, liberamente disponibile come Gist su GitHub che riporto qui di seguito.
Sempre restando su Node.js, uno snippet per chiarmarlo potrebbe essere questo:
const logger = require(/* modulo del gist */);
let mLog = logger.set(options);
mLog.log("info", {}); // uso un oggetto vuoto, giusto come spunto
Come potete notare, la chiamata è lasciata asincrona: a questo punto, quando la mia risorsa risulterà disponibile, su CloudWatch vedrò una nuova riga di log come la seguente
Preparare CloudWatch: Alarm
Fotografia di LinedPhoto / Unsplash
Come si vede dalla seguente schermata, configurando una soglia di fallimento, per esempio 3 log mancanti negli ultimi 3 minuti, è possibile creare una AWS SNS (AWS Simple Notification Service) senza doverla configurare direttamente.
Alle transizioni di stato della nostra risorsa (da stato normale a stato anomalo e viceversa quando ritornerà a stato normale) verremo avvisati, ricevendo una email alla casella di posta indicata nel campo Email list, avente un testo simile al seguente.
You are receiving this email because your Amazon CloudWatch Alarm "xxxxxx" in the EU (Frankfurt) region has entered the INSUFFICIENT_DATA state, because "Insufficient Data: 3 datapoints were unknown." at "Thursday 17 May, 2018 07:45:37 UTC".
View this alarm in the AWS Management Console:
https://console.aws.amazon.com/cloudwatch/home?region=eu-central-1#s=Alarms&alarm=sentryMissing
Alarm Details:
- Name: xxxxxx
- Description: a missing sentry triggers an alarm
- State Change: OK -> INSUFFICIENT_DATA
- Reason for State Change: Insufficient Data: 3 datapoints were unknown.
- Timestamp: Thursday 17 May, 2018 07:45:37 UTC
- AWS Account: xxxxxxxxxxxx
Threshold:
- The alarm is in the ALARM state when the metric is LessThanThreshold 1.0 for 60 seconds.
Monitored Metric:
- MetricNamespace: AWS/Logs
- MetricName: IncomingLogEvents
- Dimensions: [LogGroupName = xxxxxx]
- Period: 60 seconds
- Statistic: Average
- Unit: not specified
State Change Actions:
- OK:
- ALARM:
- INSUFFICIENT_DATA: [arn:aws:sns:eu-central-1:xxxxxxxxxxxx:xxxxxx]
L'invio di una email è naturalmente il caso più semplice ma alla SNS si potrebbero applicare funzioni sostanzialmente arbitrarie.
Ho osservato una asimmetria da parte di AWS, nei tempi di notifica relativi alle transizioni di stato (da guasto a operativo e viceversa, i tempi di variazione, da parte di AWS, sono in ritardo per entrambi i casi di alcuni minuti e una delle due transizioni viene rilevata più lentamente dell'altra ma comunque, attendendo alcuni minuti - quindi, nel mio caso, pochi campioni - il sistema rileva comunque correttamente la variazione).
Conclusioni
Fotografia di Samuel Zeller / Unsplash
Abbiamo visto un uso elementare delle funzionalità di logging e di alert di AWS CloudWatch, avendo anche fornito degli esempi di codice pronto da usare: nel caso la risorsa da osservare sia su rete pubblica, sarà possibile spostare lo script per esempio su di una Lambda, sempre per restare su AWS e senza doversi accollare la gestione di una macchina; nel caso invece si tratti di una risorsa privata (per esempio su di una rete locale o su di una VPN) allora si dovrà ricorrere a un più classico container o equivalente funzionale.
Spero che questo articolo possa essere di spunto per applicazioni interessanti, sicuramente riducendo il tempo di realizzazione di un piccolo ambiente di controllo, a maggior ragione considerando l'affidabilità e l'estendibilità di una soluzione basata su AWS.
--
Fotografia di copertina di Elijah O'Donell / Unsplash
Immagini censurate usando http://pinetools.com/censor-photo-blur-pixelate