Python Skript als Systemctl Service: Was beachten?
Hallo, ich habe ein paar grundlegende Fragen darüber wie genau die Systemctl Services unter Linux (Ubuntu Server ohne GUI) funktionieren.
Hintergrund: Ich habe ein Pyhton Skript, welches innerhalb einer virtuellen Python Umgebung fehlerfrei funktioniert und das macht was es soll (sich als Client auf einem MQTT Server anmelden und Daten in einen SQL Server schreiben). Das Skript soll beim Hochfahren des entsprechenden PCs immer automaisch im Hintegrund ausgeführt werden, dafür möchte ich das ganze als Systemctl Service benutzen. Wenn ich das Skript aber als Service anlege funktioniert es nicht mehr (Daten werden nicht gespeichert) und ich habe nicht wirklich Ideen wie ich mein Problem debuggen soll, da auch der Log vom Service nicht auffällig ist. Dort steht immer nur Service Start Successfull beim Hochfahren und Service Stop beim Runterfahren, aber keine Fehlermeldungen oder der gleichen.
2 Ich habe letztendlich 2 Fragen zum generellen Verständnis, die mich hoffentlich meinem Fehler ein Stückchen näher bringen würden:
- Wo müssen verwendete Python Module installiert sein? Bzw. wie kann man den Ort, an dem Systemctl nach den Modulen schaut angezeigt und verändert werden?
- Innerhalb des Skripts nutze ich die Client.loopforever() Funktion aus dem paho-mqtt Modul, d.h. wird das Skript einmal gestartet, läuft es ohne jemals zu enden. Ist diese Charakteristik problematisch innerhalb des Service Kontextes? Ruft der Service das Skript periodisch auf und könnte ich mir somit einen solchen Dauerloop sparen? Und wenn das so ist, kann man die Periode der Skriptaufrufe anpassen?
Wie wäre es mit einem Cronjob?
Habe tatsächlich erst versucht das ganze als Cronjob umzusetzen.. das hat nicht geklappt, deswegen jetzt der Ansatz mit dem Service, der zumindest läuft (nur nicht so wie er soll)
2 Antworten
Systemctl sucht nach keinen Pythonmodulen, das macht python ganz alleine.
Und nein, Services sind nach Definition 'long running processes', die sich üblicherweise auch nicht von selbst beenden (es sei denn, sie werden aufgefordert).
Was ggf. ein Problem sein könnte ist die Environment, in der Dein Skript gestartet wird - Dein Script selbst sollte wo Pfade nötig sind immer absolute Pfade nutzen und natürlich auch die Option haben Debugausgaben zu generieren, um nach dem Problem zu suchen.
Logging ist natürlich eien Option, Du könntest aber auch einfach ein Print and stderr machen, das sollte systemd dann als Teil seines Logs wegschreiben.
(Ansich sollte sowohl stdout als auch stderr im systemd journal landen, so zumindest bei den meisten Distris)
Für den Fall, daß Du mehr damit zu tun haben wirst, solltest Du Dir Pythons Loggign anschauen, das schreibt ohne Config an stderr, kann aber auch in Dateien loggen.
----
Wichtig wäre vor allem, daß Du die Setupphase protokollierst und schaust ob die so abläuft wie Du denkst (stimmen Parameter etc. oder ändern sich im Kontext des Service - denn dann kannst Du genauer suchen, wo das Problem sein könnte.)
So wie ich es beim Überfliegen verstanden habe, ist loop_forver im Endeffekt die Eventloop, die die Queues verarbeitet - keine Ahnung, ob Du da irgendwie Logging vom mqtt bekommen kannst, aber die Callbacks sollten vermutlich auch einige Ausgaben machen.
Klassisch würde ich die an einen Parameter knüpfen, sodaß sie optional aktiviert werden kann (scriptname -v und scriptname -debug o.ä.)
Es geht hier nicht vielmehr um die Programme oder Tools sondern du musst auch die Rechte zu dem Script anpassen. In der virtuellen Umgebung hast du einen anderen Benutzer als in der Realen Umgebung. Die Rechte Vererbung basiert nur drauf wenn man Benutzern X das Berchtigt was das Script XYZ braucht. Ebenso wenn du das Script verwenden willst das Regelmäßig Ausgefühert werden soll solltest du Cron oder CRON Tab verwenden um das Script auszuführen. Dazu die Berechtigungen Konfigurieren und danach sollte es Funktionieren. Die fehlenden Tools kannst du nach und nach bei fehlermeldungen Nachinstallieren sofern sie fehlen sollten. Die passenden Abhängigkeiten gleich mit Installieren ,dann ist man auf der Sicheren Seite.
Danke erst mal für die Antwort. In meinem Skript werden keine Dateipfade benutzt.
Wie genau könnte ich Debugausgaben umsetzen innerhalb dieses Kontextes Service? Einfach Programmausgaben in eine .txt file schreiben?