2017-05-15 3 views
-2

Ich brauche Hilfe mit awk/grep/sed oder was auch immer Sie denken, können die Arbeit tun. Ich habe eine Protokolldatei und muss sie kontinuierlich überwachen und einige Daten aus den neuen Zeilen abrufen, während sie darauf geschrieben werden.So extrahieren Sie Daten aus Live-Log und Pipe es zu Postgres

Die neuen Zeilen sind sehr lang und nicht strukturiert, aber sie enthalten das folgende Muster UserName=SOMEUSRNAME, NetworkDevice=SOMENETWORKDEVICE, Calling-Station-ID=SOMEMACADDRESS.

Exmaple:
May 15 03:59:16 MTN-LAB-ISE-B1 CISE_Passed_Authentications 0000043297 1 0 2017-05-15 03:59:16.979 +00:00 0013123384 5200 NOTICE Passed-Authentication: Authentication succeeded, ConfigVersionId=170, Device IP Address=10.97.31.130, DestinationIPAddress=10.62.56.152, DestinationPort=1812, UserName=abcd\testuser, Protocol=Radius, RequestLatency=313, NetworkDeviceName=SHROCLUSW-WLAN-LAB, User-Name=d4d748fefe96, NAS-IP-Address=10.97.31.130, NAS-Port=50005, Service-Type=Call Check, Framed-IP-Address=10.97.109.64, Framed-MTU=1500, Called-Station-ID=64-E9-50-B6-DE-05, Calling-Station-ID=D4-D7-48-FE-FE-96, NAS-Port-Type=Ethernet, NAS-Port-Id=GigabitEthernet0/5, EAP-Key-Name=,

Ich dachte tail -f mit der Protokolldatei und Rohr zu überwachen, es zu grep/sed/awk die benötigten Daten zu extrahieren. Ich brauche nur die SOMEUSERNAME, SOMENETWORKDEVICE, SOMEMACADDRESS und nicht das Muster auch.

Und natürlich, um dies noch komplizierter zu machen, nachdem die Extraktion fertig ist, muss ich es zu Postgres pipes.

Kann mir jemand einen Tipp geben, wie man das Matching/Extraktionsteil und vielleicht die Pipe zu Postgres macht?

+0

Willkommen bei StackOverflow. Bitte nehmen Sie die [Tour], lernen, gute Fragen stackoverflow zu stellen.com/help/how-to-ask, machen Sie ein [mcve]. Ein MCVE sollte eine Vielzahl von Beispieleingaben (unter Veranschaulichung aller Aspekte) und die gewünschte Ausgabe enthalten. Bitte zeigen Sie, was Sie versucht haben, einschließlich des Teils mit Schwanz. – Yunnosch

Antwort

0

Dies könnte auch mit grep/sed geschehen, aber ich persönlich bevorzuge awk.

Ich habe diese kurze Skript filter.awk:

{ 
    # find info in line 
    userName = gensub(/^.*UserName=([^,\r\n]+).*$/, "\\1", 1, $0) 
    networkDevice = gensub(/^.*NetworkDeviceName=([^,\r\n]+).*$/, "\\1", 1, $0) 
    callingStationId = gensub(/^.*Calling-Station-ID=([^,\r\n]+).*$/, "\\1", 1, $0) 
    # print filtered info (if any of patterns matched) 
    if (userName != "" || networkDevice != "" || callingStationId != "") { 
    print "INSERT INTO logs (username, networkdevice, calling_station_id) VALUES ('"userName"', '"networkDevice"', '"callingStationId"');" 
    } 
    # If "all patterns" is required instead of "any pattern" 
    # the "||" operators have to be replaced with "&&". 
} 

ich es mit GNU awk auf bash in Cygwin getestet (Fenster 10):

$ cat >filter.txt <<EOF 
> May 15 03:59:16 MTN-LAB-ISE-B1 CISE_Passed_Authentications 0000043297 1 0 2017-05-15 03:59:16.979 +00:00 0013123384 5200 NOTICE Passed-Authentication: Authentication succeeded, ConfigVersionId=170, Device IP Address=10.97.31.130, DestinationIPAddress=10.62.56.152, DestinationPort=1812, UserName=abcd\testuser, Protocol=Radius, RequestLatency=313, NetworkDeviceName=SHROCLUSW-WLAN-LAB, User-Name=d4d748fefe96, NAS-IP-Address=10.97.31.130, NAS-Port=50005, Service-Type=Call Check, Framed-IP-Address=10.97.109.64, Framed-MTU=1500, Called-Station-ID=64-E9-50-B6-DE-05, Calling-Station-ID=D4-D7-48-FE-FE-96, NAS-Port-Type=Ethernet, NAS-Port-Id=GigabitEthernet0/5, EAP-Key-Name=, 
> EOF 

$ awk -f filter.awk filter.txt 
INSERT INTO logs (username, networkdevice, calling_station_id) VALUES ('abcd\testuser', 'SHROCLUSW-WLAN-LAB', 'D4-D7-48-FE-FE-96'); 

$ 

Hinweise:

  1. Die NetworkDevice= Muster scheint mir nicht ausreichend zu sein. Ich ersetzte es durch NetworkDeviceName=. (Es sollte leicht zu ersetzen, wenn ich falsch liege.)

  2. Ich weiß nicht, wie die Ausgabe richtig formatiert für postgres noch kenne ich die Datenbankstruktur des Fragestellers. Daher muss wahrscheinlich die print Anweisung angepasst werden. (Es gibt nur eine print-Anweisung im Skript.) Die print-Anweisung wird jedoch an den Standard-Ausgabekanal ausgegeben (was Sie möglicherweise bereits erwartet haben). Somit kann es leicht in jeden anderen Eingabe-verbrauchenden Prozess geleitet werden.

  3. Es ist unklar, ob alle Muster übereinstimmen müssen oder (stattdessen) mindestens eins.
    Ich habe "mindestens eine" implementiert.
    Um "alle" zu implementieren, mussten die || Operatoren in der if Anweisung durch && Operatoren ersetzt werden. (Es gibt nur eine if Anweisung im Skript.)

  4. Leider ist die gensub() Funktion nur in GNU awk verfügbar. Für Nicht-GNU-awk könnte eine andere Lösung stattdessen unter Verwendung von gsub() durchgeführt werden. Allerdings ist die gensub() Funktion viel bequemer zu verwenden. Daher bevorzuge ich es, solange eine Nicht-GNU-awk-Lösung nicht explizit benötigt wird.

Verwandte Themen