Gelöst! Shell Skript für systemd Überwachung

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 03.03.2018 19:36:34

Ahso. Ja. Stimmt. Sorry.
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

NAB
Beiträge: 5501
Registriert: 06.03.2011 16:02:23
Lizenz eigener Beiträge: MIT Lizenz

Re: Shell Skript für systemd Überwachung

Beitrag von NAB » 04.03.2018 00:37:31

Nastra hat geschrieben: ↑ zum Beitrag ↑
03.03.2018 18:27:45
Hatte voller Euphorie noch den Skript Aufbau von breakthewall etwas im Hinterkopf (was ja garnicht lief in meinem Szenario) bei dem man auch den Suchbegriff mit der Individuellen Nachricht verknüpfen konnte.

Ich denke das ich dass nicht unbedingt brauche (das wäre mehr nice to have für andere Szenarien)
Hmm ... den Suchbegriff mit der Individuellen Nachricht verknüpfen? Ich hab mir das Script von breakthewall noch mal angeguckt ... auch der versteckt die Suchbegriffe irgendwo in der Programmlogik. Aber wenigstens stehen die Nachrichten groß oben drüber.

Ich hab noch mal etwas am Script herumgebastelt. Ich stecke die Ausgabe von journalctl jetzt in eine ewige While-Schleife. Die While-Schleife bekommt jede einzelne Zeile vorgelegt, die journalctl ausspuckt. Die Zeile steckt sinniger Weise in der Variablen $zeile. Die While-Schleife prüft in (bisher drei) IF THEN Konstrukten per grep auf die (bisher drei) Suchbegriffe und bei Erfolg tut sie was. Nur was?

Ich habe zwei Varianten geschrieben. Ich kann mich nicht entscheiden, welche Version ich dir zeigen soll, also zeig ich dir beide: Variante 1:

Code: Alles auswählen

#!/bin/bash

suchbegriff1="Failed"
nachricht1="Auf Homeserver ist was schiefgelaufen: "

suchbegriff2="Started.*homebridge-test"
nachricht2="homebridge-test wurde gestartet."

suchbegriff3="USB-Stick"
nachricht3="Jemand hat USB-Stick gesagt! "

journalctl -u homebridge-test -u homebridge-hue -u backup -f --since "now"  | \
    while read -r zeile; do
	
        if grep --quiet "$suchbegriff1" <<< "$zeile"; then
           echo sudo -u pi ntfy -b telegram send "$nachricht1$zeile"
	fi

        if grep --quiet "$suchbegriff2" <<< "$zeile" ; then
           echo sudo -u pi ntfy -b telegram send "$nachricht2"
	fi

        if grep --quiet "$suchbegriff3" <<< "$zeile" ; then 
	   echo sudo -u pi ntfy -b telegram send "$nachricht3"
	fi
		
    done
Und Variante 2:

Code: Alles auswählen

#!/bin/bash

suchbegriff1="Failed"
nachricht1="Auf Homeserver ist was schiefgelaufen: "

suchbegriff2="Started.*homebridge-test"
nachricht2="homebridge-test wurde gestartet."

suchbegriff3="USB-Stick"
nachricht3="Jemand hat USB-Stick gesagt! "

journalctl -u homebridge-test -u homebridge-hue -u backup -f --since "now"  | \
    while read -r zeile; do
	
        if grep --quiet "$suchbegriff1" <<< "$zeile"; then
	   nachricht=$nachricht1$zeile
	fi

        if grep --quiet "$suchbegriff2" <<< "$zeile" ; then
	   nachricht=$nachricht2
	fi

        if grep --quiet "$suchbegriff3" <<< "$zeile" ; then 
	   nachricht=$nachricht3
	fi

        if [ -n "$nachricht" ]; then
	   echo sudo -u pi ntfy -b telegram send "$nachricht"
	   nachricht="" 
	fi    
		
    done
Die erste Variante schickt dir bei jedem Treffer auf einen Suchbegriff sofort eine Nachricht. Da könntest du zum Beispiel auch eine andere Aktion eintragen als das Versenden einer Nachricht.

Die zweite Variante befüllt bei jedem Treffer auf einen Suchbegriff nur die Variable "nachricht" (ohne Zahl dahinter). Und ganz am Ende guckt sie nach, ob in "nachricht" was drin ist (das vierte IF-THEN Konstrukt) und wenn ja, schickt sie dir diese einzelne Nachricht.

Beide Scripte schicken dir übrigens nicht wirklich Nachrichten. Sie drucken dir mit "echo" nur aus, was sie tun würden. Starte die erst mal so auf der Konsole und schau, was du damit anfangen kannst. Wenn es gut aussieht, kannst du das "echo" im "echo sudo" entfernen.

Und wenn du genau hinschaust ... beim ersten IF-THEN-Konstrukt habe ich etwas anders gemacht. Da hänge ich an nachricht1 noch $zeile ran. Dadurch wird dir die gesamte Zeile aus journalctl zur Nachricht hinzugefügt. Kannst du natürlich auch anders machen.
Nastra hat geschrieben: ↑ zum Beitrag ↑
03.03.2018 19:24:47
Die Service sind doch alle selber manuell angelegt egal ob ich jetzt Lösung von NAB oder TomL benutze, welcher Art Update würde diese Units verändern im nachhinein ?
Das können wir doch nicht wissen, welche Units du alle überwachen willst. Und du selber denkst ja auch über "andere Szenarien" nach :wink:
Never change a broken system. It could be worse afterwards.

"No computer system can be absolutely secure." Intel Document Number: 336983-001

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 04.03.2018 02:31:54

Also ein Skript, welches das Journal parst, brauch doch viel zu viel Ressourcen. Zumal es doch bei systemd einen Mechanismus gibt, der auf fehlschlagende Services direkt reagiert.

Was interessiert mich ein journal in einer telegram-Nachricht, wenn doch der Name der Unit ausreicht, um zu wissen, welcher service ausgefallen ist. Ich muss ja sowieso auf den Rechner um zu recherchieren, was das Problem ist.
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

NAB
Beiträge: 5501
Registriert: 06.03.2011 16:02:23
Lizenz eigener Beiträge: MIT Lizenz

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von NAB » 04.03.2018 03:15:04

Eh ... viel zu viel Ressourcen? Hat dein PC sehr lange gebraucht, um all den Text dieser Webseite zu parsen?

Dass euer Ansatz auf "failed" reagieren kann, haben wir doch nun schon durchgekaut. Das ist aber auch alles.
Never change a broken system. It could be worse afterwards.

"No computer system can be absolutely secure." Intel Document Number: 336983-001

Nastra
Beiträge: 94
Registriert: 13.02.2018 05:12:27

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von Nastra » 04.03.2018 05:52:24

Guten Morgen NAB,

habe gerade beide Variante Live getestet, was soll ich sagen, absolute Spitze, bin echt baff :THX: :THX: :THX: :THX: :THX:

Ich habe mich vorerst für Variante II entschieden, da ich bisher nur das Szenario habe eine Telegram Nachricht zu verschicken. Aber Variante I ist natürlich für maximale Flexibilität genial um eventuell andere Dinge anzustoßen. Da muss ich mir nochmal Gedanken machen was man alles schönes anstellen kann statt eine Nachricht zu versenden :mrgreen:

Habe auch schon alles angepasst nach meinen Bedürfnissen und es läuft :wink:

Dankeschön!!!! :hail:

NAB
Beiträge: 5501
Registriert: 06.03.2011 16:02:23
Lizenz eigener Beiträge: MIT Lizenz

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von NAB » 04.03.2018 15:03:38

Nastra hat geschrieben: ↑ zum Beitrag ↑
04.03.2018 05:52:24
Ich habe mich vorerst für Variante II entschieden, da ich bisher nur das Szenario habe eine Telegram Nachricht zu verschicken. Aber Variante I ist natürlich für maximale Flexibilität genial um eventuell andere Dinge anzustoßen. Da muss ich mir nochmal Gedanken machen was man alles schönes anstellen kann statt eine Nachricht zu versenden :mrgreen:
Ich bin mir nicht sicher, ob du das verstanden hast. Auch Variante 1 ist nicht dafür gedacht, dir drei Nachrichten auf einmal zu schicken. Den drei IF-THEN-Konstrukten wird in beiden Varianten immer die aktuelle Zeile aus journalctl vorgelegt. Wenn du Variante 1 dazu kriegst, dir drei Nachrichten zu schicken, dann hast du sehr dämliche Suchbegriffe genommen, zum Beispiel "exited", "exit" und "ex". Dann kriegst du auf "exited" wirklich drei Nachrichten.

Variante 2 würde dir in diesem Fall nur die letzte der drei Nachrichten schicken, aber dämlich wär's trotzdem :wink:

P.S.: Genehmigung zum Veröffentlichen dieser Scripte ausdrücklich erteilt, auf Anfrage des TE per PN.
Never change a broken system. It could be worse afterwards.

"No computer system can be absolutely secure." Intel Document Number: 336983-001

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 06.03.2018 09:20:11

Ich kann mir nicht helfen... Eine Lösung, in der das ganze journal regelmäßig geparst werden muss, ist keine schöne Lösung.

Wenn du eine Nachricht bei erfolgreichem Ende willst, verwende eine Zeile

Code: Alles auswählen

 ExecStarPost=/usr/local/bin/ntfy... 
.
Und beim fehlschlagen ruf mit OnFailure= einen Service auf, der dich benachrichtigt.

Damot hat du in der Sekunde eine Verständigung, was los ist. Und du sparst dir das regelmäßige Parsen des Journals.

Das Backupskript von ExecStart darf dabei nicht in den Hintergrund geforkt werden!

Lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Nastra
Beiträge: 94
Registriert: 13.02.2018 05:12:27

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von Nastra » 06.03.2018 15:53:48

Hallo nochmal zusammen,

da ich die Tage einen alten Freund getroffen habe der mir noch ein wenig unter die Arme gegriffen hat bezüglich meines Vorhabens möchte ich euch meine entgültige Lösung natürlich hier auch nicht vorenthalten.

Als Grundlage für diese erweiterterung hat das Skript von @NAB siehe weiter oben (Variante II) gedient.

Zusammenfassung:
Mit diesem Skript ist es jetzt möglich verschieden Units /Service zu Überwachen auf bestimmte Suchbegriffe. Sollte einer dieser Suchbegriffe auftauchen wird eine Nachricht über den Telegram Messenger versendet. Die besonderheit dabei ist das bei meinem vorhaben die homebridge alle 10 Sekunden nach einem Absturz neustartet um den Dienst nach möglichkeit schnellstmöglich wieder aufzunehmen gem. Unit einstellungen onFailure.

Da ich aber nicht alle 10 Sek eine Nachricht erhalten möchte sondern nur alle 30 Min, falls man mal nicht direkt nachsehen kann oder es Nacht ist wird nun ein Zeitstempel nach erstmaligen auslösen der Nachricht hinzugefügt.
Dadurch ist es möglich das die nächste Nachricht wie hier im Beispiel mit einer Verzögerung von 30 Minuten erst wieder erneut gesendet wird.

Die systemd Lösungen waren mir schlussendlich für mein spezielles Vorhaben zu unflexibel. Trotzdem nochmal danke an alle Beteiligten!

Code: Alles auswählen

#!/bin/bash

######################## NACHRICHTEN VERZÖGERUNG ######################


letzteNachricht1=$(($(date +"%s")-1800))

letzteNachricht2=$(($(date +"%s")-1800))

letzteNachricht3=$(($(date +"%s")-1800))

letzteNachricht4=$(($(date +"%s")-1800))


######################## Überwachte Service ###########################


journalctl -u homebridge* -f --since "now"  | \
while read -r zeile; do


########################## SUCHBEGRIFFE ###############################


suchbegriff1="homebridge.*FAILURE"
nachricht1="ACHTUNG: "

suchbegriff2="communication"
nachricht2="HINWEIS: "
	
suchbegriff3="error"
nachricht3="HINWEIS: "

suchbegriff4="UUID"
nachricht4="HINWEIS: "


########################## NACHRICHTEN ###############################


if grep --quiet "$suchbegriff1" <<< "$zeile "  && [ $((letzteNachricht1+1800)) -lt $(date +"%s ") ] ; then
nachricht=$nachricht1$zeile
letzteNachricht1=$(date +"%s ")
fi


if grep --quiet "$suchbegriff2" <<< "$zeile "  && [ $((letzteNachricht2+1800)) -lt $(date +"%s ") ] ; then
nachricht=$nachricht2$zeile
letzteNachricht2=$(date +"%s ")
fi


if grep --quiet "$suchbegriff3" <<< "$zeile "  && [ $((letzteNachricht3+1800)) -lt $(date +"%s ") ] ; then
nachricht=$nachricht3$zeile
letzteNachricht3=$(date +"%s ")
fi


if grep --quiet "$suchbegriff4" <<< "$zeile "  && [ $((letzteNachricht4+1800)) -lt $(date +"%s ") ] ; then
nachricht=$nachricht4$zeile
letzteNachricht3=$(date +"%s ")
fi


################## VERSAND ÜBER NTFY AN TELEGRAM #####################


if [ -n "$nachricht" ]; then
sudo -u pi ntfy -b telegram send "$nachricht"
nachricht=""
fi    
		
done
Gruß Nastra

NAB
Beiträge: 5501
Registriert: 06.03.2011 16:02:23
Lizenz eigener Beiträge: MIT Lizenz

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von NAB » 06.03.2018 18:55:00

Man man man ... das ist ja ganz schön fett geworden im Vergleich zu den drei Zeilen am Anfang :mrgreen:

Ich würde die "1800" auch noch zu einer Variablen machen:

Code: Alles auswählen

######################## NACHRICHTEN VERZÖGERUNG ######################
flutschutz1=1800
letzteNachricht1=$(($(date +"%s")-$flutschutz1))
Das IF-THEN-Konstrukt sähe dann so aus:

Code: Alles auswählen

if grep --quiet "$suchbegriff1" <<< "$zeile"  && [ $((letzteNachricht1+$flutschutz1)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht1$zeile
    letzteNachricht1=$(date +"%s ")
fi
Vorteil: Du musst die "1800" nicht in jedem IF-THEN-Konstrukt per Hand nachbesser, wenn du sie ändern willst.

Außerdem könnte man:

Code: Alles auswählen

jetzt=$(date +"%s")

if grep --quiet "$suchbegriff1" <<< "$zeile "  && [ $((letzteNachricht1+$flutschutz1)) -lt $jetzt ] ; then
    nachricht=$nachricht1$zeile
    letzteNachricht1=$jetzt
fi
Vorteil: das "date" wird nur einmal pro While-Schleifen-Durchgang aufgerufen (dafür aber jedes mal). Achtung: Das jetzt=$(date +"%s") muss da auch nur ein mal stehen, vor dem ersten IF-THEN.

Außerdem würde ich "SUCHBEGRIFFE" wieder vor die While-Schleife ziehen ... die Variablen werden jetzt nämlich sinnloser Weise bei jedem Durchgang neu definiert.

Und die IF-THEN-Konstrukte sind jetzt etwas unübersichtlich geworden, aber was "benutzerfreundlicheres" fällt mir auch nicht ein. Man könnte sie auseinanderziehen, das macht's aber länger und vermutlich trotzdem nicht besser. Mal schauen, ob da jemand noch eine elegantere Idee hat ...

P.S.: Und ich würd's "NACHRICHTEN BEGRENZUNG" nennen ... verzögern tust du da nämlich eigentlich nichts. Ich hab erst mal dumm geguckt, was das eigentlich soll, bis ich mir den Sinn erschlossen habe.
Never change a broken system. It could be worse afterwards.

"No computer system can be absolutely secure." Intel Document Number: 336983-001

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 06.03.2018 19:45:48

Postest du deine Unit bitte auch noch einmal?
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Nastra
Beiträge: 94
Registriert: 13.02.2018 05:12:27

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von Nastra » 06.03.2018 21:23:49

Hier noch die Unit:

Code: Alles auswählen

[Unit]
Description=reporter.service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/reporter.sh
Restart=always
SyslogIdentifier=reporter.service

[Install]
WantedBy=multi-user.target

@NAB

danke für die Verbesserungsvorschläge ich schaue Sie mir morgen in Ruhe an und teste es mal aus.
Melde mich dann wieder :wink:

NAB
Beiträge: 5501
Registriert: 06.03.2011 16:02:23
Lizenz eigener Beiträge: MIT Lizenz

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von NAB » 06.03.2018 23:30:55

Restart=always? Also ... theoretisch ist das Script natürlich fehlerfrei und der Fall tritt nie ein.

Aber praktisch ... wenn's dann doch abschmiert, Systemd es neu startet _und_ es dir eine Nachricht schickt ... und das in Endlosschleife ... dann wirste wieder mit Nachrichten zugeballert ...
Never change a broken system. It could be worse afterwards.

"No computer system can be absolutely secure." Intel Document Number: 336983-001

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 07.03.2018 08:58:41

Ich meine auch die Units der Services, die du Überwachen willst. Bitte!

lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Nastra
Beiträge: 94
Registriert: 13.02.2018 05:12:27

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von Nastra » 07.03.2018 09:11:59

Hatte ich nicht so verstanden aber es ist 17 mal diese Unit. Sind alle gleich aufgebaut, steuern nur andere Plugins an also andere EnvironmentFile Pfade und andere Description.

z.B. homebridge-hue

Code: Alles auswählen

[Unit]
Description=homebridge-soundtouch.service 
After=syslog.target network-online.target

[Service]
Type=simple
User=root
EnvironmentFile=/etc/default/homebridge-soundtouch
ExecStart=/usr/bin/homebridge $HOMEBRIDGE_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 07.03.2018 09:23:23

UI... da gibts auch noch Verbesserungsbedarf... :)

Wie unterscheiden sich diese 17 Units konkret?

Wenn sich bloß "soundtouch" unterscheidet, dann erstelle eine einzige Unit die homebridge@.service heißt und folgenden Inhalt hat:

Code: Alles auswählen

[Unit]
Description=homebridge-%i.service 
After=syslog.target network-online.target

[Service]
Type=simple
User=root
EnvironmentFile=/etc/default/homebridge-%i
ExecStart=/usr/bin/homebridge $HOMEBRIDGE_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target
%i in der Unit wird dann durch das ersetzt, was im Aufruf der Unit zwischen dem ersten "@" und dem letzten ".service" steht.

Dann starte die Units mit

Code: Alles auswählen

systemctl start homebridge@soundtouch.service homebridge@bla.service homebridge@blubb.service
Die Config-Files müssten dann homebridge-soundtouch hombridge-bla homebridge-blubb usw. heißen

Dann pflegst du bloß eine einzige systemd-Unit und 17 Konfigs, statt 17 systemd-Units und 17 Konfigs.

Du kannst ja einmal nur deine Unit homebridge-soundtouch.service stoppen und mit der neuen homebridge@soundtouch.service starten. Wenn das funktioniert (wovon ich ausgehe), kannst du alle deine vielen Units stoppen und die neuen - sogenannte instanziierende - Units enablen mit

Code: Alles auswählen

systemctl enable homebridge@soundtouch.service homebridge@bla.service homebridge@blubb.service
lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 07.03.2018 12:13:53

Btw... Ganz will ich noch nicht locker lassen... :)
Ich hab das als Herausforderung genommen, um wieder mal etwas dazuzulernen.

Erweitere die Unit von vorhin auf das:

Code: Alles auswählen

[Unit]
Description=homebridge-%i.service 
After=syslog.target network-online.target
OnFailure=OnFailure=notification-telegram-failed@%n.service

[Service]
Type=simple
User=root
EnvironmentFile=/etc/default/homebridge-%i
ExecStart=/usr/bin/homebridge $HOMEBRIDGE_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target
Und dann erstelle dir die Unit
/etc/systemd/system/notification-telegram-failed@%n.service

Code: Alles auswählen

[Unit]
Description=Send failure-notification about %i to telegram

[Service]
User=DEINLOGINUSER
Environment=TSF=/tmp/%i.failed
Environment=FLOODC=60
ExecStartPre=/bin/bash -c "[ -e $TSF ] || echo $(($(date +%%s)-$FLOODC)) > $TSF"
ExecStart=/bin/bash -c "if [ $(($(cat $TSF)+$FLOODC)) -lt $(date +"%%s") ]; then echo $(date +"%%s") > $TSF; /usr/local/bin/ntfy -b telegram send \"FAILED\n$(systemctl status %i)\"; else exit 0; fi"
Das ganze Konstrukt startet im Failure-Falle deinen Homebridge-Servie neu. (Du weißt, je nachdem was du zwischen @ und .service schreibst, wird der entsprechende Service konstruiert.

Schlägt der Service fehl, wird er nach 10 Sekunden restartet und es wird die Notification-Unit für telegram gestartet.
Die Notification-Unit hat eine Begrenzung eingebaut, dass innerhalb einer FLOODC-Periode (60s) nur einmal eine Notification geschickt wird.
Es wird dazu je überwachter Unit ein File in /tmp mit dem Timestamp der letzten Nachricht abgelegt.

Die Notification enthält als erstes Wort "FAILED" und dann die Ausgabe von systemctl status überwachter.service
UND die Notification wird von deinem User ausgeführt. Die könntest du sogar von einem vollkommen unprivilegierten User ohne weitere Rechte auch ausführen lassen, was die Sicherheit deutlich erhöht.

Ich hab jetzt genau 2 Service-Units, mit der ich 1, 20 oder 500 homebridge-Services starten, überwachen (=Notification senden, wenn der Service ausfällt) und automatisch restarten lassen kann.

Du hast 17 Unit-Files (die du einzeln anpassen musst, wenn du eine kleine Änderung auf alle anwenden möchtest), 17 Konfigurationsfiles, ein Shell-Skript, welches permanent das journal parst (was performance kostet) und das als root eine Notification an telegram schickt.

Überleg noch einmal, ob deine Lösung wirklich so gut ist.

lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Nastra
Beiträge: 94
Registriert: 13.02.2018 05:12:27

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von Nastra » 07.03.2018 15:19:13

an man man ... das ist ja ganz schön fett geworden im Vergleich zu den drei Zeilen am Anfang
@NAB Da sagst du was, braucht man bald einen Waffenschein für :mrgreen:

Ich habe das Skript jetzt angepasst gem. deinen Vorschlägen. Ich hoffe ich habe alles richtig verstanden und umgesetzt. Ich habe es natürlich auch produktiv getestet. Der reporter.service lässt sich kurz starten aber beendet sich kurz danach wieder. Daher gehe ich mal davon aus das ich doch was falsch umgesetzt habe?

reporter.service

Code: Alles auswählen

pi@HomeKitServer:~ $ sudo systemctl status reporter.service
● reporter.service
   Loaded: loaded (/etc/systemd/system/reporter.service; enabled; vendor preset: enabled)
   Active: active (running) since   CET; 60ms ago
 Main PID: 17841 (reporter.sh)
    Tasks: 2 (limit: 4915)
   CGroup: /system.slice/reporter.service
           ├─17841 /bin/bash /usr/local/bin/reporter.sh
           └─17846 journalctl -u homebridge* -f --since now

Mär 07 14:48:34 HomeKitServer systemd[1]: Stopped reporter.service.
Mär 07 14:48:34 HomeKitServer systemd[1]: Started reporter.service.
pi@HomeKitServer:~ $ sudo systemctl status reporter.service
● reporter.service
   Loaded: loaded (/etc/systemd/system/reporter.service; enabled; vendor preset: enabled)
   Active: active (running) since   CET; 4ms ago
 Main PID: 17855 (reporter.sh)
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/reporter.service
           └─17855 /bin/bash /usr/local/bin/reporter.sh

Mär 07 14:48:35 HomeKitServer systemd[1]: Started reporter.service.
pi@HomeKitServer:~ $ sudo systemctl status reporter.service
● reporter.service
   Loaded: loaded (/etc/systemd/system/reporter.service; enabled; vendor preset: enabled)
   Active: failed (Result: start-limit-hit) since  CET; 3ms ago
  Process: 17866 ExecStart=/usr/local/bin/reporter.sh (code=exited, status=0/SUCCESS)
 Main PID: 17866 (code=exited, status=0/SUCCESS)

Mär 07 14:48:36 HomeKitServer systemd[1]: reporter.service: Service hold-off time over, scheduling restart.
Mär 07 14:48:36 HomeKitServer systemd[1]: Stopped reporter.service.
Mär 07 14:48:36 HomeKitServer systemd[1]: reporter.service: Start request repeated too quickly.
Mär 07 14:48:36 HomeKitServer systemd[1]: Failed to start reporter.service.
Mär 07 14:48:36 HomeKitServer systemd[1]: reporter.service: Unit entered failed state.
Mär 07 14:48:36 HomeKitServer systemd[1]: reporter.service: Failed with result 'start-limit-hit'.
pi@HomeKitServer:~ $ 

Hier das Skript, nach dem ich es angepasst habe:

Code: Alles auswählen

#!/bin/bash

######################## NACHRICHTEN BEGRENZUNG ######################


flutschutz1=60
letzteNachricht1=$(($(date +"%s")-$flutschutz1))


flutschutz2=60
letzteNachricht2=$(($(date +"%s")-$flutschutz2))


flutschutz3=60
letzteNachricht3=$(($(date +"%s")-$flutschutz3))


flutschutz4=60
letzteNachricht4=$(($(date +"%s")-$flutschutz4))


######################## ÜBERWACHTE SERVICE ###########################


journalctl -u homebridge* -f --since "now"  | \


########################## SUCHBEGRIFFE ###############################


suchbegriff1="homebridge.*FAILURE"
nachricht1="ACHTUNG: "

suchbegriff2="communication"
nachricht2="HINWEIS: "
	
suchbegriff3="error"
nachricht3="HINWEIS: "

suchbegriff4="UUID"
nachricht4="HINWEIS: "


########################## NACHRICHTEN ###############################


while read -r zeile; do


jetzt=$(date +"%s")


if grep --quiet "$suchbegriff1" <<< "$zeile"  && [ $((letzteNachricht1+$flutschutz1)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht1$zeile
    letzteNachricht1=$(date +"%s ")
fi


if grep --quiet "$suchbegriff2" <<< "$zeile"  && [ $((letzteNachricht2+$flutschutz1)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht2$zeile
    letzteNachricht2=$(date +"%s ")
fi


if grep --quiet "$suchbegriff3" <<< "$zeile"  && [ $((letzteNachricht1+$flutschutz3)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht3$zeile
    letzteNachricht3=$(date +"%s ")
fi


if grep --quiet "$suchbegriff4" <<< "$zeile"  && [ $((letzteNachricht1+$flutschutz4)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht4$zeile
    letzteNachricht4=$(date +"%s ")
fi


################## VERSAND ÜBER NTFY AN TELEGRAM #####################


if [ -n "$nachricht" ]; then
sudo -u pi ntfy -b telegram send "$nachricht"
nachricht=""
fi    
		
done

@scientific ihr macht mich fertig :lol:
Danke :THX:
Ich probier es, mal schauen ob ich es hinbekomme. Ein zwei Sachen sind mir noch nicht klar aber vielleicht ergibt sich das ja beim ausprobieren. Melde mich später dazu wieder :wink:
Zuletzt geändert von Nastra am 07.03.2018 15:48:13, insgesamt 1-mal geändert.

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 07.03.2018 15:32:11

Der Sinn von "instantiierenden Units" (also jenen mit dem @ im Namen) bei systemd ist, dass man eine einzige Unit für mehrere gleichartige Dienste hat, denen man durch den Teil im Aufruf zwischen @ und .service einen "Übergabeparameter" übergibt, den man dann in der Unit weiterverwenden kann.

Also das File für die Unit heißt homeserver@.service und wird mit homeserver@bla.service oder homeserver@blubb.service aufgerufen.

lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Nastra
Beiträge: 94
Registriert: 13.02.2018 05:12:27

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von Nastra » 07.03.2018 15:40:08

@scientific

da ich mir nicht ganz sicher bin und du gerade Online bist frage ich mal schnell :D

Speziel an dieser Stelle, passt das so

Code: Alles auswählen

EnvironmentFile=/etc/default/homebridge@reporter.service
muss ich hier jeden Instanz eintragen die ich zurzeit habe wenn ja wie sieht das aus? Und was passiert mit den jetzigen Homebridge Units, diese sind später überflüssig?
ie Config-Files müssten dann homebridge-soundtouch hombridge-bla homebridge-blubb usw. heißen
Welche Config-Files meinst du hier? Die aktuellen Units bzw. die EnvironmentFile= von den Homebridge Instanzen ?

Aktuell heißen diese ja so:

Code: Alles auswählen

EnvironmentFile=/etc/default/homebridge-soundtouch
Neu wäre dann:

Code: Alles auswählen

EnvironmentFile=/etc/default/homebridge-soundtouch@

Kann ich die Instanzen dann noch einzeln stoppen bzw. starten? Eventuell so

Code: Alles auswählen

 sudo systemctl restart homebridge-soundtouch@ 
?

Fragen über fragen :lol:


Name der Unit: homebridge@reporter.service

Code: Alles auswählen

[Unit]
Description=homebridge-%i.service 
After=syslog.target network-online.target
OnFailure=OnFailure=notification-telegram-failed@%n.service

[Service]
Type=simple
User=root
EnvironmentFile=/etc/default/homebridge@reporter.service
ExecStart=/usr/bin/homebridge $HOMEBRIDGE_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target
EnvironmentFile=/etc/default/homebridge-%i

NAB
Beiträge: 5501
Registriert: 06.03.2011 16:02:23
Lizenz eigener Beiträge: MIT Lizenz

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von NAB » 07.03.2018 16:03:37

Nastra, ich glaube, es liegt daran, dass du die zwei Zeilen unter "Überwachter Service" auseinandergerissen hast.

Versuch's mal so:

Code: Alles auswählen

########################## SUCHBEGRIFFE ###############################


suchbegriff1="homebridge.*FAILURE"
nachricht1="ACHTUNG: "

suchbegriff2="communication"
nachricht2="HINWEIS: "
	
suchbegriff3="error"
nachricht3="HINWEIS: "

suchbegriff4="UUID"
nachricht4="HINWEIS: "


######################## Überwachte Service ###########################


journalctl -u homebridge* -f --since "now"  | \
while read -r zeile; do


########################## NACHRICHTEN ###############################
Nun sind die Suchbegriffe auch über dem journalctl und der While-Schleife.

Wenn' daran nicht lag, dann muss ich noch mal genauer den Fehler suchen. Aber wenn ich das richtig sehe gab's gar keinen Fehler sondern das Script beendet sich erfolgreich. Und das sollte sich eigentlich nie beenden.
Never change a broken system. It could be worse afterwards.

"No computer system can be absolutely secure." Intel Document Number: 336983-001

Nastra
Beiträge: 94
Registriert: 13.02.2018 05:12:27

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von Nastra » 07.03.2018 16:22:55

@NAB Jetzt läuft es wie geschmiert :THX: :THX: :THX:

Hie nochmal für alle die fertige Endfassung:

Code: Alles auswählen

#!/bin/bash

######################## NACHRICHTEN BEGRENZUNG ######################


flutschutz1=60
letzteNachricht1=$(($(date +"%s")-$flutschutz1))


flutschutz2=60
letzteNachricht2=$(($(date +"%s")-$flutschutz2))


flutschutz3=60
letzteNachricht3=$(($(date +"%s")-$flutschutz3))


flutschutz4=60
letzteNachricht4=$(($(date +"%s")-$flutschutz4))


########################## SUCHBEGRIFFE ###############################


suchbegriff1="homebridge.*FAILURE"
nachricht1="ACHTUNG: "

suchbegriff2="communication"
nachricht2="HINWEIS: "
	
suchbegriff3="error"
nachricht3="HINWEIS: "

suchbegriff4="UUID"
nachricht4="HINWEIS: "


######################## ÜBERWACHTE SERVICE ###########################


journalctl -u homebridge* -f --since "now"  | \
while read -r zeile; do


########################## NACHRICHTEN ###############################

jetzt=$(date +"%s")

if grep --quiet "$suchbegriff1" <<< "$zeile"  && [ $((letzteNachricht1+$flutschutz1)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht1$zeile
    letzteNachricht1=$(date +"%s ")
fi


if grep --quiet "$suchbegriff2" <<< "$zeile"  && [ $((letzteNachricht2+$flutschutz1)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht2$zeile
    letzteNachricht2=$(date +"%s ")
fi


if grep --quiet "$suchbegriff3" <<< "$zeile"  && [ $((letzteNachricht1+$flutschutz3)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht3$zeile
    letzteNachricht3=$(date +"%s ")
fi


if grep --quiet "$suchbegriff4" <<< "$zeile"  && [ $((letzteNachricht1+$flutschutz4)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht4$zeile
    letzteNachricht4=$(date +"%s ")
fi


################## VERSAND ÜBER NTFY AN TELEGRAM #####################


if [ -n "$nachricht" ]; then
sudo -u pi ntfy -b telegram send "$nachricht"
nachricht=""
fi    
		
done

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 07.03.2018 16:31:34

Nastra hat geschrieben: ↑ zum Beitrag ↑
07.03.2018 15:40:08
@scientific

da ich mir nicht ganz sicher bin und du gerade Online bist frage ich mal schnell :D

Speziel an dieser Stelle, passt das so

Code: Alles auswählen

EnvironmentFile=/etc/default/homebridge@reporter.service
muss ich hier jeden Instanz eintragen die ich zurzeit habe wenn ja wie sieht das aus? Und was passiert mit den jetzigen Homebridge Units, diese sind später überflüssig?
Du hast nur diese eine einzige Unit, wie ich sie oben gepostet habe hombridge@.service
Alle anderen Service-Units, die 17, die du eingerichtet hast, brauchst du dann nicht mehr.
Die homebridge@.service sieht genau so aus, wie ich sie oben gepostet habe. mit dem %i und %n
Nastra hat geschrieben:
ie Config-Files müssten dann homebridge-soundtouch hombridge-bla homebridge-blubb usw. heißen
Welche Config-Files meinst du hier? Die aktuellen Units bzw. die EnvironmentFile= von den Homebridge Instanzen ?

Aktuell heißen diese ja so:

Code: Alles auswählen

EnvironmentFile=/etc/default/homebridge-soundtouch
Neu wäre dann:

Code: Alles auswählen

EnvironmentFile=/etc/default/homebridge-soundtouch@
Nein. Diese EnvironmentFiles behalten ihren namen, wie du sie jetzt hast.
in der Unit homebridge@.service steht:

Code: Alles auswählen

EnvironmentFile=/etc/default/homebridge-%i
Nastra hat geschrieben: Kann ich die Instanzen dann noch einzeln stoppen bzw. starten? Eventuell so

Code: Alles auswählen

 sudo systemctl restart homebridge-soundtouch@ 
?

Fragen über fragen :lol:
Nein. So wie ich schrieb:
Den Service für homebridge-soundtouch startest, stoppst, enablesd und disablesd du mit

Code: Alles auswählen

systemctl start homebridge@soundtouch.service
systemctl stop homebridge@soundtouch.service
systemctl enable homebridge@soundtouch.service
systemctl disable homebridge@soundtouch.service
Nastra hat geschrieben:
Name der Unit: homebridge@reporter.service

Code: Alles auswählen

[Unit]
Description=homebridge-%i.service 
After=syslog.target network-online.target
OnFailure=OnFailure=notification-telegram-failed@%n.service

[Service]
Type=simple
User=root
EnvironmentFile=/etc/default/homebridge@reporter.service
ExecStart=/usr/bin/homebridge $HOMEBRIDGE_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target
EnvironmentFile=/etc/default/homebridge-%i
Im nächsten Post wegen der Übersichtlichkeit noch einmal die genau zwei Files mit Inhalt die du anlegen musst.
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 07.03.2018 16:38:53

Im obigen Post viewtopic.php?p=1167315#p1167315 habe ich dir zwei Unit-Files angegeben. Ich poste sie gerne noch einmal:
Du legst EIN File mit dem Namen und Inhalt an:

Code: Alles auswählen

# edit /etc/systemd/system/homebridge@.service
[Unit]
Description=homebridge-%i.service 
After=syslog.target network-online.target
OnFailure=OnFailure=notification-telegram-failed@%n.service

[Service]
Type=simple
User=root
EnvironmentFile=/etc/default/homebridge-%i
ExecStart=/usr/bin/homebridge $HOMEBRIDGE_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target
Und ein zweites mit Namen und Inhalt:

Code: Alles auswählen

# edit /etc/systemd/system/notification-telegram-failed@.service
[Unit]
Description=Send failure-notification about %i to telegram

[Service]
User=DEINLOGINUSER
Environment=TSF=/tmp/%i.failed
Environment=FLOODC=60
ExecStartPre=/bin/bash -c "[ -e $TSF ] || echo $(($(date +%%s)-$FLOODC)) > $TSF"
ExecStart=/bin/bash -c "if [ $(($(cat $TSF)+$FLOODC)) -lt $(date +"%%s") ]; then echo $(date +"%%s") > $TSF; /usr/local/bin/ntfy -b telegram send \"FAILED\n$(systemctl status %i)\"; else exit 0; fi"
Das war es.
Deine Konfigurationsfiles für deine Verschiedenen homebridge-Server-Instanzen
/etc/default/homebridge-soundtouch
/etc/default/homebridge-bla
/etc/default/homebridge-blubb
/etc/default/homebridge-foo
/etc/default/homebridge-bar

lässt du so, wie sie sind.

Um den Service homebridge-bar und bla zu starten führst du

Code: Alles auswählen

systemctl start homebridge@bar.service homebridge@bla
aus.
Um sie zu stoppen zu enablen oder disablen (also ob sie beim Boot gestartet werden oder nicht) ersetzt zu lediglich start durch stop, enable oder disable.

Alle deine anderen Units aus dem Projekt stoppe bitte zuvor. Die kannst du danach löschen. Auch die Reporter-Unit benötigst du dann nicht mehr. (Auch wenn du viel Energie reingesteckt hast... Ich versteh dich....)

Ich hab am Anfang auch eine Zeit gebraucht, bis ich diese Instanzen bei systemd verstanden habe... Wenn man sie kapiert hat, sind die dann aber wirklich lässig und flexibel!

lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

NAB
Beiträge: 5501
Registriert: 06.03.2011 16:02:23
Lizenz eigener Beiträge: MIT Lizenz

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von NAB » 07.03.2018 16:39:24

Gut! Richtig geraten! :mrgreen:

Nee, nee, so ganz fertig sind wir noch nicht. Guck mal hier:
Nastra hat geschrieben: ↑ zum Beitrag ↑
07.03.2018 16:22:55

Code: Alles auswählen

########################## NACHRICHTEN ###############################

jetzt=$(date +"%s")

if grep --quiet "$suchbegriff1" <<< "$zeile"  && [ $((letzteNachricht1+$flutschutz1)) -lt $(date +"%s ") ] ; then
    nachricht=$nachricht1$zeile
    letzteNachricht1=$(date +"%s ")
fi
Da brechnen wir einmal die aktuelle Uhrzeit in Sekunden und speichern sie dann in "jetzt".

Danach verwendest du "jetzt" aber gar nicht mehr. Also entweder schmeißt du die eine Zeile wieder raus, oder du benutzt "jetzt" dann auch, statt die aktuelle Uhrzeit noch mal zu berechnen:

Code: Alles auswählen

jetzt=$(date +"%s")

if grep --quiet "$suchbegriff1" <<< "$zeile "  && [ $((letzteNachricht1+$flutschutz1)) -lt $jetzt ] ; then
    nachricht=$nachricht1$zeile
    letzteNachricht1=$jetzt
fi
Ich find's so etwas lesbarer, aber das ist Geschmackssache.
Never change a broken system. It could be worse afterwards.

"No computer system can be absolutely secure." Intel Document Number: 336983-001

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: Gelöst! Shell Skript für systemd Überwachung

Beitrag von scientific » 07.03.2018 16:41:32

Ich hab das übrigens hier im Test laufen.
Statt Homebridge habe ich in der Unit /bin/true bzw. /bin/false. Damit kann ich dann simulieren, ob eine Unit erfolgreich läuft oder fehlschlägt.

Und ich krieg im Intervall FLOODC genau nur eine Nachricht auf Telegram, obwohl der Service alle 10 Sekunden restartet wird und fehlschläg (bei /bin/false als ExecStart)

lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Antworten