staging.inyokaproject.org

Wie Zeilen filtern bevor sie nach systemd-cat ins journal gehen?

Status: Ungelöst | Ubuntu-Version: Ubuntu 22.10 (Kinetic Kudu)
Antworten |

Serengeti

Avatar von Serengeti

Anmeldungsdatum:
24. Februar 2008

Beiträge: 1913

Ich möchte die Ausgabe einer Anwendung filtern und Zeilen entfernen bevor ich sie nach systemd-cat sende. Wenn ich das mit grep mache, dann ist anschliessend die ganze Programmausgabe in einer Journal Zeile. Wie kann ich das verhindern?

aktuell verwende ich:

1
BEFEHL |grep -v "text1"|grep -v "text2"|grep -v "text3"| systemd-cat -t identifier -p6

Der Befehl kann bis zu 5min laufen und recht viel unnötige Ausgabe erzeugen, wenn nicht ein paar Elemente rausfiltere.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

Serengeti schrieb:

Ich möchte die Ausgabe einer Anwendung filtern und Zeilen entfernen bevor ich sie nach systemd-cat sende. Wenn ich das mit grep mache, dann ist anschliessend die ganze Programmausgabe in einer Journal Zeile. Wie kann ich das verhindern?

Also, ich kann das für den allgemeinen Fall nicht bestätigen: mit seq 1 3 | systemd-cat -t foo -p debug bekomme ich:

Dez 21 23:24:14 foo[13077]: 1
Dez 21 23:24:14 foo[13077]: 2
Dez 21 23:24:14 foo[13077]: 3

Möglicherweise sendet Dein Programm gar keine Zeilenumbrüche. Leite mal die Ausgabe Deines Programmes nach od -t x1c um. Dann solltest du sehen, ob da \n auftauchen oder vielleicht nur \r.

aktuell verwende ich:

1
BEFEHL |grep -v "text1"|grep -v "text2"|grep -v "text3"| systemd-cat -t identifier -p6

Man kann das noch etwas optimieren, indem man die greps zusammen fasst:

1
BEFEHL | egrep -v 'text1|text2|text3' | systemd-cat -t identifier -p6

Das sollte allerdings nichts am Ergebnis ändern.

Serengeti

(Themenstarter)
Avatar von Serengeti

Anmeldungsdatum:
24. Februar 2008

Beiträge: 1913

Hallo rklm, danke für den Hinweis zu egrep.

Ich habe meinen code neu geschrieben. Jetzt geht es. Allerdings ist mir aufgefallen, dass ich auch das Problem habe, dass die Daten erst nach Abschluss der Anwendung im Log landen. So stimmen dann die Uhrzeiten nicht. Laut Internet soll hier nun --line-buffered als Kommando zu grep helfen, weil grep wohl sonst alles sammelt, was aber auch nicht funktioniert. Hast du da auch eine Idee zu.

Serengeti

(Themenstarter)
Avatar von Serengeti

Anmeldungsdatum:
24. Februar 2008

Beiträge: 1913

Hab mein Script etwas zusammengefasst, damit du siehst was ich im Detail mache.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/bash

scriptname=$(basename $0)
exec 4> >(systemd-cat -t $scriptname -p6)
exec 3> >(egrep -v 'text1|text2|text3' |systemd-cat -t $scriptname -p5)
exec 2> >(tee /dev/fd/3 )
exec 1> /dev/fd/3

echo "Start der Anwendung" >&4
BEFEHL 
echo "Befehl endet" >&4

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

Serengeti schrieb:

Allerdings ist mir aufgefallen, dass ich auch das Problem habe, dass die Daten erst nach Abschluss der Anwendung im Log landen. So stimmen dann die Uhrzeiten nicht. Laut Internet soll hier nun --line-buffered als Kommando zu grep helfen, weil grep wohl sonst alles sammelt, was aber auch nicht funktioniert. Hast du da auch eine Idee zu.

Möglicherweise sendet der Prozess, der die Ausgaben produziert, sie erst am Ende. Oder er erkennt, dass er auf eine Pipe schreibt und puffert größere Mengen an Daten als für die Konsole.

Serengeti schrieb:

Hab mein Script etwas zusammengefasst, damit du siehst was ich im Detail mache.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/bash

scriptname=$(basename $0)
exec 4> >(systemd-cat -t $scriptname -p6)
exec 3> >(egrep -v 'text1|text2|text3' |systemd-cat -t $scriptname -p5)
exec 2> >(tee /dev/fd/3 )
exec 1> /dev/fd/3

echo "Start der Anwendung" >&4
BEFEHL 
echo "Befehl endet" >&4

Das sieht seltsam aus - vor allem, dass Du Stdout und Stderr auf eine Floppy schreibst. Das produziert doch unvorhersehbare Ergebnisse. Was machst Du da eigentlich?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 10978

IMHO ist das Problem, dass systemd-cat nur einmal pro Pipe-Kette eines File-Deskriptors aufgerufen wird statt für jede einzelne Zeile.

Was man bräuchte wäre eine asynchrone, zeilenweise Verarbeitung der vom Programm auf stdout und stderr ausgegeben Daten:

#!/bin/bash

scriptname=$(basename $0)
exec 4> >(while read line; do echo "$line" | systemd-cat -t $scriptname -p6; done)
exec 3> >(egrep --line-buffered -v 'text1|text2|text3' | while read line; do echo $line | systemd-cat -t $scriptname -p5; done)
exec 2> >(tee /dev/fd/3 )
exec 1> /dev/fd/3

echo "Start der Anwendung" >&4
for i in $(seq 10); do
    echo "Das ist ein Test $i"
    sleep 1
done
echo "Befehl endet" >&4 

rklm schrieb:

Das sieht seltsam aus - vor allem, dass Du Stdout und Stderr auf eine Floppy schreibst.

https://manpages.ubuntu.com/manpages/jammy/en/man4/fd.4freebsd.html - nicht https://manpages.ubuntu.com/manpages/jammy/en/man4/fd.4.html

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

seahawk1986 schrieb:

IMHO ist das Problem, dass systemd-cat nur einmal pro Pipe-Kette eines File-Deskriptors aufgerufen wird statt für jede einzelne Zeile.

Das ist kein Problem:

1
2
3
4
5
6
$ for i in 1 2 3; do echo "> $i"; sleep 2; done | systemd-cat -t foo -p debug
$ journalctl -b -0 -t foo
Dez 24 14:29:07 foo[12978]: > 1
Dez 24 14:29:09 foo[12978]: > 2
Dez 24 14:29:11 foo[12978]: > 3
$ 

Man kann auch sehen, dass Ausgaben aus anderer Quelle dazwischen kommen können:

1
2
3
4
5
6
7
8
$ for i in 1 2 3; do echo "> $i"; systemd-cat -t foo date; sleep 2; done | systemd-cat -t foo -p debug
$ journalctl -b -0 -t foo
Dez 24 14:36:32 foo[13195]: > 1
Dez 24 14:36:32 foo[13196]: Sa 24. Dez 14:36:32 CET 2022
Dez 24 14:36:34 foo[13195]: > 2
Dez 24 14:36:34 foo[13198]: Sa 24. Dez 14:36:34 CET 2022
Dez 24 14:36:36 foo[13195]: > 3
Dez 24 14:36:36 foo[13200]: Sa 24. Dez 14:36:36 CET 2022

Was man bräuchte wäre eine asynchrone, zeilenweise Verarbeitung der vom Programm auf stdout und stderr ausgegeben Daten:

Ich denke nicht (s.o.).

rklm schrieb:

Das sieht seltsam aus - vor allem, dass Du Stdout und Stderr auf eine Floppy schreibst.

https://manpages.ubuntu.com/manpages/jammy/en/man4/fd.4freebsd.html - nicht https://manpages.ubuntu.com/manpages/jammy/en/man4/fd.4.html

Ach! Danke für die Korrektur. Das Problem mit den beiden Deskriptoren bleibt allerdings. Oder gibt es da eine Synchronisierung, die ich gerade übersehe?

Serengeti

(Themenstarter)
Avatar von Serengeti

Anmeldungsdatum:
24. Februar 2008

Beiträge: 1913

Ich verwende das Konstrukt aus meinem Beispiel mittlerweile immer für bash Scripte. Es ist einfach sehr angenehm um Sachen zielgerichtet zu protokollieren. Es hat sich bislang bewährt.

Ich habe mittlerweile herausgefunden, dass ich das Problem nur habe, wenn ein grep -v vorkommt. Bei normalem grep funktioniert es problemlos.

Antworten |