[gelöst] Logging aus/mit Shellskript

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
smutbert
Beiträge: 8342
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

[gelöst] Logging aus/mit Shellskript

Beitrag von smutbert » 21.05.2018 12:24:52

Hallo liebe Leute,


beim Logging verzweifle ich gerade, ein kleines bisschen, weil immer irgendetwas nicht funktioniert.

bis jetzt verwende ich zum Loggen

Code: Alles auswählen

echo "${Nachricht}" | systemd-cat -p ${Prioritaet} -t mein_dienst
aber das tut nicht ganz das was ich gerne hätte, denn so kann systemd-journald nicht erkennen und speichern von welcher Unit die Meldung gekommen ist, weil der systemd-cat-Prozess schon längst wieder verschwunden ist, bevor es nachsehen kann von wem der Prozess gestartet worden ist (das ist das Problem soweit ich es verstanden habe).
Damit habe ich Meldungen zwar im Log, sehe sie aber nicht, wenn ich nach (m)einer Unit filtere.

Versuche ich systemd-cat mit logger zu ersetzen ist es erst einmal dasselbe – mit dem Unterschied, dass ich bei logger eine PID angeben könnte. Allerdings geht das nur wenn ich logger als root ausführe, was ich nicht will. Schließlich habe ich meine unit gerade erst von root auf einen unprivilegierten Benutzer umgestellt und ich bin mir nicht einmal sicher, dass das mein Problem lösen würde.
Außerdem komme ich gar nicht soweit, weil die Meldungen nicht im Log erscheinen, wenn ich es so versuche

Code: Alles auswählen

logger --priority ${Prioritaet} --tag mein_dienst "${Nachricht}"
(das Problem habe ich meinen Beobachtungen nach nur in der systemd-unit nicht im Terminal, habe es aber auch nicht weiter verfolgt, weil ich nicht erwarte, dass es zu einer Lösung führt)


Im arch-Forum habe ich dann noch folgenden Lösungsvorschlag gefunden

Code: Alles auswählen

LOGPIPE="$(mktemp -u)"
mkfifo "${LOGPIPE}"
systemd-cat -t mein_dienst < "${LOGPIPE}" &
exec 3>"${LOGPIPE}"

function log ()
{
    echo "<${2}> ${1}" >&3
}

function handle_term ()
{
        ### Diese Meldung funktioniert nicht 
        log "bin dabei mich zu beenden" 4
        exec 3>&-
        rm "${LOGPIPE}"
        exit
}

trap handle_term SIGTERM

### Hier folgt mein Skript mit weiteren (funktionierenden) Log-Ausgaben
log "Nachricht" 5

exec 3>&-
rm "${LOGPIPE}"
und abgesehen davon, dass es mir rein gefühlsmäßig nicht so gut gefällt funktioniert es eigentlich™.
Nur das mit dem Abfangen von SIGTERM funktioniert nicht so recht. Abgefangen wird es schon, aber scheinbar nur im Skript und nicht von bzw. für systemd-cat? Jedenfalls erhalte ich bei SIGTERM im Log

Code: Alles auswählen

May 20 22:22:57 pc mein_dienst[1102]: /usr/local/bin/mein_dienst: line 43: echo: write error: Broken pipe
(Zeile 43, wäre dann die mit der Zeile „echo ...“ in der Funktion log)

Stimmt es überhaupt, dass SIGTERM an die Kinder (systemd-cat) weitergereicht wird und das die Ursache ist?
Dann müsste ich SIGTERM auch für systemd-cat abfangen (geht das überhaupt/wie mach ich das)?
Oder bin ich sowieso komplett auf dem Holzweg und jemand hat einen komplett anderen Vorschlag wie ich zum Ziel komme (vorzugsweise ohne named pipe)?

lg smutbert
Zuletzt geändert von smutbert am 24.05.2018 16:34:04, insgesamt 1-mal geändert.

Benutzeravatar
smutbert
Beiträge: 8342
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Logging aus/mit Shellskript

Beitrag von smutbert » 22.05.2018 00:37:51

kleines Update:

Eigentlich soll das alles headless laufen, aber um bequemer testen zu können, habe ich nun die Variante mit der named pipe in einem Skript auf meinem Desktop im Terminalfenster laufen lassen und dort funktioniert alles inklusive Abfangen von SIGTERM ohne „broken pipe“.

Daraus schließe ich, dass der Fehler etwas mit der Art zu tun hat, mit der systemd die Prozesse tötet. Das ist schon einmal ein Anhaltspunkt, bin gespannt ob ich alleine weiterkomme (und natürlich auch weiterhin für Vorschläge offen).

Benutzeravatar
smutbert
Beiträge: 8342
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Logging aus/mit Shellskript

Beitrag von smutbert » 24.05.2018 16:33:52

Mit den verschiedenen Varianten zum Killen, die systemd bietet bin ich nicht so recht weitergekommen - die broken pipe bin ich zwar losgeworden, aber es sind dann andere Fehler aufgetreten, aber dafür funktioniert eine überraschend einfache Lösung, nämlich das Skript so aufrufen zu lassen

Code: Alles auswählen

/usr/bin/systemd-cat -t mein_dienst /usr/local/bin/mein_dienst
und die Meldungen im Skript einfach in der Form »<Priorität>Meldung« mit echo ohne weitere Umleitung auszugeben.

Als ich mir die Sache näher angesehen habe ist mir noch aufgefallen, dass obwohl alles funktioniert, systemd-cat gar nicht läuft und ich habe das Skript wieder ohne systemd-cat aufgerufen und auch das funktioniert.
Also dass die Meldungen im Log landen ist nicht weiter überraschend, aber dass sich auch bei der ganz normalen Ausgabe nach stdout oder stderr die Prioritäten in der Form »<Priorität>Meldung« festlegen lassen, habe ich nicht erwartet.
Einfacher geht es nicht, damit ist das Problem gelöst.

Antworten