2017-05-08 4 views
1

ich die fluentd verwenden, um die logstash zu ersetzen, ich in-tail Plugin Schwanz der nginx access Protokoll Zugriffsprotokoll des Format verwenden wie:wie fluentd regexp verwenden, wenn die nginx schlecht Anfrage erfüllen

log_format main '$remote_addr - $remote_user [$time_local] $request ' 
'"$status" $body_bytes_sent "$http_referer" ' 
'"$http_user_agent" "$http_x_forwarded_for" $request_time'; 

die fluentd conf wie ist

format /^(?<host>\S+)\s-\s(?<user>\S+)\s\[(?<time>[^\]]*)\]\s(?<method>\S+)\s(?<url>\S+)\s(?<http_version>\S+)\s"(?<status>[^\"]+)"\s(?<bytes>\d+)\s"(?<rfc>[^\"]+)"\s"(?<agent>[^\"]+)"\s"(?<x_forward>[^\"]+)"\s(?<time_spent>\S+).*$/ 

es funktioniert gut, wenn die Anfrage korrekt ist, aber es Fehler treffen, wenn die Anforderung schlecht ist, wie folgt:

172.31.33.157 - - [08/May/2017:16:30:20 +0800] - "400" 0 "-" "-" "-" 0.000 

die schlechte Anfrage vermisse die method und rfc Feld, so dass die fluentd falsch läuft. Wie kann ich die format ändern, so dass es mir egal ist, ob die Anfrage falsch oder richtig ist?

allfällige Antworten

laufen in ein anderes Szenario zu erkennen sind, die agent oder rfc abgelegt ist keine, es Fehler läuft. genau wie

172.31.44.196 - - [08/May/2017:18:47:31 +0800] GET /click?mb_pl=ios&version=1.1 HTTP/1.1 "302" 5 "-" "" "100.38.38.149, 54.224.136.60" 0.004 

oder

172.31.44.196 - - [08/May/2017:18:47:31 +0800] GET /click?mb_pl=ios&version=1.1 HTTP/1.1 "302" 5 "" "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E304" "100.38.38.149, 54.224.136.60" 0.004 

wie dieses Szenario zu lösen?

+0

Was für eine korrekte Anfrage wie aus? –

+0

172.31.44.196 - - [08/Mai/2017: 18: 47: 31 0.800] GET /click?mb_pl=ios&version=1.1 HTTP/1.1 "302" 5 "-" „Mozilla/5.0 (iPhone, CPU iPhone OS 10_3_1 wie Mac OS X) AppleWebKit/603.1.30 (KHTML, wie Gecko) mobile/14E304" "100.38.38.149, 54.224.136.60" 0.004 –

Antwort

1

Sie können die Teile des Musters wickeln, die innerhalb optional nicht-einfangenden Gruppen sind optional, (?:...)?:

^(?<host>\S+)\s-\s(?<user>\S+)\s\[(?<time>[^\]]*)\](?:\s(?<method>\S+))?(?:\s(?<url>\S+))?\s(?<http_version>\S+)\s"(?<status>[^\"]+)"\s(?<bytes>\d+)(?:\s"(?<rfc>[^\"]+)")?\s"(?<agent>[^\"]+)"\s"(?<x_forward>[^\"]+)"\s(?<time_spent>\S+).*$ 

Siehe regex demo

Hier wickelte ich die folgenden Teile:

(?:\s(?<method>\S+))? 
(?:\s(?<url>\S+))? 
(?:\s"(?<rfc>[^\"]+)")? 

Das bedeutet, dass die gesamten Untermusterfolgen optional sind. ein Leerzeichen und die genannten Fanggruppenmuster.

Hinweis: Wenn Sie mehrere optionale Felder haben, befinden Sie sich möglicherweise in einer Situation, in der die Mustergruppen unerwünschte Teile der Eingabe abgleichen, die zu anderen Gruppen gehören. Stellen Sie in diesem Fall sicher, dass Sie die generischen Muster beschränken und optionale Muster verwenden: Ersetzen Sie + durch *, um 0 oder mehr Vorkommen anstelle von 1 oder mehr zu entsprechen, verwenden Sie optionale Gruppen wie oben gezeigt und stellen Sie sicher, dass nur die Zeichen/Muster, die erwartet werden.

ein verbessertes Muster Siehe unten:

^(?<host>\S+)\s-\s(?<user>\S+)\s\[(?<time>[^\]]*)\](?:\s(?<method>\w+))?(?:\s(?<url>\/\S+))?\s(?<http_version>\S+)\s"(?<status>\d+)"\s(?<bytes>\d+)(?:\s"(?<rfc>[^\"]*)")?(?:\s"(?<agent>[^\"]*)")?\s"(?<x_forward>[^\"]*)"\s(?<time_spent>[\d.]+).*$ 

die regex demo See.

Einige POIs hier:

  • (?<method>\w+))? - hier haben wir nur Zeichen entsprechen Wort
  • (?:\s(?<url>\/\S+))? (\S>\w, können Sie sogar mit [A-Z] betrachten) - hinzugefügt / da Ihre URLs mit / starten
  • (?<status>\d+)-\S geändert \d (da der Statuscode nur aus Ziffern besteht)
  • (?<rfc>[^\"]*)")? - die + auf * (der Wert kann leer sein)
  • (?:\s"(?<agent>[^\"]*)")? geändert - hier gilt das gleiche wie bei rfc
  • \s"(?<x_forward>[^\"]*)" - wie oben
  • (?<time_spent>[\d.]+ - der time_spent Wert enthält nur Ziffern und Punkte.
+1

Wenn Sie andere optionale Felder versuchen, das Einwickeln der '\ s' +' die subpattern' mit der optionalen nicht-Erfassungsgruppe. –