Autor Thema: FHEM über systemd mit Watchdog und sd_notify  (Gelesen 1848 mal)

Offline a-p-s

  • New Member
  • *
  • Beiträge: 17
FHEM über systemd mit Watchdog und sd_notify
« am: 03 März 2018, 23:05:27 »
Hallo zusammen,

aufbauend auf den Diskussionen hier zum Thema systemd hatte ich ein paar Experimente gemacht, um meine FHEM-Installationen etwas stabiler zu machen, ohne die Komplexität hochzuschrauben. Dafür habe ich die systemd-Bordmittel (Watchdog) genutzt.

Hier die resultierende Service Unit:

[Unit]
Description=FHEM Home Automation
Requires=network.target
After=dhcpcd.service

[Service]
Type=notify
NotifyAccess=all
User=fhem
Group=dialout
WorkingDirectory=/opt/fhem
ExecStart=/usr/bin/perl fhem.pl fhem.cfg
TimeoutStartSec=240
TimeoutStopSec=120
ExecStop=/usr/bin/pkill -U fhem perl
Restart=always
RestartSec=10
WatchdogSec=180
PIDFile=/opt/fhem/log/fhem.pid
 
[Install]
WantedBy=multi-user.target

Um den Watchdog zu nutzen, muss man aus FHEM regelmäßige Nachrichten über ein UNIX-Socket schicken (sd_notify). Da die Bibliotheken, die ich gefunden habe, ultra-heavy sind für den simplen Task, ist das hier schnell zusammengeschrieben:

attr global nofork 1

defmod systemd_ready notify global:INITIALIZED { \
use Socket;;;;\
my $name = $ENV{NOTIFY_SOCKET};;;;\
my $sock_addr = sockaddr_un($name);;;;\
socket(my $server, PF_UNIX,SOCK_DGRAM,0);;;;\
connect($server, $sock_addr);;;;\
print $server "READY=1\n";;;;\
close($server);;;; }

defmod systemd_shutdown notify global:SHUTDOWN {\
use Socket;;;;\
my $name = $ENV{NOTIFY_SOCKET};;;;\
my $sock_addr = sockaddr_un($name);;;;\
socket(my $server, PF_UNIX,SOCK_DGRAM,0);;;;\
connect($server, $sock_addr);;;;\
print $server "STOPPING=1\n";;;;\
close($server);;;; }

defmod systemd_watchdog at +*00:01 { \
use Socket;;;;\
my $name = $ENV{NOTIFY_SOCKET};;;;\
my $sock_addr = sockaddr_un($name);;;;\
socket(my $server, PF_UNIX,SOCK_DGRAM,0);;;;\
connect($server, $sock_addr);;;;\
print $server "WATCHDOG=1\n";;;;\
close($server);;;; }

Das funktioniert bei mir seit einer Weile ganz gut. Mit den Timeouts muss man ein bisschen spielen. Eine meiner Installationen ist da (zeitweise) etwas träge, so dass ich die Timeouts hochgesetzt habe.

Momentan ist das noch ein Hack - da kann man ein Modul draus bauen.

Vielleicht kann trotzdem jemand etwas damit anfangen.

Grüße,
a-p-s
« Letzte Änderung: 03 März 2018, 23:11:31 von a-p-s »

Offline hexenmeister

  • Developer
  • Hero Member
  • ****
  • Beiträge: 4317
    • tech_LogBuch
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #1 am: 04 März 2018, 10:39:51 »
ich baue mal kurz ein Modul daraus...
In Verwendung: HM, EnOcean, 1wire, Firmata, MySensors, ESPEasy, MQTT*, NodeRED, Alexa, Telegram,..
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy
Kaffeekasse: https://www.paypal.me/s6z

Offline hexenmeister

  • Developer
  • Hero Member
  • ****
  • Beiträge: 4317
    • tech_LogBuch
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #2 am: 04 März 2018, 17:43:14 »
So, hier wäre das. Richtig testen konnte ich noch nicht, muss zuerst mein Test-FHEM auf systemd-script umstellen.
Datei in FHEM-Verzeichnis werfen und Device anlegen.
define watchdog systemd_watchdog
EDIT: Anhang gelöscht
« Letzte Änderung: 04 März 2018, 18:58:31 von hexenmeister »
In Verwendung: HM, EnOcean, 1wire, Firmata, MySensors, ESPEasy, MQTT*, NodeRED, Alexa, Telegram,..
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy
Kaffeekasse: https://www.paypal.me/s6z

Offline hexenmeister

  • Developer
  • Hero Member
  • ****
  • Beiträge: 4317
    • tech_LogBuch
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #3 am: 04 März 2018, 18:57:59 »
Habe ein Fehler mit dem InternalTimer gefunden (lief nach dem Löschen von Modul, mit aktivierten Watchdog sollte man das Modul eh jedoch besser nicht löschen).
« Letzte Änderung: 04 März 2018, 20:41:49 von hexenmeister »
In Verwendung: HM, EnOcean, 1wire, Firmata, MySensors, ESPEasy, MQTT*, NodeRED, Alexa, Telegram,..
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy
Kaffeekasse: https://www.paypal.me/s6z

Offline hexenmeister

  • Developer
  • Hero Member
  • ****
  • Beiträge: 4317
    • tech_LogBuch
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #4 am: 04 März 2018, 19:32:13 »
Vorerst endgültige Version (nur Commandref geschrieben).
Habe zwischendurch testen können.  Benutze Type=forking mit einer PIDFile. Funktioniert bis jetzt sehr gut. Shutdown klappt (Restart=allways durch Restart=on-failure ersetzt). Nach dem kill -9 wird korrekt neu gestartet.
In Verwendung: HM, EnOcean, 1wire, Firmata, MySensors, ESPEasy, MQTT*, NodeRED, Alexa, Telegram,..
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy
Kaffeekasse: https://www.paypal.me/s6z

Offline a-p-s

  • New Member
  • *
  • Beiträge: 17
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #5 am: 04 März 2018, 20:11:12 »
Das ging ja super schnell. Danke!

Habe meine Bastellösung durch das Modul ausgetauscht (blieb also bei Type=Notify). Funktioniert bislang einwandfrei.

Grüße,
a-p-s

Offline hexenmeister

  • Developer
  • Hero Member
  • ****
  • Beiträge: 4317
    • tech_LogBuch
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #6 am: 04 März 2018, 20:39:36 »
Das ging ja super schnell. Danke!
Gerne. Deine Bastellösung ersparte mir die Suche und Einarbeitung um meine Bastellösung zu ersetzen. win-win ;)
In Verwendung: HM, EnOcean, 1wire, Firmata, MySensors, ESPEasy, MQTT*, NodeRED, Alexa, Telegram,..
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy
Kaffeekasse: https://www.paypal.me/s6z

Offline hexenmeister

  • Developer
  • Hero Member
  • ****
  • Beiträge: 4317
    • tech_LogBuch
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #7 am: 04 März 2018, 21:21:31 »
Kurzanleitung für die Verwendung:

  • Sicherstellen, dass das eigene System unter Kontrolle von Systemd läuft. Dürfte bei den meisten aktuellen Linux-Distributionen der Fall sein.
  • Datei 98_systemd_watchdog.pm in das FHEM-Modulverzeichnis kopieren. Link: https://raw.githubusercontent.com/hexenmeister/MyFHEM/master/FHEM/98_systemd_watchdog.pm
  • In FHEM Watchdog-Device erstellen: define watchdog systemd_watchdog
  • Bleibt es bei Type=forking, dann sicherstellen, dass FHEM eine PID-Datei schreibt. Ggf. global Attribute pidfilename seiten: attr global pidfilename /opt/fhem/log/fhem.pid
    Bei Type=notify muss nofork=1 gesetzt werden: attr global nofork 1
  • FHEM beenden, falls noch läuft.
  • Sicherstellen, dass FHEM mittels systemd-script gestartet wird. Ggf. noch vorhandenen init.d-Script entfernen.
  • Systemd-Script (Inhalt s.u.) erstellen: sudo nano /etc/systemd/system/fhem.service
  • Systemd-Konfiguration aktualisieren: sudo systemctl daemon-reload
  • FHEM starten: sudo systemctl start fhem.service
  • Prüfen, ob alles wie gewünscht funktioniert: FHEM wird nicht alle 3 Minuten durch den Watchdog gekillt, beim Beenden mittels kill -9 wird neu gestartet, bei shutdown (aus FHEM) jedoch nicht.


[Unit]
Description=FHEM Home Automation
Requires=network.target
#After=network.target
After=dhcpcd.service

[Service]
Type=forking
NotifyAccess=all
User=fhem
Group=dialout
WorkingDirectory=/opt/fhem
ExecStart=/usr/bin/perl fhem.pl fhem.cfg
#ExecStart=/usr/bin/perl fhem.pl configDB
TimeoutStartSec=240
TimeoutStopSec=120
#ExecStop=/usr/bin/pkill -U fhem perl
ExecStop=/usr/bin/pkill -f -U fhem "fhem.pl fhem.cfg"
# Restart options: no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, or always.
Restart=on-failure
RestartSec=3
WatchdogSec=180
PIDFile=/opt/fhem/log/fhem.pid

[Install]
WantedBy=multi-user.target

Das Modul erzeugt zwei Readings:
state: gibt an, ob die Instanz aktiv ist (ist automatish der Fall, wenn Systemd-Watchdog verfügbar ist)
next: zeigt den Zeitpunkt der nächten keep-alive-Meldung

Außerdem gibt es zusützlich zu den allgemeinen 'Internals' zwei weitere:
sleep-time: Zeitinterval zw. den keep-alive-Meldungen (wird aus dem im Watchdog definierten Interval ausgerechnet, es wird ein Vietel von der maximalen Zeit verwendet).
systemd-watchdog: zeigt an, ob Systemd-Watchdog verfügbar ist.
« Letzte Änderung: 04 März 2018, 21:49:13 von hexenmeister »
In Verwendung: HM, EnOcean, 1wire, Firmata, MySensors, ESPEasy, MQTT*, NodeRED, Alexa, Telegram,..
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy
Kaffeekasse: https://www.paypal.me/s6z

Offline hexenmeister

  • Developer
  • Hero Member
  • ****
  • Beiträge: 4317
    • tech_LogBuch
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #8 am: 14 März 2018, 22:00:39 »
Habe jetzt das Modul ein paar Tage getestet, für stabil befunden und letztendlich in contib eingecheckt.
In Verwendung: HM, EnOcean, 1wire, Firmata, MySensors, ESPEasy, MQTT*, NodeRED, Alexa, Telegram,..
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy
Kaffeekasse: https://www.paypal.me/s6z

Offline tpm88

  • Full Member
  • ***
  • Beiträge: 382
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #9 am: 15 März 2018, 22:59:05 »
Hallo Alexander,

Kurzanleitung für die Verwendung:

  • Prüfen, ob alles wie gewünscht funktioniert: FHEM wird nicht alle 3 Minuten durch den Watchdog gekillt, beim Beenden mittels kill -9 wird neu gestartet, bei shutdown (aus FHEM) jedoch nicht.


Ich habe den watchdog exakt nach obiger Kurzanleitung definiert.

Er funktioniert soweit einwandfrei - allerdings wird fhem auch bei einem shutdown (aus FHEM) neu gestartet - trotz:
Restart=on-failure
Hier ein paar relevante Zeilen aus dem fhem.log:

2018.03.15 22:40:31 0: Server shutdown
2018.03.15 22:40:31 1: Timeout for SIP_ListenStart reached, terminated process 30235
2018.03.15 22:40:31 2: Watchdog Client: Shutting down
2018.03.15 22:40:31 2: Watchdog Client: deactivated
2018.03.15 22:40:35 3: [UtilsHourCounter] Init Done with Version 1.0.1.0 - 10.12.2014 (john)
2018.03.15 22:40:36 1: PERL WARNING: "my" variable $url masks earlier declaration in same scope at ./FHEM/99_myUtils.pm line 371.
2018.03.15 22:40:36 1: Including fhem.cfg
2018.03.15 22:40:36 3: telnetPort: port 7072 opened
...
2018.03.15 22:40:53 2: Watchdog Client: initialized
2018.03.15 22:40:53 3: OWS_rpi1: Opening connection to OWServer 192.168.8.52:4304...
2018.03.15 22:40:53 3: OWS_rpi1: Successfully connected to 192.168.8.52:4304.
2018.03.15 22:40:54 1: PERL WARNING: Use of uninitialized value in split at ./FHEM/10_OWServer.pm line 395.
2018.03.15 22:40:54 0: [Freezemon] fm: Log3 is already wrapped
2018.03.15 22:40:54 0: [Freezemon] fm: status=already wrapped
2018.03.15 22:40:54 2: [Freezemon] fm ready to watch out for delays greater than 1 second(s)
2018.03.15 22:40:54 3: NTFY return:  watchdog:active
2018.03.15 22:40:54 0: Featurelevel: 5.8
2018.03.15 22:40:54 0: Server started with 201 defined entities (fhem.pl:16403/2018-03-13 perl:5.020002 os:linux user:fhem pid:30427)

Hast du eine Idee?

Gruß
Tobias
Test FHEM Server on RPi, CUL_HM
Prod FHEM Server on CubieTruck, HM-USB, JeeLink
DB Logging FHEM Server on QNAP NAS
Devices: diverse HM, IT1500, 1wire via AVR NetIO, LaCrosse

Offline hexenmeister

  • Developer
  • Hero Member
  • ****
  • Beiträge: 4317
    • tech_LogBuch
Antw:FHEM über systemd mit Watchdog und sd_notify
« Antwort #10 am: 16 März 2018, 22:25:42 »
Ich weiß nicht, was ich damals getestet habe ??? War wohl schon zu spät... Wie auch immer, jetzt tut es bei mir auch nicht - es startet immer neu. Möglicherweise liefert FHEM nie den Wert für 'efolgreich beendet' zurück. Muss ich mir mal genauer ansehen.
 >:(
In Verwendung: HM, EnOcean, 1wire, Firmata, MySensors, ESPEasy, MQTT*, NodeRED, Alexa, Telegram,..
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy
Kaffeekasse: https://www.paypal.me/s6z