SYSLOG Auswertung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
w2kfs1
User
Beiträge: 6
Registriert: Mittwoch 14. Mai 2014, 08:22

Hi,

Ich habe folgende Herausforderung:
Ich habe ein SYSLOG file uns muss diese via Python27 auslesen und auswerten.
Ich habe leider noch keine vorkentnisse in Py und habe mal folgendes Probiert:

1: Hier das SYSLOG:

Code: Alles auswählen

......
blabla
[RIP] 2014/04/28 16:38:40,921
IP-RIP Rx : Response   SrcIp: 172.16.XX.128.
Vers.: RIP-2 Routg.Dom.: 0000
xyz blabla

[RIP] 2014/04/28 16:38:41,921
IP-RIP Rx : Response   SrcIp: 172.16.XX.128.
Vers.: RIP-2 Routg.Dom.: 0000
xyz blabla

[RIP] 2014/04/28 16:38:41,924
IP-RIP Rx : Response   SrcIp: 172.16.XX.128.
Vers.: RIP-2 Routg.Dom.: 0000
xyz blabla
....
2: Hier mein Script:

Code: Alles auswählen

import re
import datetime

filedata = ''

with open("C:\\X\\Syslog-X.txt", "r") as fobj:
	filedata = fobj.read()
	
def trace_dissect(trace):
	'''
	take a trace text and split it into little blocks, one per message
	'''
	trace_elements = []
	
	# trace_elements = trace.split('')
	block = []
	for line in trace.splitlines():
		if '[RIP]' in line:
			if len(block)>0:
				if '[RIP]' in block[0]:
					trace_elements.append(block)
			block = [line]
		else:
			block.append(line)
	if len(block):
		trace_elements.append(block)
	return trace_elements

## (a)hier neue Funktion?

def get_element_date(element):
	# damit wird die datetime ausgegeben
	d_str =  element[0].split(" ", 1)[1]
	d= datetime.datetime.strptime(d_str, "%Y/%m/%d %H:%M:%S,%f")
	return d

## (b)hier neue Funktion?

tr_elements = trace_dissect(filedata)
oldblock = None

for block in tr_elements:
	print get_element_date(block)
	if oldblock is not None:
		print get_element_date(block) - get_element_date(oldblock)
	oldblock = block

## (c)hier neue Funktion?
ich bekomme meine Ausgabe, aber ich habe derzeit keinen Idee wo ich die nähste Funktion
hinzufügen muss.
Bei print block[0]
2014-04-28 16:38:40.921000
0:00:00.002000
Bei print block[1]
IP-RIP Rx : Response
Bei print block[2]
Vers.: RIP-2 Routg.Dom.: 0000

ich habe leider gerade ein brett vom kopf?!
durch die splittung bekomme ich doch:
['[RIP] 2014/04/28 16:38:30,104', 'IP-RIP Tx: Request',
'SrcIp: 172.16.100.1', 'DstIp: 224.0.0.9', 'Vers.: RIP-2 Routg.Dom.: 0000', '']

Ich muss in der ersten Funktion nach Datum sortieren, RIP entfernen, dann nach 'IP-RIP Tx: Request'
suchen und nur diese zeilen verwenden mit der bedienung, dass 'Vers.: RIP-2 Routg.Dom.: 0000' vorhanden ist

==> ich kommen gerade nicht weiter und freue mich auf eure Vorschläge.

Mit besten Gruß

W2kfs1
Zuletzt geändert von Anonymous am Mittwoch 14. Mai 2014, 09:16, insgesamt 1-mal geändert.
Grund: Quellltext in Python-Code-Tags gesetzt.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

Setze deinen Code doch bitte in Codetags. Wie du sicher weißt, ist in Python die Einrückung Teil der Syntax. Geht die Einrückung verloren, so ist das Programm nicht mehr verständlich. Über dem Eingabefeld gibt es dazu ein "Code"-Button.

Es wäre auch gut, wenn du die Log-Daten in Codetags highlightest, dann heben diese sich deutlicher vom Fließtext ab und lassen sich besser lesen.
Das Leben ist wie ein Tennisball.
w2kfs1
User
Beiträge: 6
Registriert: Mittwoch 14. Mai 2014, 08:22

Hi EyDu,

sorry hatte ich übersehen.
BlackJack

@w2kfs1: Ich würde ja als nächstes eine Funktion schreiben die aus den Blöcken aus der ersten Funktion nur die ausfiltert die auch tatsächlich das nötige Format haben, also deren zweite Zeile mit 'IP-RIP Rx : Response SrcIp: ' anfängt und deren dritte Zeile 'Vers.: RIP-2 Routg.Dom.: 0000'.

Beim anfänglichen erstellen der Blöcke könnte man auch noch dafür sorgen das nur die ersten drei Zeilen von jedem Block in der Ergebnisliste landen.

Wenn man die drei Zeilen pro Block hat und es auf die Blöcke runtergefiltert hat, die tatsächlich weiterverarbeitet werden sollen, kann man die eigentlichen Informationen aus den Blöcken holen. Also Zeitstempel und IP wenn ich das richtig sehe. Bei zwei Werten kann man noch normale Tupel zum zusammenfassen verwenden, wenn es mehr wird, sollte man mindestens `collections.namedtuple` verwenden, damit der Quelltext verständlich bleibt.

Für solche Aufgaben bietet es sich an jeweils eine Funktion zu schreiben die nur *einen* Datensatz verarbeitet oder testet und diese Funktion dann mit `map()`/`filter()` oder `imap()`/`ifilter()` aus dem `itertools`-Modul zu verwenden um mehrere Datensätze damit zu transformieren oder zu filtern.

Ich persönlich würde wahrscheinlich komplett auf das „lazy” verarbeiten der Daten setzen und zum Gruppieren der Blöcke schon auf `itertools.groupby()` setzen.

Das Hauptprogramm auf Modulebene sollte auch in einer Funktion verschwinden. Auf jeden Fall sollte man nicht Hauptprogramm und definieren von Funktionen auf Modulebene abwechselnd schreiben. Das wird unübersichtlich weil man dann schnell mal Code zwischen zwei Funktionen übersieht beziehungsweise das Hauptprogramm gar nicht zusammenhängend lesen kann.

Üblicherweise kommt das in eine Funktion mit dem Namen `main()` und wird mit folgendem Idiom aufgerufen:

Code: Alles auswählen

if __name__ == '__main__':
    main()
Einrücktiefe ist per Konvention vier Leerzeichen.
w2kfs1
User
Beiträge: 6
Registriert: Mittwoch 14. Mai 2014, 08:22

Hi BlackJack,

[...]
Ich würde ja als nächstes eine Funktion schreiben die aus den Blöcken aus der ersten Funktion nur die ausfiltert die auch tatsächlich
das nötige Format haben, also deren zweite Zeile mit 'IP-RIP Rx : Response SrcIp: ' anfängt und deren dritte Zeile 'Vers.: RIP-2 Routg.Dom.: 0000'.
[...]

Genau das brauche ich, ich habe aber derzeit keine Idee wie?

Code: Alles auswählen

if 'IP-RIP Rx : Response SrcIp: ' in line:
    else:
	block.append(line)
Wie beschrieben, nutze ich Python erst 2 Tage ... itertools.groupby() ist mir noch zu komplex.
BlackJack

@w2kfs1: Mal ein Ansatz:

Code: Alles auswählen

#!/usr/bin/env python
from datetime import datetime as DateTime
from itertools import groupby, ifilter, imap, islice
from operator import itemgetter


get_first, get_second = [itemgetter(i) for i in [0, 1]]


def iter_rip_blocks(lines):
    """Returns iterator of lists with first three lines of blocks starting
    with '[RIP]'.
    """
    def mark():
        i = 0
        for line in lines:
            if line.startswith('[RIP] '):
                i += 1
            yield (i, line)

    for i, group in groupby(mark(), get_first):
        if i != 0:
            result = list(islice(imap(get_second, group), 3))
            if len(result) == 3:
                yield result


def check_block(lines):
    """Checks if the given three lines are a [RIP]-Block of interest."""
    return (
        lines[0].startswith('[RIP]')
        and lines[1].startswith('IP-RIP Rx : Response ')
        and lines[2] == 'Vers.: RIP-2 Routg.Dom.: 0000\n'
    )


def parse_block(lines):
    """Extracts the timestamp and IP from the given [RIP]-Block lines."""
    return (
        DateTime.strptime(lines[0], '[RIP] %Y/%m/%d %H:%M:%S,%f\n'),
        lines[1].split()[-1][:-1]
    )


def parse_blocks(lines):
    return imap(parse_block, ifilter(check_block, iter_rip_blocks(lines)))


def main():
    with open('test.txt') as lines:
        for block in parse_blocks(lines):
            print block


if __name__ == '__main__':
    main()
w2kfs1
User
Beiträge: 6
Registriert: Mittwoch 14. Mai 2014, 08:22

Hi BlackJack,

ich habe es einfacher gelöst:

Code: Alles auswählen

import re
import datetime

filedata = ''

with open("C:\\SYSLOG\\SYSLOG.txt", "r") as fobj:
	filedata = fobj.read()

def trace_dissect(trace):
	
	trace_elements = []
	
	block = []
	for line in trace.splitlines():
		if '[RIP]' in line:
			if len(block)>0:
				if '[RIP]' in block[0]:
					trace_elements.append(block)
			block = [line]
		else:
			block.append(line)
	if len(block):
		trace_elements.append(block)
	return trace_elements

def get_element_date(element):
	d_str =  element[0].split(" ", 1)[1]
	d= datetime.datetime.strptime(d_str, "%Y/%m/%d %H:%M:%S,%f")
	return d

tr_elements = trace_dissect(filedata)
ripblocks_delayed = []

for block in tr_elements:
 	if 'IP-RIP Rx : Response' in block[1] and 'SrcIp: 172.16.100.1' in block[2] and not block[5].startswith('0.0.0.0'):
 		ripblocks_delayed.append(block)

oldblock = None

for block in ripblocks_delayed:
 	#print block
 	if oldblock is not None:
		 print get_element_date(block) - get_element_date(oldblock)
  	oldblock = block

	print block
Damit erhalte ich folgendes Ergebnis aus meinen SYSLOG-LOG:
['[RIP] 2014/04/28 16:38:42,029', 'IP-RIP Rx: Response', 'SrcIp: 172.16.100.1', 'DstIp: 224.0.0.9', 'Vers.: RIP-2 Routg.Dom.:
['[RIP] 2014/04/28 16:38:42,130', 'IP-RIP Rx: Response', 'SrcIp: 172.16.100.1', 'DstIp: 224.0.0.9', 'Vers.: RIP-2 Routg.Dom.:
['[RIP] 2014/04/28 16:38:42,230', 'IP-RIP Rx: Response', 'SrcIp: 172.16.100.1', 'DstIp: 224.0.0.9', 'Vers.: RIP-2 Routg.Dom.:
['[RIP] 2014/04/28 16:38:42,331', 'IP-RIP Rx: Response', 'SrcIp: 172.16.100.1', 'DstIp: 224.0.0.9', 'Vers.: RIP-2 Routg.Dom.:

Jetzt muss ich nur noch gucken wie ist das Time_delta der Zeilen hinbekomme, wie man sieht sollten es zwischen den Paketen 100ms sein.

Mit besten Gruß

W2kfs1
w2kfs1
User
Beiträge: 6
Registriert: Mittwoch 14. Mai 2014, 08:22

Hi BlackJack,

um meine Pakete nach nach dem delay 100ms zu prüfen, mache ich das mit datetime_delay?
Ich brauche nur noch eine Funktion die x==100ms = True.

Wobei x=block.
  • ['[RIP] 2014/04/28 16:38:42,029', 'IP-RIP Rx: Response', 'SrcIp: 172.16.100.1', 'DstIp: 224.0.0.9', 'Vers.: RIP-2 Routg.Dom.:
    ['[RIP] 2014/04/28 16:38:42,130', 'IP-RIP Rx: Response', 'SrcIp: 172.16.100.1', 'DstIp: 224.0.0.9', 'Vers.: RIP-2 Routg.Dom.:
    ['[RIP] 2014/04/28 16:38:42,230', 'IP-RIP Rx: Response', 'SrcIp: 172.16.100.1', 'DstIp: 224.0.0.9', 'Vers.: RIP-2 Routg.Dom.:
    ['[RIP] 2014/04/28 16:38:42,331', 'IP-RIP Rx: Response', 'SrcIp: 172.16.100.1', 'DstIp: 224.0.0.9', 'Vers.: RIP-2 Routg.Dom.:
Oder kann ich eine einfache if anweisung verwenden?
if timebla in block[0] >= 100ms than true?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo,

schau einfach mal in die Dokumentation des datetime-Moduls, du kannst problemlos mit Zeiten rechnen. Hilfreich ist hier sicherlich timedelta.

Du solltest dir angewöhnen deine Probleme präziser zu beschreiben. Aussagen wie
w2kfs1 hat geschrieben:Ich brauche nur noch eine Funktion die x==100ms = True.
Wobei x=block.
oder
w2kfs1 hat geschrieben:if timebla in block[0] >= 100ms than true?
sind wenig hilfreich. Die erste ist mir vollkommen unklar, bei der zweiten sollte das "than" wohl "then" heißen. Dann bleibt nur noch die Frage, was "timebla" sein soll.
Das Leben ist wie ein Tennisball.
w2kfs1
User
Beiträge: 6
Registriert: Mittwoch 14. Mai 2014, 08:22

Hi @ll,

danke an alle, habe es hinbekommen.

THX
Antworten