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: 3022
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: 3022
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: 3022
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: 3022
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: 3022
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

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 17:06:10

Vielen Dank für die schnelle Rückmeldung, ich denke mit deinen Antworten von oben kann ich soweit was anfangen.
Ich stoße aber beim Aktivieren der homebridge@.service Unit auf einen Fehler:

Reload habe ich gemacht.

Code: Alles auswählen

sudo systemctl enable homebridge@.service
The unit files have no installation config (WantedBy, RequiredBy, Also, Alias
settings in the [Install] section, and DefaultInstance for template units).
This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's
   .wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
   a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
   D-Bus, udev, scripted systemctl call, ...).
4) In case of template units, the unit is meant to be enabled with some
   instance name specified.

Ich habe die Unit genau so eingefügt wie du diese vorgegeben hast mit dem Namen homebridge@.service, eine Idee wieso?

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
Die zweite Unit brauch ja nich Aktiviert werden, da diese onFailure gestartet wird?

@NAB
Ich baue es jetzt mal um, aber das war es dann oder hast du noch ein one more thing :mrgreen: :mrgreen: :mrgreen: ?
Nicht das ich noch öfter hier eine endgültige Version veröffentliche die garnicht fertig gewesen ist :?: :D

scientific
Beiträge: 3022
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 17:14:46

Hast du meine Anleitung genau genug gelesen?

Has du das File, welches /etc/systemd/system/homebridge@.service heißt angelegt, und hat es den Inhalt, wie ich ihn angegeben habe?

Wenn du den Service für soundtouch mit der Hombridge aktivieren willst, dann muss du das so machen:

Code: Alles auswählen

systemctl start homebridge@soundtouch.service
Wenn du

Code: Alles auswählen

systemctl start homebridge@.service
ausführt, fehlt das soundtouch. Der Service kann nicht starten.

Und genau. Die notification-telegram-failed@.service wird nur dann ausgeführt, wenn homebridge@soundtouch.service failed, also wenn der Homebridgeserver für soundtouch abschmiert.

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 18:08:12

@scientific @NAB

sorry, muss leider für heute aufhören da meine Tochter 7 Monate seitdem Mittag schon quängelisch drauf ist und jetzt noch fieber hat ist Sie die ganze Zeit am Schreien. Ich wollte das zwischen drinnen mal schnell ausprobieren gem. deinen Vorgaben aber mit konzentrieren ist gerade schlecht wenn man angeschrien wird. Daher habe ich bestimmt auch die ein oder andere Sache vorhin überlesen :(

Ich kümmer mich jetzt erstmal um die kleine Maus und probier es auf jeden Fall morgen nochmal :wink:

Schönen Abend euch beiden noch!

Gruß Nastra

scientific
Beiträge: 3022
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 19:25:24

Seit Mittag schon 7 Monate...

Na dann kümmere dich mal schön um deine kleine Maus. Ich versteh dich. Hab auch so einen kleinen Schatz :)

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 21:14:39

So, nachdem Nastra zufriedengestellt zu sein scheint :mrgreen:

Was diese Versuche mit Systemd angeht ... ich kann von dieser Verwendung von "OnFailure" in Verbindung mit "Restart" nur dringend abraten. Gerade wenn es darum geht, unbedarften Apple-Nutzern eine wartungsfreie Lösung anzubieten.

Das Problem an "OnFailure" ist, dass es kaputt ist (wie so vieles an Systemd).

Unter Jessie war es völlig kaputt:
https://stackoverflow.com/questions/478 ... -this?rq=1

Wenn man in die Gebrauchsanweisung guckt:
OnFailure=
A space-separated list of one or more units that are activated when this unit enters the "failed" state.
dann soll OnFailure eigentlich auf den Zustand "failed" reagieren. Der wird bei "Restart" aber nicht bei jedem "failure" erreicht, sondern erst, wenn das Neustart-Limit abgelaufen ist.

In der neuen Version der Gebrauchsanleitung formulieren sie das auch deutlicher:
OnFailure=
A space-separated list of one or more units that are activated when this unit enters the "failed" state. A service unit using Restart= enters the failed state only after the start limits are reached.
Nun haben sie es in Stretch zu reparieren versucht, aber es leider nicht gebacken gekriegt. Das Verhalten von "OnFailure" weicht immer noch von der Gebrauchsanleitung ab. Sonst würde es nicht so funktionieren wie es das hier im Thread tut.

Das zweite Problem ist, dass Poettering den Bug-Report nicht versteht:
https://bugs.freedesktop.org/show_bug.cgi?id=87799
Und der Berichterstatter mittlerweile aufgegeben hat:
https://github.com/systemd/systemd/issues/305

Aus meiner Sicht ist das zukünftige Verhalten von "OnFailure" unberechenbar. Wenn sich noch jemand findet, der Poettering die Sache in kindgerechter Sprache erklärt, kann es gut sein, dass er das Verhalten von OnFailure an die Gebrauchsanleitung anpasst, oder auch umgekehrt. Eventuell ist das auch schon passiert (ich find da nix im Bug-Tracker, und eine Liste von "Fixes" finde ich auch nicht).

scientific, liest und beschreibst du die Dateien unter /tmp/ eigentlich so auf gut Glück in der Hoffnung, dass niemand anders diese Dateinamen verwendet? Oder reserviert Systemd dir die irgendwie?
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: 3022
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 » 08.03.2018 00:49:53

Wenn ich dich richtig verstehe, dann sollte das Verhalten von OnFailure so sein, dass der Service z.B. 5 Mal erfolglos gestartet wird, dann fällt die Unit in den "Failed"-Zustand, und dann wird "OnFailure" ausgelöst. So würd ich die Manpage verstehen.

Ich hab mir jetzt einmal diese Test-Unit gebaut:

Bau dir einmal diese Test-Unit:

Code: Alles auswählen

/etc/systemd/system: # cat test@.service 
[Unit]
Description=Testservice notification
OnFailure=notification-telegram-failed@%n.service

[Service]
Type=simple
Restart=on-failure
#RestartSec=10
ExecStart=/bin/%i
SyslogIdentifier=test@%i.service
StartLimitBurst=5
StartLimitInterval=10
Und die telegram-notification-Unit so vereinfacht:

Code: Alles auswählen

# cat notification-telegram@.service 
[Unit]
Description=Send failure-notification about %i to telegram

[Service]
User=jakob
ExecStart=/bin/bash -c "/usr/local/bin/ntfy -b telegram send \"FAILED\n$(systemctl status %i)\""
Wenn ich mit

Code: Alles auswählen

systemctl start test@false
die testunit aufrufe, sodass ExecStart=/bin/false ausgeführt wird und das journal beobachte, so wird die Unit 5 Mal neu gestartet und fällt dann in den Failed-Zustand:

Mär 08 00:31:53 aldebaran systemd[1]: Started Testservice notification.
Mär 08 00:31:53 aldebaran systemd[1]: test@false.service: Main process exited, code=exited, status=1/FAILURE
Mär 08 00:31:53 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:31:53 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Service hold-off time over, scheduling restart.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Scheduled restart job, restart counter is at 1.
Mär 08 00:31:54 aldebaran systemd[1]: Stopped Testservice notification.
Mär 08 00:31:54 aldebaran systemd[1]: Started Testservice notification.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Main process exited, code=exited, status=1/FAILURE
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Service hold-off time over, scheduling restart.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Scheduled restart job, restart counter is at 2.
Mär 08 00:31:54 aldebaran systemd[1]: Stopped Testservice notification.
Mär 08 00:31:54 aldebaran systemd[1]: Started Testservice notification.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Main process exited, code=exited, status=1/FAILURE
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Service hold-off time over, scheduling restart.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Scheduled restart job, restart counter is at 3.
Mär 08 00:31:54 aldebaran systemd[1]: Stopped Testservice notification.
Mär 08 00:31:54 aldebaran systemd[1]: Started Testservice notification.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Main process exited, code=exited, status=1/FAILURE
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Service hold-off time over, scheduling restart.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Scheduled restart job, restart counter is at 4.
Mär 08 00:31:54 aldebaran systemd[1]: Stopped Testservice notification.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Start request repeated too quickly.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:31:54 aldebaran systemd[1]: Failed to start Testservice notification.
Mär 08 00:31:54 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.


Ich bekomme 3 Notifications. Wahrscheinlich, weil die notification-Unit zu oft hintereinander aufgerufen wird, und der sendeprozess noch nicht abgeschlssen ist.

Daher hab ich RestartSec=2 einkommentiert und noch einmal ausgeführt:


Mär 08 00:44:14 aldebaran systemd[1]: Started Testservice notification.
Mär 08 00:44:14 aldebaran systemd[1]: test@false.service: Main process exited, code=exited, status=1/FAILURE
Mär 08 00:44:14 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:44:14 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.
Mär 08 00:44:16 aldebaran systemd[1]: test@false.service: Service hold-off time over, scheduling restart.
Mär 08 00:44:16 aldebaran systemd[1]: test@false.service: Scheduled restart job, restart counter is at 1.
Mär 08 00:44:16 aldebaran systemd[1]: Stopped Testservice notification.
Mär 08 00:44:16 aldebaran systemd[1]: Started Testservice notification.
Mär 08 00:44:16 aldebaran systemd[1]: test@false.service: Main process exited, code=exited, status=1/FAILURE
Mär 08 00:44:16 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:44:16 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.
Mär 08 00:44:19 aldebaran systemd[1]: test@false.service: Service hold-off time over, scheduling restart.
Mär 08 00:44:19 aldebaran systemd[1]: test@false.service: Scheduled restart job, restart counter is at 2.
Mär 08 00:44:19 aldebaran systemd[1]: Stopped Testservice notification.
Mär 08 00:44:19 aldebaran systemd[1]: Started Testservice notification.
Mär 08 00:44:19 aldebaran systemd[1]: test@false.service: Main process exited, code=exited, status=1/FAILURE
Mär 08 00:44:19 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:44:19 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.
Mär 08 00:44:21 aldebaran systemd[1]: test@false.service: Service hold-off time over, scheduling restart.
Mär 08 00:44:21 aldebaran systemd[1]: test@false.service: Scheduled restart job, restart counter is at 3.
Mär 08 00:44:21 aldebaran systemd[1]: Stopped Testservice notification.
Mär 08 00:44:21 aldebaran systemd[1]: Started Testservice notification.
Mär 08 00:44:21 aldebaran systemd[1]: test@false.service: Main process exited, code=exited, status=1/FAILURE
Mär 08 00:44:21 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:44:21 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.
Mär 08 00:44:23 aldebaran systemd[1]: test@false.service: Service hold-off time over, scheduling restart.
Mär 08 00:44:23 aldebaran systemd[1]: test@false.service: Scheduled restart job, restart counter is at 4.
Mär 08 00:44:23 aldebaran systemd[1]: Stopped Testservice notification.
Mär 08 00:44:23 aldebaran systemd[1]: test@false.service: Start request repeated too quickly.
Mär 08 00:44:23 aldebaran systemd[1]: test@false.service: Failed with result 'exit-code'.
Mär 08 00:44:23 aldebaran systemd[1]: Failed to start Testservice notification.
Mär 08 00:44:23 aldebaran systemd[1]: test@false.service: Triggering OnFailure= dependencies.



Wie man sieht, sind immer 2 Sekunden Pause zwischen den einzelnen Aufrufen, bis dann in der vorletzten Zeile der Failed-Status eintritt, nachdem StartLimitBurst erreicht wird.

Das Verhalten entspricht in der Tat nicht der Manpage von systemd.

Und weil es mir nicht liegt, irgendwie auf irgendwen hinzupecken, nur weil es andere auch tun, hab ich genau dieses Verhalten auf der systemd-Mailingliste geschildert. Bin gespannt, was da zurück kommt.
Bisher hab ich auf dieser Liste immer nur positive Erfahrungen gemacht. Und ja, Pöttering diskutiert dort mit. Und man kann auch als keiner Debianforist mit The Master Himself diskutieren... das machen nicht nur irgendwelche Entwickler oder Journalisten...

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: 3022
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 » 08.03.2018 00:57:13

Was die Files in /tmp anbelangt: Ja, ich hoffe, das sonst kein Prozess diese aufgreift.
Das Problem ist, wenn ich sie in ein RuntimeDirectory lege, welches ich mit dem Aufruf der Unit erzeugen lasse, wird dieses Directory mit dem Stopp der Unit wieder entfernt. Ich kann doch nicht Aufrufübergreifend persistente Files ablegen.

Mit tmpfiles hab ich mich noch zu wenig beschäftigt, als dass ich die hier verwenden könnte.

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 » 08.03.2018 05:02:56

scientific hat geschrieben: ↑ zum Beitrag ↑
08.03.2018 00:49:53
Bau dir einmal diese Test-Unit:
Ich hab damit schon im Sommer (?) rumgespielt, als ich auf Stretch und Systemd umgestiegen bin. Ich dachte mir nur "Oh, das ist aber komisch, vielleicht fixen sie das ja noch". Ich hab noch diese alte Spiel-Unit auf der Platte:

Code: Alles auswählen

[Unit]
Description=Lang laufender Dienst
StartLimitBurst=3
StartLimitIntervalSec=500
OnFailure=blabla.service

[Service]
#Type=oneshot
Type=simple
RemainAfterExit=no

ExecStart=/bin/sh -c "/bin/sleep 30; exit 1"
#ExecStart=/bin/sh -c "/bin/sleep 30"

Restart=on-failure
#Restart=on-success
RestartSec=10

[Install]
WantedBy=multi-user.target
Grad noch mal gestartet, zeigt immer noch das vom Manual abweichende Verhalten: OnFailure= wird vier mal ausgelöst, drei mal durch exit 1, ohne dass die Unit den "failed state" erreicht und das vierte mal nach/durch den "failed state". MMn reicht das so als "minimal example".

"systemctl status" zeigt dementsprechend in den drei mal 10 Sekunden RestartSec auch jeweils:
Active: activating (auto-restart) (Result: exit-code)
und nach dem vierten Versuch:
Active: failed (Result: exit-code)

Mir wird auch grad klar, was er im oben verlinkten Bugreport meinte. OnFailure reagiert nämlich auf zwei verschiedene Dinge. Einmal exit != 0 und einmal "Start request repeated too quickly". Diese unterschiedlichen Ereignisse möchte er wohl auseinanderhalten können.

Interessant auch dieses widersprüchliche Verhalten:
Das letzte Wort der Unit, so wie sie oben steht, ist:
Failed with result 'exit-code'.
Welcher exit-code? Die Unit wird gar nicht mehr gestartet, es gibt keinen exit-code.
Wenn ich umstelle auf:
Restart=on-success
und das exit 1 rausnehme, ist das letzte Wort der Unit:
Failed with result 'start-limit-hit'.
Joa, das macht mehr Sinn.
Der Status der Unit ist danach auch ein anderer (trotz gleicher "Beendigungs-Ursache"):
Active: failed (Result: start-limit-hit)
Uh?

Den Effekt kriegste völlig unabhängig von "OnFailure". Ich vermute, der ganze Code von Restart ist etwas "sloppy" und das Verhalten von OnFailure ist hier nur ein Symptom.

Wenn man OnFailure dann so benutzen möchte, wie es im Manual steht, nämlich als Reaktion auf die zugesichterte Eigenschaft "Der aufrufende Dienst ist garantiert mausetot", dann ist es kaputt, weil diese Eigenschaft eben nicht immer erfüllt ist. Manchmal ja, manchmal nein ...

Demenstsprechend wäre das, was hier im Thread vorgeschlagen wird, dann ein kreativer Bug Exploit von Systemd. Das finde ich zwar ausgesprochen lustig, aber ich glaube nicht, dass das etwas ist, was man Nastra empfehlen sollte.
scientific hat geschrieben: ↑ zum Beitrag ↑
08.03.2018 00:49:53
hab ich genau dieses Verhalten auf der systemd-Mailingliste geschildert.
:THX:
scientific hat geschrieben: ↑ zum Beitrag ↑
08.03.2018 00:57:13
Was die Files in /tmp anbelangt: Ja, ich hoffe, das sonst kein Prozess diese aufgreift.
Spricht was gegen /home/DEINLOGINUSER ?
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 » 08.03.2018 09:08:55

Guten Morgen,

uiii hier sind ja noch einige neue Erkenntnisse bezüglich einer systemd Lösung zu tage gekommen.

Da ich wie NAB schon gesagt hat eine zuverlässige Lösung suche, denke ich das ich von der systemd Lösung zur Überwachung der Instanzen vorerst Abstand nehme, da es scheinbar noch ziemlich verbugt ist.
Schade eigentlich da es auch ein ziemlich interessant Lösungsansatz ist wie @scientific ihn vorgeschlagen hat

@NAB habe das jetzt überall eingefügt und es läuft super :THX:


Gruß Nastra
Zuletzt geändert von Nastra am 08.03.2018 22:07:44, insgesamt 2-mal geändert.

scientific
Beiträge: 3022
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 » 08.03.2018 09:26:55

 @NAB hast du, außer zu spielen und dich damit über Pöttering zu ärgern, auch einen Bugreport verfasst?

Ich hab letzte Nacht an die Liste geschrieben und heute früh schon eine Antwort von Andrei Borzenkov bekommen:
This is apparently wrong, because service briefly goes via "failed"
state every time it fails. It is true that if Restart= is set it
immediately follows by "activating" state again, but OnFailure actions
are still taken.

So from end-user perspective unit indeed remains "failed" only when
limits are reached, but internally it does transition via "failed" state
every time.


>
> But in this testcase, the unit listet in OnFailure is called every time,
> the unit failes, restarts again fails again, and after 5 times
> (=StartLimitBurst), the unit falls into failed state... Here should be
> the only one time, where "OnFailure=" is hit...
>
> My systemd-Version is 237-3 from debian.
>
> Should i file a Bug in bugs.freedesktop.org?
>


You should create issue on github, this this where primary bug tracker
is today:

https://github.com/systemd/systemd/
Siehe da, er erkennt das Verhalten sofort als Bug an.

Ich werde den Bugreport verfassen und lasse euch wissen, ob und wie es gelöst wurde.

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: 3022
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 » 08.03.2018 10:05:01

Mein Bugreport im Bugtracker auf Github für systemd

https://github.com/systemd/systemd/issues/8398
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 » 17.03.2018 03:22:05

Sorry für mein Schweigen hier, mich hatte die Grippe gründlich zerlegt. Eigentlich wollte ich noch was zu Systemd sagen. Die Lösung, ein Script über eine Service Unit zu starten ist zwar recht eingeschränkt, da man damit nur auf die Ereignisse "Dienst wird gestartet" und "Dienst wird beendet" reagieren kann, aber dafür kann man das wenigstens zielgenau tun und muss nicht "auf gut Glück" im Journal herumstochern.

Und eigentlich war mein toller Plan, dafür eine zusätzliche Überwachungs-Unit zu nehmen, die sich mit BindsTo= an den zu überwachenden Service hängt und bei jedem Start und Ende dieses Service eine Reaktion auslöst. Das hätte den Vorteil gehabt, dass man die vorhandenen Units nicht verändern muss. Leider scheitert die Idee am "Restart=". Für Type=oneshot verbietet mir Systemd die Benutzung von "Restart=" (gut, das macht Sinn) und für Type=simple wird "Restart=" einfach ignoriert (was am ExecStart=/bin/true liegen könnte). Ob das nun gewolltes Verhalten oder auch ein Bug ist, vermag ich der Gebrauchsanleitung nicht so recht zu entnehmen.

Somit sehe ich dann auch keine andere Möglichkeit, als hässlicher Weise in jede Unit, die man überwachen möchte, ein entsprechendes Script einzutragen:

Code: Alles auswählen

ExecStopPost=/bin/sh -c "/usr/bin/sudo -E -u pi /usr/local/bin/benachrichtigung.sh %n 1200"
Erläuterung: Das Script benachrichtigung.sh wird per sudo unter dem Benutzer "pi" gestartet, wann immer sich der ExecStart= Prozess dieser Unit beendet, egal aus welchem Grund. Das Script bekommt zwei Argumente: %n enthält den Namen der Service-Datei, die sich gerade beendet und die "1200" sind das von Nastra gewünschte Nachrichtenlimit in Sekunden. Das individuelle Nachrichtenlimit muss somit in jede zu überwachende Unit eingetragen werden.

Das Script benachrichtigung.sh sieht dann so aus:

Code: Alles auswählen

#!/bin/bash
# Erwartet, von Systemd aufgerufen zu werden, mit den
# Umgebungsvariablen $SERVICE_RESULT $EXIT_CODE und $EXIT_STATUS.
# siehe man systemd.exec
# Erwartet als ersten Parameter den Namen der aufrufenden .service Datei (%n).
# Erwartet als zweiten Parameter in Sekunden den minimalen Abstand zwischen zwei Nachrichten dieses Service.
# Erzeugt $arbeitsverzeichnis und speichert dort Zeitstempel. Räumt $arbeitsverzeichnis NICHT auf.

benutzer=pi
arbeitsverzeichnis=/home/$benutzer/dienstueberwachung

dienst=$1
abstand=$2

zeitstempel=$arbeitsverzeichnis/$dienst

# Debug:
# echo $(date) $dienst $abstand $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS >> $arbeitsverzeichnis/debug.txt

if [ "$(whoami)" != "$benutzer" ]; then
   # echo "Falscher Benutzer $(whoami)" > $arbeitsverzeichnis/debug.txt
   exit 1
fi

mkdir -p $arbeitsverzeichnis
      
if [ -f "$zeitstempel" ]; then
    if [ $(($(cat "$zeitstempel") + $abstand)) -gt $(date +"%s") ]; then
      # echo "$(date) Zeitstempel zu neu" >> $arbeitsverzeichnis/debug.txt
      exit 0 # Keine Nachricht wenn Zeitstempel zu neu
   fi
fi

if [ "$SERVICE_RESULT" == "success" ]; then
   exit 0 # Keine Nachricht bei erfolgreicher Beendigung
fi

# Zeitstempel existiert nicht oder ist zu alt. Neuer Zeitstempel wird erzeugt:
echo $(date +"%s") > $zeitstempel

# Debug
# echo /usr/local/bin/ntfy -b telegram send "Dienst $dienst ausgefallen mit $SERVICE_RESULT $EXIT_STATUS" >> $arbeitsverzeichnis/debug.txt

/usr/local/bin/ntfy -b telegram send "Dienst $dienst ausgefallen mit $SERVICE_RESULT $EXIT_STATUS"
Das Script ist möglichst einfach gehalten, mit dem Gedanken, dass man unerwünschte Teile leicht wieder rausreißen kann oder ihm weitere Tricks beibringen kann. Ich habe es grob mit exit 0, exit 1 und systemctl stop durchgetestet und bei mir funktioniert es erwartungsgemäß. Aber da ich weiterhin keine "homebridge" Dienste betreibe und kein ntfy installiert habe, mag ich für Nastras Verwendungszwecke keine Garantie übernehmen.

Ebenso könnte man mit ExecStartPre= noch auf das Ereignis "Dienst wird gestartet" reagieren, aber ich weiß nicht, ob das in diesem Kontext überhaupt sinnvoll ist.
scientific hat geschrieben: ↑ zum Beitrag ↑
08.03.2018 09:26:55
@NAB hast du, außer zu spielen und dich damit über Pöttering zu ärgern, auch einen Bugreport verfasst?
Nein, warum sollte ich? Ich halte den vorhandenen Bugreport für ausreichend. Ich sehe auch nicht dass (d)ein zweiter zu einer beschleunigten Bearbeitung führt.

Nebenbei, ich "ärgere" mich nicht über Poettering, ich amüsiere mich eher über ihn.
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: 3022
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 » 17.03.2018 22:24:08

Nun, wenn ein Bug zu ist, muss man einen neuen eröffnen, solange das Problem nicht gelöst ist.

Und wenn es genügend Leute bestätigen und dessen Behebung einfordern, wird sich was ändern.

Aber Pöttering belächeln und nix tun, ist halt auch feig und faul... So funktioniert Opensource halt nicht...
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 » 18.03.2018 05:58:00

Ich glaub, mein Schwein pfeift ... warum zieht Systemd eigentlich immer die Vollspacken an?

Statt andere Leute als "feig und faul" zu beleidigen, lerne Lesen! Hier noch mal die beiden vorhandenen Bug-Reports:
https://bugs.freedesktop.org/show_bug.cgi?id=87799
https://github.com/systemd/systemd/issues/305
Versuche zu verstehen, wann die eröffnet wurden und wann sie aus welchem Grund geschlossen wurden. Wenn du dabei Hilfe brauchst, such dir welche, aber nicht in diesem Thread! Dann traut sich Nastra vielleicht doch noch mal her. Und wenn du deinen dämlichen Bug gefixt haben willst, dann schreibe einen Patch. Sonst interessiert sich einfach niemand dafür. So funktioniert Open Source.
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 » 18.03.2018 06:55:36

Guten Morgen zusammen,

@NAB ich hoffe es geht dir wieder besser, hatte schon vermutetet das du vielleicht im Urlaub bist :D
Habe deinen Beitrag gestern schon gelesen und natürlich auch kurz getestet, leider hat es nicht auf anhieb geklappt. Bin gestern leider auch nicht mehr dazu gekommen mich mit einem Feedback zu melden.

Erstmal vielen Dank für deine erneuten Mühen :THX:

Hier kurz erklärt wie ich vorgegangen bin:

Ich habe eine Unit von meinen Homebridge Instanzen gestoppt, geöffnet und die Zeile:

Code: Alles auswählen

ExecStopPost=/bin/sh -c "/usr/bin/sudo -E -u pi /usr/local/bin/benachrichtigung.sh %n 1200"
im Bereich [Service] eingetragen und einen deamon-reload durchgeführt. Die 1200 habe ich zum testen auf 30 gestellt.

Anschließend habe ich unter usr/local/bin das Skript mit dem Namen benachrichtigung.sh erstellt und die Rechte auf 755 gesetzt. Danach die config.json der Homebridge Instanz manipuliert das er mit status=1/FAILURE beendet.

Leider wurde ich nicht benachrichtig es scheint so als ob er noch ein Problem hat gem. Meldung unten?
Zusätzliche Info, das Arbeitsverzeichnis wurde angelegt und der ntfy Befehl im Skript funktioniert auch.

Code: Alles auswählen

Mär 17 07:21:24 HomeKitServer homebridge[954]: [2018-3-17 07:21:24] ---
Mär 17 07:21:24 HomeKitServer homebridge[954]: [2018-3-17 07:21:24] Loaded plugin: homebridge-mi-fan
Mär 17 07:21:24 HomeKitServer homebridge[954]: undefined:1
Mär 17 07:21:24 HomeKitServer homebridge[954]: x{
Mär 17 07:21:24 HomeKitServer homebridge[954]: ^
Mär 17 07:21:24 HomeKitServer homebridge[954]: SyntaxError: Unexpected token x in JSON at position 0
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at JSON.parse (<anonymous>)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at isConfig (/usr/lib/node_modules/homebridge-mi-fan/index.js:22:23)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Plugin.module.exports [as initializer] (/usr/lib/node_modules/homebridge-mi-fan/index.js:8:9)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Server.<anonymous> (/usr/lib/node_modules/homebridge/lib/server.js:160:14)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Array.forEach (<anonymous>)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Server._loadPlugins (/usr/lib/node_modules/homebridge/lib/server.js:138:22)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at new Server (/usr/lib/node_modules/homebridge/lib/server.js:56:24)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at module.exports (/usr/lib/node_modules/homebridge/lib/cli.js:26:16)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Object.<anonymous> (/usr/lib/node_modules/homebridge/bin/homebridge:17:22)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Module._compile (module.js:649:30)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Object.Module._extensions..js (module.js:660:10)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Module.load (module.js:561:32)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at tryModuleLoad (module.js:501:12)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Function.Module._load (module.js:493:3)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at Function.Module.runMain (module.js:690:10)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at startup (bootstrap_node.js:194:16)
Mär 17 07:21:24 HomeKitServer homebridge[954]:     at bootstrap_node.js:666:3
Mär 17 07:21:24 HomeKitServer systemd[1]: homebridge-test.service: Main process exited, code=exited, status=1/FAILURE
Mär 17 07:21:24 HomeKitServer sudo[1126]:     root : TTY=unknown ; PWD=/ ; USER=pi ; COMMAND=/usr/local/bin/benachrichtigung.sh homebridge-test.service 30
Mär 17 07:21:24 HomeKitServer sudo[1126]: pam_unix(sudo:session): session opened for user pi by (uid=0)
Mär 17 07:21:25 HomeKitServer sh[1125]: Traceback (most recent call last):
Mär 17 07:21:25 HomeKitServer sh[1125]:   File "/usr/local/bin/ntfy", line 7, in <module>
Mär 17 07:21:25 HomeKitServer sh[1125]:     from ntfy.cli import main
Mär 17 07:21:25 HomeKitServer sh[1125]:   File "/usr/local/lib/python2.7/dist-packages/ntfy/cli.py", line 12, in <module>
Mär 17 07:21:25 HomeKitServer sh[1125]:     from .data import scripts
Mär 17 07:21:25 HomeKitServer sh[1125]:   File "/usr/local/lib/python2.7/dist-packages/ntfy/data.py", line 9, in <module>
Mär 17 07:21:25 HomeKitServer sh[1125]:     makedirs(ntfy_data_dir)
Mär 17 07:21:25 HomeKitServer sh[1125]:   File "/usr/lib/python2.7/os.py", line 150, in makedirs
Mär 17 07:21:25 HomeKitServer sh[1125]:     makedirs(head, mode)
Mär 17 07:21:25 HomeKitServer sh[1125]:   File "/usr/lib/python2.7/os.py", line 150, in makedirs
Mär 17 07:21:25 HomeKitServer sh[1125]:     makedirs(head, mode)
Mär 17 07:21:25 HomeKitServer sh[1125]:   File "/usr/lib/python2.7/os.py", line 157, in makedirs
Mär 17 07:21:25 HomeKitServer sh[1125]:     mkdir(name, mode)
Mär 17 07:21:25 HomeKitServer sh[1125]: OSError: [Errno 13] Permission denied: '/root/.local'
Mär 17 07:21:25 HomeKitServer systemd[1]: homebridge-test.service: Control process exited, code=exited status=1
Mär 17 07:21:25 HomeKitServer systemd[1]: homebridge-test.service: Unit entered failed state.
Mär 17 07:21:25 HomeKitServer systemd[1]: homebridge-test.service: Failed with result 'exit-code'.
Mär 17 07:21:35 HomeKitServer systemd[1]: homebridge-test.service: Service hold-off time over, scheduling restart.
Mär 17 07:21:35 HomeKitServer systemd[1]: Stopped homebridge-test.service.
Mär 17 07:21:35 HomeKitServer systemd[1]: Started homebridge-test.service.
Gruß Nastra

Antworten