Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
snafu1 schrieb: Dann läuft da eine ältere Python-Version, die noch nicht die relativ neuen f-Strings kennt.
Ist laut aptitude Version 3.4.0. Es steht demnächst ein System-Upgrade an, aber vorher sind noch andere wichtigere Dinge zu erledigen (z.B. Umzug auf neue Hardware).
Ist aber im Grunde auch egal, da das Vorhaben mit AWK eh leichter zu lösen ist.
Jep, das lässt sich am einfachsten in ein Bash-Skript überführen, um am Ende noch eine Zusammenfassung ausgeben zu können.
Okay, ich wollte mal kreativ sein. Bau dir die Spalten halt in der Reihenfolge, die für dich am besten ist. ☺
Kein Problem. Danke nochmal an alle Beteiligten für die Unterstützung! 😀
Na, dann lass ich's jetzt auch mal gut sein. Du solltest nun genug Code vorliegen haben. 😉
In der Tat.
EDIT:
Bezüglich der schlechten Performance beim letzen Skript:
Ja, in diese Richtung ging auch mein Gedanke, denn (nahezu) jede zweite Zeile im Log beginnt ja mit einer öffnenden eckigen Klammer und einem nachfolgenden Zeitstempel, von allem, was protokolliert wird. Aber nur wenige Zeilen enthalten tatsächlich Angaben zu den fehlgeschlagenden Logins. Grüße
Dalai
|
snafu1
Anmeldungsdatum: 5. September 2007
Beiträge: 2123
Wohnort: Gelsenkirchen
|
Dalai schrieb: snafu1 schrieb: Bezüglich der schlechten Performance beim letzen Skript:
Ja, in diese Richtung ging auch mein Gedanke, denn (nahezu) jede zweite Zeile im Log beginnt ja mit einer öffnenden eckigen Klammer und einem nachfolgenden Zeitstempel, von allem, was protokolliert wird. Aber nur wenige Zeilen enthalten tatsächlich Angaben zu den fehlgeschlagenden Logins.
Regex-Konstrukte, die beliebigen Text erlauben (also sowas wie .* und .+) verhalten sich wohl übel in der Laufzeit, wenn sie keinen Treffer finden. Die Logik versucht bei der Ausführung dann alles mögliche, um doch noch erfolgreich zu sein. Das ist auch als Catastrophic Backtracking bekannt. Näheres findet man bei Interesse z.B. hier: https://www.regular-expressions.info/catastrophic.html Für mich ist es ein weiterer Beleg, dass häufig eine Kombination aus sinnvoller Vorab-Filterung, speziellen String-Operationen und Regex-Pattern besser und performanter ist, anstatt sich nur auf letzteres zu verlassen.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12801
|
snafu1 schrieb:
Regex-Konstrukte, die beliebigen Text erlauben (also sowas wie .* und .+) verhalten sich wohl übel in der Laufzeit, wenn sie keinen Treffer finden.
Ich glaube, in der Allgemeinheit ist diese Aussage nicht korrekt. Es hängt schon sehr vom Ausdruck und der Engine ab. DFA's machen z.B. generell kein Backtracking. Es gibt immer noch den Regex Coach, mit dem man so etwas nett untersuchen kann. Mittleweile gibt es weitere ähnliche Tools (siehe hier).
Die Logik versucht bei der Ausführung dann alles mögliche, um doch noch erfolgreich zu sein. Das ist auch als Catastrophic Backtracking bekannt. Näheres findet man bei Interesse z.B. hier: https://www.regular-expressions.info/catastrophic.html
Ich denke aber, so einen Fall haben wir hier nicht - zumal meine Regexe keine Sequenzen ".*" und ".+" enthalten. Außerdem waren die Ausdrücke ja so gebaut, dass sie jeweils jede zweite Zeile matchen und schnell scheitern, weil ich das Muster recht spezifisch gemacht habe.
Für mich ist es ein weiterer Beleg, dass häufig eine Kombination aus sinnvoller Vorab-Filterung, speziellen String-Operationen und Regex-Pattern besser und performanter ist, anstatt sich nur auf letzteres zu verlassen.
Ich würde immer mit den regulären Ausdrücken anfangen und den Algorithmus nur komplizierter machen, wenn die Ausführungszeit ein Problem ist, das man nicht durch Änderungen am Ausdruck (z.B. Possessive Quantifier) reparieren kann. Dalai schrieb: rklm schrieb: Iiih! Rein aus Neugier, kannst Du mal diese Ruby-Version meines awk -Skriptes probieren und uns wissen lassen, wie lange die auf der selben Eingabe braucht?
Ruby ist nicht installiert, und das werde ich auf diesem Produktivsystem nur zum Testen auch nicht machen. Python und Perl sind vorhanden.
Kannst Du mal einen bereinigten Satz von Logs bereitstellen, so dass ich das selbst mal testen kann? Du könntest natürlich auch die Ruby-Version und die awk -Version auf Deinem Entwicklungsrechner ausprobieren.
|
snafu1
Anmeldungsdatum: 5. September 2007
Beiträge: 2123
Wohnort: Gelsenkirchen
|
rklm schrieb: Ich würde immer mit den regulären Ausdrücken anfangen und den Algorithmus nur komplizierter machen, wenn die Ausführungszeit ein Problem ist, das man nicht durch Änderungen am Ausdruck (z.B. Possessive Quantifier) reparieren kann.
Was ja hier der Fall war. Aber gut, ich will das nun nicht ausdiskutieren, da wir offenbar unterschiedliche Philosophien in diesem Bereich verfolgen. Im Endeffekt sollte es in annehmbarer Zeit funktionieren und möglichst verständlich sein. Wie verständlich komplexe reguläre Ausdrücke sind - und dies (IMHO) ohne Not, weil es halt Alternativen gibt - steht auf einem anderen Blatt. Nur sind wir dann wieder bei den zwei gegensätzlichen Ansichten, von denen ich sprach.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12801
|
snafu1 schrieb: rklm schrieb: Ich würde immer mit den regulären Ausdrücken anfangen und den Algorithmus nur komplizierter machen, wenn die Ausführungszeit ein Problem ist, das man nicht durch Änderungen am Ausdruck (z.B. Possessive Quantifier) reparieren kann.
Was ja hier der Fall war. Aber gut, ich will das nun nicht ausdiskutieren, da wir offenbar unterschiedliche Philosophien in diesem Bereich verfolgen. Im Endeffekt sollte es in annehmbarer Zeit funktionieren und möglichst verständlich sein. Wie verständlich komplexe reguläre Ausdrücke sind - und dies (IMHO) ohne Not, weil es halt Alternativen gibt - steht auf einem anderen Blatt. Nur sind wir dann wieder bei den zwei gegensätzlichen Ansichten, von denen ich sprach.
Ja, ich fühle mich mit Regulären Ausdrücken halt sehr wohl. ☺ Und sie müssen gar nicht so unlesbar sein: manche Engines (z.B. die von Ruby) erlauben Ausdrücke über mehrere Zeilen zu verteilen und sogar Kommentare einzubetten. Das ändert nichts an der Scan-Performance, macht sie aber lesbar. Ruby ist halt meine Brot-und-Butter-Sprache für solche Probleme und ich nutze awk hier im Forum hauptsächlich, weil es für viele Probleme reicht und ich das Werkzeug besser kennen lernen will.
|
Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
rklm schrieb: Kannst Du mal einen bereinigten Satz von Logs bereitstellen, so dass ich das selbst mal testen kann?
Leider nein, jedenfalls nicht, wenn es darum geht, die Laufzeit zu untersuchen. Es sind fast 1000 Dateien mit insgesamt ~120 MiB Größe. Aktuell sind darin nur ca. 20 Loginfehlversuche enthalten. Also ist das nichts, was man einfach so bereinigen könnte. Stattdessen nur die Loginfehlversuche herauszufiltern, ist meiner Meinung nach auch sinnfrei, wenn es um die Untersuchung der Laufzeit geht, da ist es wohl "einfacher" die Logzeilen aus dem OP zu vervielfachen.
Du könntest natürlich auch die Ruby-Version und die awk -Version auf Deinem Entwicklungsrechner ausprobieren.
Das hatte ich zwar auch überlegt, aber aussagekräftig wird es IMO nicht. Denn einerseits müsste ich die Logs vom Produktivsystem holen (die Beispiele im OP hab ich von der Test-VM), und anderseits werden die Laufzeiten kaum vergleichbar, weil völlig andere CPU (Ryzen vs. Opteron) und andere Umgebung mit einem anderen Satz von Diensten; auf der VM springt logischerweise keiner produktiv rum. Grüße
Dalai
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12801
|
Dalai schrieb: rklm schrieb: Kannst Du mal einen bereinigten Satz von Logs bereitstellen, so dass ich das selbst mal testen kann?
Leider nein, jedenfalls nicht, wenn es darum geht, die Laufzeit zu untersuchen. Es sind fast 1000 Dateien mit insgesamt ~120 MiB Größe.
120MB sind ja nix - und wenn Du das mit 7z oder tar + bzip2 komprimierst, wird es mit Sicherheit noch mal deutlich weniger.
Aktuell sind darin nur ca. 20 Loginfehlversuche enthalten. Also ist das nichts, was man einfach so bereinigen könnte.
Mit "Bereinigen" war gemeint, PII (Benutzernamen, IP-Adressen) unkenntlich zu machen, aber den Rest natürlich genau so lassen, wie er ist.
Stattdessen nur die Loginfehlversuche herauszufiltern, ist meiner Meinung nach auch sinnfrei, wenn es um die Untersuchung der Laufzeit geht, da ist es wohl "einfacher" die Logzeilen aus dem OP zu vervielfachen.
Das müsste man dann im Richtigen Verhältnis machen. Da müsstest Du mal ansagen, wie viel Prozent der Zeilen welches Muster enthalten.
Du könntest natürlich auch die Ruby-Version und die awk -Version auf Deinem Entwicklungsrechner ausprobieren.
Das hatte ich zwar auch überlegt, aber aussagekräftig wird es IMO nicht. Denn einerseits müsste ich die Logs vom Produktivsystem holen (die Beispiele im OP hab ich von der Test-VM), und anderseits werden die Laufzeiten kaum vergleichbar, weil völlig andere CPU (Ryzen vs. Opteron) und andere Umgebung mit einem anderen Satz von Diensten; auf der VM springt logischerweise keiner produktiv rum.
Ich finde das sehr wohl aussagekräftig: Du bekommst zumindest einen Vergleich der Laufzeiten von ruby und awk auf dem selben System. Da macht der andere CPU-Typ nix aus. Und das Holen vom Produktionssystem ist ja nur ein Vorbereitungsschritt.
|
Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
rklm schrieb: 120MB sind ja nix - und wenn Du das mit 7z oder tar + bzip2 komprimierst, wird es mit Sicherheit noch mal deutlich weniger.
Das stimmt zwar, aber ändert nichts am Umfang der enthaltenen Daten, die ich durcharbeiten müsste, um alles datenschutzrelevante zu entfernen, und das dennoch nicht sicherstellen könnte. Auch aus Metadaten lässt sich eine Menge ablesen, so dass ich diese Logs garantiert nicht öffentlich zur Verfügung stellen werde. Ich hoffe, das ist nachvollziehbar.
Das müsste man dann im Richtigen Verhältnis machen. Da müsstest Du mal ansagen, wie viel Prozent der Zeilen welches Muster enthalten.
Das ist klar. Aber das Verhältnis hatte ich ja genannt. Alles, was nicht Loginfehlversuche sind, sind entweder erfolgreiche Logins oder andere Meldungen zu nicht gefundenen Druckern (haha, Drucker-Zeug ist in der smb.conf deaktiviert, soweit das möglich ist) oder anderem unwichtigem Kram.
Ich finde das sehr wohl aussagekräftig: Du bekommst zumindest einen Vergleich der Laufzeiten von ruby und awk auf dem selben System. Da macht der andere CPU-Typ nix aus. Und das Holen vom Produktionssystem ist ja nur ein Vorbereitungsschritt.
Die relativen Laufzeitunterschiede zwischen awk und Ruby lassen sich trotzdem nicht notwendigerweise auf eine andere CPU übertragen. Da spielen zu viele Faktoren mit rein (Cache, Takt, Architektur usw). Zum Abschluss des Ganzen: Durch einen sowieso schon seit Ewigkeiten und gestern endlich vollzogenen Hardware-Wechsel (von Opteron auf EPYC) ist die Laufzeit von ~3,5 auf 1,4 bis 1,6 Sekunden (mit denselben Logs) gefallen, so dass jegliche zusätzlich investierte Zeit zur Optimierung es kaum wert ist. Nochmal ein dickes Dankeschön an die Helfer und einen schönen restlichen ersten Advent! (dem Forum fehlen Advents-Smilies 😉) Grüße
Dalai
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12801
|
Dalai schrieb:
Die relativen Laufzeitunterschiede zwischen awk und Ruby lassen sich trotzdem nicht notwendigerweise auf eine andere CPU übertragen. Da spielen zu viele Faktoren mit rein (Cache, Takt, Architektur usw).
Das ist natürlich streng genommen korrekt, aber diese Unterschiede bewegen sich in einem kleinen Bereich. Es wäre ja schon eine wertvolle Information zu wissen, dass ein Ansatz doppelt so lange braucht wie der andere. Bei kleinen Unterschieden - sagen wir: kleiner als 5% - ist es sowieso egal, was man nimmt. Aber es wäre schon hilfreich zu wissen, wenn es dramatischere Unterschiede gibt. Denn, selbst, wenn man die exakten Zahlen nicht übertragen kann, so kann man das doch für die Größenordnung.
Zum Abschluss des Ganzen: Durch einen sowieso schon seit Ewigkeiten und gestern endlich vollzogenen Hardware-Wechsel (von Opteron auf EPYC) ist die Laufzeit von ~3,5 auf 1,4 bis 1,6 Sekunden (mit denselben Logs) gefallen, so dass jegliche zusätzlich investierte Zeit zur Optimierung es kaum wert ist.
Jo.
|
Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
Leider muss ich den Thread nochmal wiederbeleben wegen einer Kleinigkeit (hoffentlich). Aktuell verwende ich folgenden Befehl zum Durchsuchen der Logs: awk '/FAILED with error/ {
match($0, /(\[.*]( -> )?)+/, usermatch)
print(timestamp, ARGV[ARGIND], usermatch[0], $NF)
}
/^\[/ {timestamp = substr($0, 1, 20) "]"} ' /var/log/samba/log.*
Inzwischen läuft auf dem System ein neueres Ubuntu mit neuerem Samba, der weitere Dinge in die Logs schreibt. Daher bräuchte ich nochmal eure Hilfe. Samba loggt nun
check_ntlm_password: Authentication for user [Administrator] -> [administrator] FAILED with error NT_STATUS_NO_SUCH_USER, authoritative=0 Es existieren im Verzeichnis sowohl neue als auch alte Logs, letzteren fehlt das ", authoritative=?" am Ende der Zeilen. Mit obigem awk-Code wird bei neuen Logs das "authoritative=?" statt des NT_STATUS_NO_SUCH_USER ausgegeben. Wie kann man diesen Teil der Zeile als optional kennzeichnen und ignorieren lassen? Ich hab versucht, das in der match-Funktion als non-capturing group und mittels Fragezeichen optional zu machen, aber das ändert nichts. Diesen String erst wegschneiden und dann wie gehabt verarbeiten mit
awk '/FAILED with error/ {
sub(/, authoritative=.+/, "")
match($0, /(\[.*]( -> )?)+/, usermatch)
print(timestamp, ARGV[ARGIND], usermatch[0], $NF)
}
/^\[/ {timestamp = substr($0, 1, 20) "]"} ' /var/log/samba/log.* geht. Aber ich denke, dass es besser, d.h. ohne weiteren Funktionsruf, gehen müsste. Das geht doch bestimmt auch in dem schon existierenden Aufruf von match, oder? Grüße
Dalai
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12801
|
| awk '/FAILED with error/ {
match($0, /(\[.*]( -> )?)+[^,]* ([^ ,]+)/, usermatch)
print(timestamp, ARGV[ARGIND], usermatch[1], usermatch[3])
}
/^\[/ {timestamp = substr($0, 1, 20) "]"} ' /var/log/samba/log.*
|
|
Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
Ah, so ist das. Ich Depp hatte völlig übersehen, dass username[0] den gesamten gematchten String enthält, wie die Doku ausführt, und nicht den Teil in der ersten Klammer. Nun verstehe ich auch die Indizes 1 und 3 des Arrays. Dankeschön! Grüße
Dalai
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12801
|
Dalai schrieb: Ah, so ist das. Ich Depp hatte völlig übersehen, dass username[0] den gesamten gematchten String enthält, wie die Doku ausführt, und nicht den Teil in der ersten Klammer. Nun verstehe ich auch die Indizes 1 und 3 des Arrays.
Prima! Ich vermute, dass das Plus hinter der ersten Gruppe überflüssig ist. Hatte aber gestern Abend nicht mehr genug Lust und Zeit und jetzt fehlt mir leider auch die Zeit. Probier einfach mal aus.
Dankeschön!
Gerne!
|