Mi chiamo Anton Baderin. Lavoro presso il Centro Tecnologie Avanzate e mi occupo di amministrazione di sistemi. Un mese fa si è conclusa la nostra conferenza aziendale, dove abbiamo condiviso l'esperienza accumulata con la comunità IT della nostra città. Ho parlato del monitoraggio delle applicazioni web. Il materiale era destinato a un pubblico di livello junior o middle, che non aveva impostato questo processo da zero.

La pietra angolare di qualsiasi sistema di monitoraggio è la risoluzione delle problematiche aziendali. Il monitoraggio fine a se stesso non interessa a nessuno. Cosa desidera il business? Che tutto funzioni rapidamente e senza errori. Il business vuole proattività, che possiamo identificare autonomamente i problemi nel funzionamento del servizio e risolverli il più velocemente possibile. Queste sono, in sostanza, le sfide che ho affrontato per tutto lo scorso anno nel progetto di uno dei nostri clienti.
Il progetto
Il progetto è uno dei programmi di fedeltà più grandi del paese. Aiutiamo le reti di vendita al dettaglio ad aumentare la frequenza delle vendite tramite vari strumenti di marketing come le carte fedeltà. In totale, il progetto comprende 14 applicazioni, che operano su dieci server.
Durante i colloqui di lavoro, ho notato più volte che gli amministratori non sempre si approcciano correttamente al monitoraggio delle applicazioni web: molti si fermano ancora alle metriche del sistema operativo, monitorando raramente i servizi.
Nel mio caso, in precedenza il sistema di monitoraggio del cliente si basava su Icinga. Questo non affrontava le problematiche sopra menzionate. Spesso il cliente ci comunicava autonomamente i problemi e non di rado ci mancavano i dati per risalire alla causa.
Inoltre, c'era una chiara comprensione della mancanza di prospettive per il suo ulteriore sviluppo. Penso che chi conosce Icinga mi capirà. Pertanto, abbiamo deciso di riprogettare completamente il sistema di monitoraggio delle applicazioni web nel progetto.
Prometheus
Abbiamo scelto Prometheus sulla base di tre indicatori principali:
- Un numero enorme di metriche disponibili. Nel nostro caso sono 60.000. Certo, è da sottolineare che la stragrande maggioranza di esse non viene utilizzata (probabilmente circa il 95%). D'altra parte, sono tutte relativamente economiche. Per noi, questa è l'altra extremità, rispetto a quanto utilizzato precedentemente con Icinga. Aggiungere metriche in quell'ultima era particolarmente doloroso: quelle esistenti costavano molto (basta guardare il codice sorgente di qualsiasi plugin). Ogni plugin era uno script in Bash o Python, il cui avvio non è economico in termini di risorse consumate.
- Questo sistema consuma una quantità relativamente ridotta di risorse. Per tutte le nostre metriche, bastano 600 MB di memoria RAM, il 15% di un core e alcune decine di IOPS. Certo, dobbiamo avviare gli exporter di metriche, ma sono tutti scritti in Go e non si distinguono per affamato di risorse. Non credo che nelle attuali condizioni sia un problema.
- Consente il passaggio a Kubernetes. Considerati i piani del cliente, la scelta è evidente.
ELK
In precedenza non raccoglievamo né elaboravamo log. Gli svantaggi sono chiari a tutti. Abbiamo scelto ELK, poiché avevamo già esperienza con questo sistema. Conserviamo lì solo i log delle applicazioni. I criteri principali di scelta sono stati la ricerca full-text e la sua velocità.
Clickhouse
Inizialmente la scelta è ricaduta su InfluxDB. Eravamo consapevoli della necessità di raccogliere i log di Nginx, le statistiche da pg_stat_statements e di conservare dati storici di Prometheus. Non ci è piaciuto Influx, poiché ogni tanto iniziava a consumare una grande quantità di memoria e crollava. Inoltre, volevamo raggruppare le richieste per remote_addr, mentre il raggruppamento in questo DB è solo per tag. I tag costano (memoria), il loro numero è limitato.
Abbiamo ricominciato le ricerche. Avevamo bisogno di una base analitica con un consumo minimo di risorse, preferibilmente con compressione dei dati su disco.
Clickhouse soddisfa tutti questi criteri, e non ci siamo mai pentiti della scelta. Non scriviamo volumi di dati eccezionali in esso (il numero di inserimenti è di circa cinquemila al minuto).
NewRelic
NewRelic è storicamente con noi, poiché era la scelta del cliente. Lo utilizziamo come APM.
Zabbix
Utilizziamo Zabbix esclusivamente per il monitoraggio della Black Box di varie API.
Definizione dell'approccio al monitoraggio
Volevamo decomporre il compito e in tal modo sistematizzare l'approccio al monitoraggio.
Per questo ho suddiviso il nostro sistema nei seguenti livelli:
- «hardware» e VMS;
- sistema operativo;
- servizi di sistema, stack software;
- applicazione;
- logica di business.
I vantaggi di questo approccio:
- sappiamo chi è responsabile del funzionamento di ciascun livello e, di conseguenza, possiamo inviare notifiche;
- possiamo utilizzare la struttura per sopprimere le notifiche: sarebbe strano inviare una notifica per l'inaccessibilità del database quando l'intera macchina virtuale è inaccessibile.
Poiché il nostro obiettivo è identificare le anomalie nel funzionamento del sistema, dobbiamo identificare un insieme di metriche a ciascun livello da tenere in considerazione nella scrittura delle regole di notifica. Procederemo quindi attraverso i livelli «VMS», «Sistema Operativo» e «Servizi di Sistema, Stack Software».
Le macchine virtuali
Hosting ci fornisce CPU, disco, memoria e rete. E con i primi due abbiamo avuto problemi. Ecco quindi le metriche:
CPU stolen time — quando acquisti una macchina virtuale su Amazon (t2.micro, ad esempio), devi comprendere che ti viene assegnato non un intero core della CPU, ma solo una quota del suo tempo. E quando esaurisci questa quota, la CPU inizierà a essere prelevata da te.
Questa metrica consente di monitorare tali situazioni e prendere decisioni. Ad esempio, è necessario passare a una tariffa più robusta o suddividere l’elaborazione delle attività in background e le richieste API su diversi server.
IOPS + tempo di attesa CPU iowait — per qualche motivo molti servizi di hosting cloud hanno il difetto di non fornire abbastanza IOPS. Inoltre, un grafico con bassi IOPS per loro non è un argomento. Pertanto, è utile raccogliere anche il tempo di attesa CPU iowait. Con questa coppia di grafici — bassi IOPS e alta attesa di input-output — si può già avviare una discussione con l'hosting e risolvere il problema.
Sistema operativo
Metriche del sistema operativo:
- quantità di memoria disponibile in %;
- attività di utilizzo dello swap: vmstat swapin, swapout;
- numero di inode disponibili e spazio libero sul file system in %
- carico medio;
- numero di connessioni in stato tw;
- saturazione della tabella conntrack;
- la qualità del lavoro della rete può essere monitorata con l'utility ss, il pacchetto iproute2 — per ottenere dal suo output il valore RTT delle connessioni e raggruppare per porta di destinazione.
Inoltre, a livello di sistema operativo abbiamo una nozione di processi. È importante identificare nel sistema un insieme di processi che svolgono un ruolo cruciale nel suo funzionamento. Se, ad esempio, hai più pgpool, è necessario raccogliere informazioni su ciascuno di essi.
L'insieme di metriche è il seguente:
- CPU;
- la memoria è, innanzitutto, residente;
- IO — preferibilmente in IOPS;
- FileFd — file aperti e limite;
- errori di pagina significativi — così puoi capire quale processo è in swap.
Tutto il monitoraggio è eseguito in Docker, per la raccolta dei dati metrici utilizziamo Cadvisor. Su altre macchine utilizziamo process-exporter.
Servizi di sistema, stack software
Ogni applicazione ha la sua specificità, ed è difficile distinguere un insieme di metriche.
Un insieme universale è:
- tasso di richieste;
- numero di errori;
- latenza;
- saturazione.
I più evidenti esempi di monitoraggio di questo livello sono Nginx e PostgreSQL.
Il servizio più carico del nostro sistema è il database. In passato, avevamo spesso problemi a capire cosa stesse facendo il database.
Abbiamo notato un alto carico sui dischi, ma i slow log non mostravano nulla di sostanziale. Abbiamo risolto questo problema con pg_stat_statements, una vista che raccoglie statistiche sulle richieste.
È tutto ciò di cui ha bisogno un amministratore.
Costruiamo grafici sull'attività delle richieste di lettura e scrittura:


È tutto semplice e chiaro, ogni richiesta ha il suo colore.
Un esempio altrettanto significativo sono i log di Nginx. Non sorprende che pochi li analizzino o li menzionino nella lista di quelli obbligatori. Il formato standard non è molto informativo e deve essere ampliato.
Personalmente, ho aggiunto request_time, upstream_response_time, body_bytes_sent, request_length, request_id. Costruiamo grafici sui tempi di risposta e sul numero di errori:


Costruiamo grafici sui tempi di risposta e sul numero di errori. Ricordi? Ho parlato delle esigenze aziendali? Per essere rapidi e senza errori? Abbiamo già coperto queste questioni con due grafici. E su di essi è già possibile contattare gli amministratori in servizio.
Ma rimane ancora un problema — garantire una rapida risoluzione delle cause dell'incidente.
Risoluzione degli incidenti
L'intero processo dalla rilevazione alla risoluzione del problema può essere suddiviso in vari passaggi:
- rilevazione del problema;
- notifica dell'amministratore di turno;
- reazione all'incidente;
- risoluzione delle cause.
È importante che dobbiamo farlo il più rapidamente possibile. E se nelle fasi di rilevazione del problema e invio della notifica non possiamo guadagnare tempo — ci vorranno due minuti comunque, le fasi successive sono un campo lasciato incolto per i miglioramenti.
Immaginiamo semplicemente che il telefono del servizio di guardia stia squillando. Cosa farà? Cercherà risposte alle domande: cosa è rotto, dove è rotto, come reagire? Ecco come rispondiamo a queste domande:

Includiamo semplicemente tutte queste informazioni nel testo della notifica, fornendo un link a una pagina nel wiki dove è descritto come reagire a questo problema, come risolverlo e come escalare.
Non ho ancora detto nulla riguardo al livello dell'applicazione e della logica di business. Purtroppo, nelle nostre applicazioni non è ancora implementata la raccolta delle metriche. L'unica fonte di informazioni, anche parziali, a questi livelli sono i log.
Un paio di punti.
In primo luogo, scrivete log strutturati. Non includete il contesto nel testo del messaggio. Questo complica la loro raggruppamento e analisi. Logstash richiede molto tempo per normalizzare tutto questo.
In secondo luogo, usate correttamente i livelli di severità. Ogni linguaggio ha il proprio standard. Personalmente, ne distinguo quattro livelli:
- nessun errore;
- errore lato client;
- errore lato nostro, non perdiamo soldi, non ci sono rischi;
- errore lato nostro, perdiamo soldi.
In sintesi. Occorre cercare di costruire il monitoraggio proprio dalla logica di business. Cercare di monitorare l'applicazione stessa e operare già con metriche come il numero di vendite, il numero di nuove registrazioni utenti, il numero di utenti attivi in quel momento e così via.
Se tutto il vostro business si riduce a un pulsante nel browser, è necessario monitorare se viene premuto, se funziona correttamente. Tutto il resto non è importante.
Se non lo avete, potete cercare di recuperarlo nei log dell'applicazione, nei log di Nginx e così via, come abbiamo fatto noi. Dovete essere il più vicino possibile all'applicazione.
Le metriche del sistema operativo sono ovviamente importanti, ma non interessano al business, non ci pagano per esse.
Fonte: habr.com
