Alle begrüßen liebe Leser. In diesem Artikel erzähle ich Ihnen von meinem „Fahrrad“, auf dem ich verschiedene Dinge überwache, ohne die Konsole zu verlassen.
Ich war einmal in einer Situation, in der viele verschiedene Projekte und Server gezüchtet wurden und meine Hände die normale Überwachung nicht erreichten.
Und in der modernen Welt bedeutet „korrekte“ Überwachung die Bereitstellung einer ganzen Reihe von Software, die Konfiguration dieser ganzen Sache. Nun, du weißt schon ... Docker, elastischer Stapel und los ging's. Für mich war es ein starker Aufwand. Ich wollte ein oder zwei in der Produktion.
Ich schaute in Richtung
Simple Monitor auf einer Python, es war mir im Geiste am nächsten, aber es fehlten einige Funktionen. Und zur gleichen Zeit wollte ich Go lernen ... nun, im Allgemeinen wissen Sie selbst, wie normalerweise alles beginnt.
Also nahm ich das Go-
Schweißen und stellte dieses
Fahrrad zusammen .
Cli Monitoring ist in Go geschrieben und besteht aus einer Reihe von Binärdateien, von denen jede Daten von stdin empfängt, eine bestimmte Aufgabe ausführt und das Ergebnis in stdout anzeigt.
Insgesamt gibt es vier Arten von Binärdateien:
Metriken ,
Prozessoren ,
Filter und
Ausgaben .
Wie der Name schon sagt, erfassen
Metriken alle Daten und stehen normalerweise an erster Stelle in der Kette.
Die Prozessoren befinden sich in der Mitte und ändern irgendwie die Daten oder führen andere Dienstprogrammfunktionen aus.
Filter sind fast wie Prozessoren, aber im Gegensatz zu ihnen überspringen sie je nach Bedingung Daten oder überspringen sie nicht.
Die Ausgänge befinden sich am Ausgang der Kette und werden zum Senden von Benachrichtigungen an verschiedene Dienste verwendet.
Die gesamte Befehlskette hat normalerweise die Form:
some_metric | processor_1 | processor_2 ... | cm_p_message | output_1 | output_2 ...
Jeder Teil dieser Kette kann ein beliebiger Linux-Befehl sein, solange er Daten in stdin empfängt und ohne Pufferung an stdout sendet. Es gibt nur einen kleinen ABER im Zusammenhang mit Zeilenumbrüchen, aber dazu später mehr.
Der Name der Binärdateien wird als
cm_ {type} _ {name} gebildet , wobei type einer von drei ist:
m, p, f oder o , und name ist der Name des Befehls.
Beispielsweise ist cm_m_cpu eine Metrik, die Statistiken über einen Prozessor im JSON-Format an stdout ausgibt.
Und die Datei cm_p_debounce ist ein Prozessor, der jedes Mal in einem bestimmten Intervall nur eine Nachricht ausgibt.
Es gibt einen speziellen
cm_p_message- Prozessor, der sich vor der ersten Ausgabe befinden muss. Es erstellt eine Nachricht im erforderlichen Format für die nachfolgende Verarbeitung durch seine Ausgaben.
Um mit json in der Konsole und unter verschiedenen Bedingungen
umzugehen , habe ich das Dienstprogramm
jq verwendet . Dies ist so etwas wie sed, nur für json.
So sieht beispielsweise die CPU-Überwachung am Ende aus.
cm_m_cpu | cm_p_eot2nl | jq -cM --unbuffered 'if .LoadAvg1 > 1 then .LoadAvg1 else false end' | cm_p_nl2eot | cm_f_regex -e '\d+' | cm_p_debounce -i 60 | cm_p_message -m 'Load average is {stdin}' | cm_o_telegram
Und so die Anzahl der Nachrichten in der RabbitMQ-Warteschlange überwachen
while true; do rabbitmqctl list_queues -p queue_name | grep -Po --line-buffered '\d+'; sleep 60; done | jq -cM '. > 10000' --unbuffered | cm_p_nl2eot | cm_f_true | cm_p_message -m 'There are more than 10000 tasks in rabbit queue' | cm_o_opsgenie
So können Sie in 10 Sekunden überwachen, dass nichts in die Datei geschrieben wurde
tail -f out.log | cm_p_nl2eot | cm_p_watchdog -i 10 | cm_p_debounce -i 3600 | cm_p_message -m 'No write to out.log for 10 seconds' -s 'alert' | cm_o_telegram
Beeilen Sie sich nicht, um den Bildschirm zu schließen. Jetzt werden wir im ersten Beispiel analysieren, was hier passiert.
1) Die Metrik
cm_m_cpu zeigt einmal pro Sekunde (angegeben durch den Parameter -i, standardmäßig eine Sekunde) Zeichenfolgen im JSON-Format an. Beispiel: {"LoadAvg1": 2.0332031, "LoadAvg2": 1.9018555, "LoadAvg3": 1.8623047}
2) cm_p_nl2eot ist einer der Dienstprogrammbefehle, die das EOT-Zeichen in das LF-Zeichen konvertieren. Um Probleme mit dem Zeilenumbruch zu vermeiden, habe ich mich entschlossen, sicherzustellen, dass alle meine Binärdateien Daten bis zum ASCII-Zeichen EOT (End of Transmission) lesen. Auf diese Weise können Sie sicher mehrzeilige Daten zwischen Teams übertragen.
Wenn andere Befehle aufgerufen werden, sollten sie daher in der folgenden Form umgeben sein:
cm_p_eot2nl | jedes andere Team | cm_p_nl2eot.3) Als nächstes wird das Dienstprogramm
jq aufgerufen , das das Feld LoadAvg1 überprüft. Wenn es größer als 1 ist, wird es weiter angezeigt, wenn weniger, wird false angezeigt
4) Als nächstes müssen wir die gesamte Nachricht
false aus der Kette werfen. Dazu wenden wir den Filter
cm_f_regex an , der eine Zeichenfolge als Eingabe verwendet, sie mit einem regulären Ausdruck vergleicht und im Falle einer Übereinstimmung weiter anzeigt. Andernfalls wird die Zeichenfolge einfach verworfen
Gewöhnliches grep könnte verwendet werden, aber erstens puffert es die Ausgabe und die vollständige Syntax wird etwas länger (grep --line-buffered), zweitens macht es cm_f_regex sehr einfach, Gruppenübereinstimmungen anzuzeigen. Z.B:
cm_f_regex -e '(\d+)-(\d+)' -o '{1}/{2}'
Konvertiert Zeile 123-345 in Zeile 123/345
5) Der Prozessor
cm_p_debounce nimmt in diesem Fall unseren LoadAvg1-Wert und zeigt ihn nur einmal alle 60 Sekunden in der Kette an. Dies ist notwendig, um sich nicht selbst zu spammen. Sie können ein beliebiges anderes Intervall einstellen.
6) Fast alles ist fertig. Es bleibt nur eine Nachricht zu bilden und sie an Telegramme zu senden. Die Nachricht wird mit dem speziellen Befehl
cm_p_message generiert. Es akzeptiert einfach eine Zeichenfolge als Eingabe, erstellt json mit den Feldern Schweregrad, Nachricht und anderen und gibt sie dann für die Ausgabeverarbeitung aus. Wenn wir die Option -m nicht übergeben würden, wäre stdin die Nachricht, d.h. Hirse Nummer ist unser LoadAvg1. Dies ist nicht sehr informativ.
7) Das cm_o_telegram-
Team sendet einfach die empfangene Nachricht an das Telegramm. Die Telegrammeinstellungen werden in einer INI-Datei gespeichert.
Konfiguration
Alle Parameter, die Binärdateien akzeptieren, können in der INI-Datei angegeben werden. Die durch das Befehlszeilenargument angegebenen Parameter haben Vorrang vor der INI-Datei.
Das Init-Dateiformat lautet:
[global]
host_name=override host name for this machine
[telegram]
cid=....
token=....
[opsgenie]
apiToken=...
apiEndpoint=...
......
[debounce]
i=3600
Die INI-Datei selbst wird in der folgenden Reihenfolge ausgewählt:
1) Die Datei cm.config.ini im aktuellen Arbeitsverzeichnis
2) Die Datei /etc/cm/config.ini, wenn die Datei aus Element 1 nicht gefunden wird
Produktion
Auf einem realen Server erstelle ich eine Datei, zum Beispiel cpu.sh, in die alle erforderlichen Befehlsketten geschrieben sind. Dann verschreibe ich in der Krone so etwas:
*/5 * * * * flock -n /etc/cm/cpu.lock /etc/cm/cpu.sh > /dev/null
Wenn etwas von der Herde fällt, wird der Befehl erneut ausgelöst. Und alle! Die Einfachheit, die mir nicht so fehlte.
Dies ist so ein Werkzeug, vielleicht findet es jemand bequem. Für mich ist es praktisch, dass nicht viele unnötige Dinge gemacht werden müssen, nur um die notwendigen Dinge zu überwachen. Und alles ist bequem konfiguriert: Es hat das Repository geklont, den Pfad zu den Binärdateien in $ PATH hinzugefügt und fertig.
Bitte urteilen Sie nicht streng. Das Tool wurde für mich geschrieben, der Befehlssatz ist noch nicht groß. Aber ich freue mich über Feedback und Anregungen. Vielen Dank für Ihre Aufmerksamkeit.