Hive RegexSerDe Multiline Log-Abgleich

9

Ich suche nach einer Regex, die zu einer "create external table" -Anweisung von Hive QL in Form von

gespeist werden kann %Vor%

Die Bedingung ist, dass die Protokolle in den Dateien, die RegexSerDe lesen muss, die folgende Form haben:

%Vor%

Ich verwende den folgenden externen Tabellencode erstellen:

%Vor%

Hier ist das Ding:

Es kann alle FIRST LINES jedes Logs ziehen. Aber nicht die anderen Zeilen von Protokollen, die mehr als eine Zeile haben. Ich habe alle Links ausprobiert, am Ende \z durch \Z ersetzt, \A durch ^ ersetzt und \Z oder \z durch $ , nichts hat funktioniert. Fehle ich etwas in der %4$s von output.format.string? oder verwende ich die Regex nicht richtig?

Was die Regex tut:

Es stimmt zuerst mit dem Zeitstempel überein, gefolgt vom Protokolltyp ( DEBUG oder INFO oder was auch immer), dann ID (Mischung aus Kleinbuchstaben, Zahlen und Bindestrichen) gefolgt von ANYTHING bis zum nächsten Zeitstempel gefunden oder bis das Ende der Eingabe mit dem letzten Protokolleintrag übereinstimmt. Ich habe auch versucht, die /m am Ende hinzufügen, in diesem Fall hat die generierte Tabelle alle NULL-Werte.

    
harshilg 29.07.2013, 22:20
quelle

3 Antworten

1

Es scheint eine Reihe von Problemen mit Ihrer Regex zu geben.

Entfernen Sie zuerst Ihre doppelten eckigen Klammern.

Zweitens müssen \A und \Z / \z dem Anfang und dem Ende der Eingabe entsprechen, nicht nur einer Zeile. Ändern Sie \A in ^ , um den Zeilenanfang zu erreichen, aber nicht ändern Sie \z in $ , da Sie in diesem Fall tatsächlich das Ende der Eingabe anpassen möchten.

Drittens, Sie möchten (.*?) , nicht (.*)? zuordnen. Das erste Muster ist nicht gierig, während das zweite Muster gierig, aber optional ist. Es sollte Ihre gesamte Eingabe an das Ende angepasst haben, da Sie nach dem Ende der Eingabe folgen konnten.

Viertens stimmt . nicht mit Newlines überein. Sie können stattdessen (\s|\S) oder ([x]|[^x]) usw. jedes Paares von kostenlosen Übereinstimmungen verwenden.

Fünftens, wenn es Ihnen Übereinstimmungen mit einzelnen Zeilen mit \A und \Z / \z gab, dann waren die Eingaben auch einzelne Zeilen, da Sie die gesamte Zeichenfolge verankert haben.

Ich würde vorschlagen, nur \n zu finden, wenn nichts passt, dann werden keine Zeilenumbrüche hinzugefügt.

Sie können /m nicht zum Ende hinzufügen, da die Regex keine Trennzeichen enthält. Es wird versuchen, die Literalzeichen /m zu finden, deshalb haben Sie keine Übereinstimmung.

Wenn es funktionieren würde, wäre die gewünschte Regex:

%Vor%

Aufschlüsselung:

%Vor%

Übereinstimmungsstart von newline und 19 Zeichen, die Ziffern sind, : , - oder plus ein Komma, drei Ziffern und ein Leerzeichen. Erfassen Sie alle bis auf das letzte Leerzeichen (den Zeitstempel).

%Vor%

Entspricht einem Literal [ , einer beliebigen Anzahl von Großbuchstaben, sogar keinem, einem Literal ] und einem Leerzeichen. Erfassen Sie alle bis auf das letzte Leerzeichen (die Fehlerstufe).

%Vor%

Entsprechen Sie einer beliebigen Anzahl von Ziffern, Kleinbuchstaben oder - und einem Leerzeichen. Erfassen Sie alle bis auf das letzte Leerzeichen (die Nachrichten-ID).

%Vor%

Entsprechen alle Leerzeichen oder Nicht-Leerzeichen (jedes Zeichen), stimmen aber mit nicht gierigen *? überein. Stoppen Sie den Abgleich, wenn ein neuer Datensatz oder ein Ende der Eingabe ( \Z ) unmittelbar voraus ist. In diesem Fall möchten Sie das Ende der Zeile nicht erneut zuordnen, Sie erhalten nur eine Zeile in Ihrer Ausgabe. Erfassen Sie alle bis auf das letzte (den Nachrichtentext). Mit \r?\n wird der letzte Zeilenumbruch am Ende der Nachricht übersprungen, ebenso wie mit \r?\Z . Sie könnten auch \r?\n\z schreiben. Hinweis: capital \Z enthält den letzten Zeilenumbruch am Ende der Eingabe, falls vorhanden. Kleinbuchstaben \z stimmt nur am Ende der Eingabe überein, nicht vor dem Ende der Eingabe. Ich habe \z? hinzugefügt, nur für den Fall, dass Sie mit Windows-Zeilenenden zu tun haben, aber ich glaube nicht, dass dies notwendig sein sollte.

Ich vermute jedoch, dass Sie nicht die ganze Datei gleichzeitig einspeisen können, anstatt Zeile für Zeile, dass dies auch nicht funktioniert.

Ein weiterer einfacher Test, den Sie ausprobieren können, ist:

%Vor%

Wenn es funktioniert, wird es mit jeder vollen Zeile übereinstimmen, gefolgt von einer Zeilenziffer in der nächsten Zeile (der ersten Ziffer Ihres Zeitstempels).

    
CJ Dennis 27.09.2014 11:50
quelle
1

Folgende Java Regex kann helfen:

%Vor%

Aufschlüsselung:

  • 1. Erfassungsgruppe (\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2},\d{1,3})
  • 2. Erfassungsgruppe (\[.+?\])
  • 3. Erfassungsgruppe (.+?)
  • 4. Erfassungsgruppe ([\s\S]+?) .

(?=\d{4}-\d{1,2}-\d{1,2}|\Z) Positive Lookahead - Stellen Sie sicher, dass die unten stehende Regex angepasst werden kann.1. Alternative: \d{4}-\d{1,2}-\d{1,2} .2nd Alternative: \Z Position am Ende der Zeichenfolge.

Referenz Ссылка

    
Omer Sonmez 25.10.2014 09:39
quelle
0

Ich weiß nicht viel über Hive, aber die folgende Regex oder eine für Java-Strings formatierte Variante könnte funktionieren:

%Vor%

Hier sehen Sie Ihre Beispieldaten:

Ссылка

Eine Aufschlüsselung:

  • (\d{4}-\d\d-\d\d \d\d:\d\d:\d\d,\d+) Datum und Uhrzeit (Erfassungsgruppe 1)
  • \[([a-zA-Z_-]+)\] Die Protokollstufe (Erfassungsgruppe 2)
  • ([\w-]+) Die Anforderungs-ID (Erfassungsgruppe 3)
  • ((?:[^\n\r]+)(?:[\n\r]{1,2}\s[^\n\r]+)*) Die potenziell mehrzeilige Nachricht (Erfassungsgruppe 4)

Die ersten drei Capture-Gruppen sind ziemlich einfach.

Der letzte ist vielleicht etwas merkwürdig, aber er arbeitet an der Rubel. Eine Aufschlüsselung:

%Vor%

Ich habe [^\n\r] anstelle von . verwendet, weil es so aussieht, als ob RegexSerDe die . neuen Zeilen zuordnet (link ):

%Vor%

Hoffe, das hilft.

    
tiffon 30.09.2014 02:41
quelle

Tags und Links