Tipps und Fehlerbehebung beim Schreiben von Parsern
In diesem Dokument werden Probleme beschrieben, die beim Schreiben von Parsercode auftreten können.
Beim Schreiben von Parsercode können Fehler auftreten, wenn Parsing-Anweisungen nicht wie erwartet funktionieren. Mögliche Fehlersituationen:
- Ein
Grok
-Muster schlägt fehl - Ein
rename
- oderreplace
-Vorgang schlägt fehl - Syntaxfehler im Parsercode
Häufige Praktiken im Parsercode
In den folgenden Abschnitten werden die Best Practices, Tipps und Lösungen beschrieben. um Ihnen bei der Fehlerbehebung zu helfen.
Vermeiden Sie die Verwendung von Punkten oder Bindestrichen in Variablennamen
Die Verwendung von Bindestrichen und Punkten
in Variablennamen kann zu unerwartetem Verhalten führen.
häufig bei merge
-Vorgängen zum Speichern von Werten in UDM-Feldern. Möglicherweise treten auch zeitweise Parsing-Probleme auf.
Verwenden Sie beispielsweise folgende Variablennamen nicht:
my.variable.result
my-variable-result
Verwenden Sie stattdessen den folgenden Variablennamen: my_variable_result
.
Verwenden Sie keine Begriffe mit besonderer Bedeutung als Variablennamen.
Bestimmte Wörter wie event
und timestamp
können im Parser eine besondere Bedeutung haben
Code.
Der String event
wird häufig für einen einzelnen UDM-Eintrag verwendet und in folgenden Fällen verwendet:
Die @output
-Anweisung. Eine Lognachricht enthält ein Feld mit dem Namen event
oder
wenn Sie eine Zwischenvariable namens event
definieren und die
wenn der Parsercode das Wort event
in der @output
-Anweisung verwendet, erhältst du
erhalten Sie eine Fehlermeldung zu einem Namenskonflikt.
Benennen Sie die Zwischenvariable in einen anderen Namen um oder verwenden Sie den Begriff event1
wie
ein Präfix in UDM-Feldnamen und in der @output
-Anweisung.
Das Wort timestamp
steht für den erstellten Zeitstempel des ursprünglichen Rohlogs. A
wird der in dieser Zwischenvariablen festgelegte Wert im
UDM-Feld „metadata.event_timestamp
“. Der Begriff @timestamp
steht für das Datum
und die Zeit, zu der das Rohlog geparst wurde, um einen UDM-Eintrag zu erstellen.
Im folgenden Beispiel wird das UDM-Feld metadata.event_timestamp
auf das Datum gesetzt.
und die Zeit, zu der das
Rohprotokoll geparst wurde.
# Save the log parse date and time to the timestamp variable
mutate {
rename => {
"@timestamp" => "timestamp"
}
}
Im folgenden Beispiel wird das UDM-Feld metadata.event_timestamp
auf das Datum und
Zeit, die aus dem ursprünglichen Rohprotokoll extrahiert und in der Zwischendatei when
gespeichert wird
.
# Save the event timestamp to timestamp variable
mutate {
rename => {
"when" => "timestamp"
}
}
Folgende Begriffe dürfen nicht als Variablen verwendet werden:
- CollectionZeitstempel
- createtimestamp
- event
- filename
- Nachricht
- Namespace
- Ausgabe
- onerrorcount
- timestamp
- Zeitzone
Speichern Sie jeden Datenwert in einem separaten UDM-Feld
Speichern Sie mehrere Felder nicht in einem einzelnen UDM-Feld, indem Sie sie mit einem Trennzeichen. Hier ein Beispiel:
"principal.user.first_name" => "first:%{first_name},last:%{last_name}"
Speichern Sie stattdessen jeden Wert in einem separaten UDM-Feld.
"principal.user.first_name" => "%{first_name}"
"principal.user.last_name" => "%{last_name}"
Verwenden Sie im Code Leerzeichen statt Tabulatoren
Verwenden Sie im Parsercode keine Tabulatoren. Verwenden Sie nur Leerzeichen und rücken Sie jeweils zwei Leerzeichen ein.
Nicht mehrere Zusammenführungsaktionen in einem Vorgang ausführen
Wenn Sie mehrere Felder in einem Vorgang zusammenführen, kann dies zu
uneinheitliche Ergebnisse. Platzieren Sie merge
-Anweisungen stattdessen in separate
Geschäftsabläufe.
Ersetzen Sie beispielsweise das folgende Beispiel:
mutate {
merge => {
"security_result.category_details" => "category_details"
"security_result.category_details" => "super_category_details"
}
}
durch diesen Codeblock:
mutate {
merge => {
"security_result.category_details" => "category_details"
}
}
mutate {
merge => {
"security_result.category_details" => "super_category_details"
}
}
Bedingte Ausdrücke if
und if else
auswählen
Wenn der bedingte Wert,
den Sie testen möchten, immer nur eine
Verwenden Sie dann die bedingte if else
-Anweisung. Dieser Ansatz ist etwas stärker
effizient zu gestalten. Wenn Sie jedoch ein Szenario haben, bei dem der getestete Wert mehr
als einmal verwenden, verwenden Sie mehrere unterschiedliche if
-Anweisungen und ordnen Sie die Anweisungen
vom allgemeinsten zum spezifischsten Fall.
Wählen Sie einen repräsentativen Satz von Protokolldateien aus, um Parseränderungen zu testen
Eine bewährte Methode besteht darin, Parsercode mithilfe von Rohlogbeispielen mit einer umfassenden in verschiedenen Formaten. So können Sie eindeutige Logs oder Grenzfälle ermitteln, die der Parser möglicherweise verarbeiten muss.
Beschreibende Kommentare zum Parsercode hinzufügen
Fügen Sie dem Parsercode Kommentare hinzu, die erklären, warum die Anweisung wichtig ist, als das, was die Anweisung tut. Der Kommentar hilft allen, die den Parser verwalten um dem Ablauf zu folgen. Hier ein Beispiel:
# only assign a Namespace if the source address is RFC 1918 or Loopback IP address
if [jsonPayload][id][orig_h] =~ /^(127(?:\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\{3\}$)|(10(?:\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\{3\}$)|(192\.168(?:\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\{2\}$)|(172\.(?:1[6-9]|2\d|3[0-1])(?:\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\{2\}$)/ {
mutate {
replace => {
"event1.idm.read_only_udm.principal.namespace" => "%{resource.labels.project_id}"
}
}
}
Zwischenvariablen frühzeitig initialisieren
Initialisieren Sie die Zwischendatei, bevor Sie Werte aus dem ursprünglichen Rohlog extrahieren. Variablen, die zum Speichern von Testwerten verwendet werden.
Dadurch wird verhindert, dass ein Fehler zurückgegeben wird, der darauf hinweist, dass die Zwischenvariable existiert nicht.
Mit der folgenden Anweisung wird der Wert in der Variablen product
das UDM-Feld metadata.product_name
.
mutate{
replace => {
"event1.idm.read_only_udm.metadata.product_name" => "%{product}"
}
}
Wenn die Variable product
nicht vorhanden ist, wird der folgende Fehler angezeigt:
"generic::invalid_argument: pipeline failed: filter mutate (4) failed: replace failure: field \"event1.idm.read_only_udm.metadata.product_name\": source field \"product\": field not set"
Sie können eine on_error
-Anweisung hinzufügen, um den Fehler abzufangen. Hier ein Beispiel:
mutate{
replace => {
"event1.idm.read_only_udm.metadata.product_name" => "%{product}"
}
on_error => "_error_does_not_exist"
}
Mit der vorherigen Beispielanweisung wird der Parsing-Fehler erfolgreich in einen
boolesche Zwischenvariable namens _error_does_not_exist
. Nicht
ermöglichen Ihnen die Verwendung der Variable product
in einer bedingten Anweisung, z. B. if
.
Hier ein Beispiel:
if [product] != "" {
mutate{
replace => {
"event1.idm.read_only_udm.metadata.product_name" => "%{product}"
}
}
on_error => "_error_does_not_exist"
}
Im vorherigen Beispiel wird der folgende Fehler zurückgegeben, da die Bedingungsklausel if
unterstützt keine on_error
-Anweisungen:
"generic::invalid_argument: pipeline failed: filter conditional (4) failed: failed to evaluate expression: generic::invalid_argument: "product" not found in state data"
Um dieses Problem zu lösen, fügen Sie einen separaten Anweisungsblock hinzu, der die
Variablen vor dem Ausführen der Extraktionsfilteranweisungen (json
, csv
, xml
, kv
oder grok
) hinzu.
Folgendes ist ein Beispiel.
filter {
# Initialize intermediate variables for any field you will use for a conditional check
mutate {
replace => {
"timestamp" => ""
"does_not_exist" => ""
}
}
# load the logs fields from the message field
json {
source => "message"
array_function => "split_columns"
on_error => "_not_json"
}
}
Das aktualisierte Snippet des Parsercodes verarbeitet die verschiedenen Szenarien mithilfe eines
bedingte Anweisung, um zu prüfen, ob das Feld vorhanden ist. Darüber hinaus enthält der
Mit der on_error
-Anweisung werden mögliche Fehler verarbeitet.
SHA-256 in base64 konvertieren
Im folgenden Beispiel wird der SHA-256-Wert extrahiert, in base64 codiert und der codierten Daten in einen hexadezimalen String um und ersetzt dann bestimmte Felder durch die extrahierten und verarbeiteten Werte.
if [Sha256] != ""
{
base64
{
encoding => "RawStandard"
source => "Sha256"
target => "base64_sha256"
on_error => "base64_message_error"
}
mutate
{
convert =>
{
"base64_sha256" => "bytestohex"
}
on_error => "already_a_string"
}
mutate
{
replace =>
{
"event.idm.read_only_udm.network.tls.client.certificate.sha256" => "%{base64_sha256}"
"event.idm.read_only_udm.target.resource.name" => "%{Sha256}"
}
}
}
Fehler in Parser-Anweisungen verarbeiten
Eingehende Protokolle können ein unerwartetes Protokollformat haben oder schlecht formatierte Daten enthalten.
Sie können den Parser so erstellen, dass diese Fehler behandelt werden. Es empfiehlt sich,
on_error
-Handler in den Extraktionsfilter und dann
die Zwischenvariable testen, bevor Sie mit dem nächsten Segment der Parserlogik fortfahren.
Im folgenden Beispiel wird der Extraktionsfilter json
mit einem on_error
verwendet
, um die boolesche Variable _not_json
festzulegen. Wenn _not_json
auf
true
bedeutet dies, dass der eingehende Logeintrag nicht im gültigen JSON-Format vorkam und der
Logeintrag wurde nicht erfolgreich geparst. Wenn die Variable _not_json
false
ist,
Der eingehende Logeintrag hatte ein gültiges JSON-Format.
# load the incoming log from the default message field
json {
source => "message"
array_function => "split_columns"
on_error => "_not_json"
}
Sie können auch testen, ob ein Feld das richtige Format hat. Im folgenden Beispiel
Prüft, ob _not_json
auf true
gesetzt ist. Dies weist darauf hin, dass das Log nicht im
erwartete Format.
# Test that the received log matches the expected format
if [_not_json] {
drop { tag => "TAG_MALFORMED_MESSAGE" }
} else {
# timestamp is always expected
if [timestamp] != "" {
# ...additional parser logic goes here …
} else {
# if the timestamp field does not exist, it's not a log source
drop { tag => "TAG_UNSUPPORTED" }
}
}
Dadurch wird sichergestellt, dass das Parsen nicht fehlschlägt, wenn Logs mit einem falschen Format aufgenommen werden. für den angegebenen Logtyp.
Verwenden Sie den Filter drop
mit der Variablen tag
, damit die Bedingung im
Tabelle mit Aufnahmemesswerten in BigQuery.
TAG_UNSUPPORTED
TAG_MALFORMED_ENCODING
TAG_MALFORMED_MESSAGE
TAG_NO_SECURITY_VALUE
Der Filter drop
verhindert, dass der Parser das Rohlog verarbeitet und die Felder normalisiert.
und einen UDM-Eintrag erstellen. Das ursprüngliche Rohlog wird weiterhin in Google Security Operations aufgenommen
und können mit der Rohprotokollsuche in Google Security Operations durchsucht werden.
Der an die Variable tag
übergebene Wert wird im drop_reason_code
gespeichert: im Feld
Tabelle mit Aufnahmemesswerten. Sie können eine Ad-hoc-Abfrage für die Tabelle wie folgt ausführen:
SELECT
log_type,
drop_reason_code,
COUNT(drop_reason_code) AS count
FROM `datalake.ingestion_metrics`
GROUP BY 1,2
ORDER BY 1 ASC
Validierungsfehler beheben
Beim Erstellen eines Parsers können bei der Validierung Fehler auftreten, Beispiel: Im UDM-Eintrag wurde kein Pflichtfeld festgelegt. Der Fehler könnte etwa so aussehen: Folgendes:
Error: generic::unknown: invalid event 0: LOG_PARSING_GENERATED_INVALID_EVENT: "generic::invalid_argument: udm validation failed: target field is not set"
Der Parsercode wird erfolgreich ausgeführt, der generierte UDM-Eintrag jedoch nicht
Schließt alle erforderlichen UDM-Felder ein, wie durch den Wert definiert, der auf metadata.event_type
gesetzt ist. Die
Im Folgenden finden Sie weitere Beispiele, die diesen Fehler verursachen können:
- Wenn
metadata.event_type
den WertUSER_LOGIN
hat und das UDM-Feldtarget.user value
nicht festgelegt ist. - Wenn
metadata.event_type
NETWORK_CONNECTION
ist und dertarget.hostname
UDM-Feld ist nicht festgelegt.
Weitere Informationen zum UDM-Feld „metadata.event_type
“ und zum Pflichtfeld
finden Sie im Leitfaden zur Verwendung von UMs.
Eine Möglichkeit zur Behebung dieses Fehlertyps besteht darin, zuerst statische Werte auf UDM festzulegen. . Nachdem Sie alle erforderlichen UDM-Felder definiert haben, prüfen Sie das ursprüngliche Rohlog, um zu sehen, welche Werte zum Parsen und Speichern im UDM-Eintrag. Wenn das ursprüngliche Rohprotokoll bestimmte Felder enthalten, müssen Sie ggf. Standardwerte festlegen.
Es folgt eine Beispielvorlage, die für den Ereignistyp USER_LOGIN
spezifisch ist und die
veranschaulicht diesen Ansatz.
Beachten Sie Folgendes:
- Die Vorlage initialisiert Zwischenvariablen und legt jede auf einen statischen String fest.
- Mit dem Code im Abschnitt Feldzuweisung werden die Werte in Zwischenvariablen festgelegt. zu UDM-Feldern.
Sie können diesen Code erweitern, indem Sie zusätzliche Zwischenvariablen und UDM-Felder hinzufügen. Nachdem Sie alle UDM-Felder identifiziert haben, die ausgefüllt werden müssen, gehen Sie so vor:
Fügen Sie im Abschnitt Eingabekonfiguration Code hinzu, mit dem Felder aus das ursprüngliche Rohprotokoll und legt die Werte auf die Zwischenvariablen fest.
Fügen Sie im Abschnitt Datum extrahieren Code hinzu, der den Zeitstempel des Ereignisses extrahiert. aus dem ursprünglichen Rohlog, transformiert es und legt es auf die Zwischenvariable fest.
Ersetzen Sie bei Bedarf den initialisierten Wert, der in jeder Zwischenvariablen festgelegt wurde, durch einen leeren String.
filter {
mutate {
replace => {
# UDM > Metadata
"metadata_event_timestamp" => ""
"metadata_vendor_name" => "Example"
"metadata_product_name" => "Example SSO"
"metadata_product_version" => "1.0"
"metadata_product_event_type" => "login"
"metadata_product_log_id" => "12345678"
"metadata_description" => "A user logged in."
"metadata_event_type" => "USER_LOGIN"
# UDM > Principal
"principal_ip" => "192.168.2.10"
# UDM > Target
"target_application" => "Example Connect"
"target_user_user_display_name" => "Mary Smith"
"target_user_userid" => "mary@example.com"
# UDM > Extensions
"auth_type" => "SSO"
"auth_mechanism" => "USERNAME_PASSWORD"
# UDM > Security Results
"securityResult_action" => "ALLOW"
"security_result.severity" => "LOW"
}
}
# ------------ Input Configuration --------------
# Extract values from the message using one of the extraction filters: json, kv, grok
# ------------ Date Extract --------------
# If the date {} function is not used, the default is the normalization process time
# ------------ Field Assignment --------------
# UDM Metadata
mutate {
replace => {
"event1.idm.read_only_udm.metadata.vendor_name" => "%{metadata_vendor_name}"
"event1.idm.read_only_udm.metadata.product_name" => "%{metadata_product_name}"
"event1.idm.read_only_udm.metadata.product_version" => "%{metadata_product_version}"
"event1.idm.read_only_udm.metadata.product_event_type" => "%{metadata_product_event_type}"
"event1.idm.read_only_udm.metadata.product_log_id" => "%{metadata_product_log_id}"
"event1.idm.read_only_udm.metadata.description" => "%{metadata_description}"
"event1.idm.read_only_udm.metadata.event_type" => "%{metadata_event_type}"
}
}
# Set the UDM > auth fields
mutate {
replace => {
"event1.idm.read_only_udm.extensions.auth.type" => "%{auth_type}"
}
merge => {
"event1.idm.read_only_udm.extensions.auth.mechanism" => "auth_mechanism"
}
}
# Set the UDM > principal fields
mutate {
merge => {
"event1.idm.read_only_udm.principal.ip" => "principal_ip"
}
}
# Set the UDM > target fields
mutate {
replace => {
"event1.idm.read_only_udm.target.user.userid" => "%{target_user_userid}"
"event1.idm.read_only_udm.target.user.user_display_name" => "%{target_user_user_display_name}"
"event1.idm.read_only_udm.target.application" => "%{target_application}"
}
}
# Set the UDM > security_results fields
mutate {
merge => {
"security_result.action" => "securityResult_action"
}
}
# Set the security result
mutate {
merge => {
"event1.idm.read_only_udm.security_result" => "security_result"
}
}
# ------------ Output the event --------------
mutate {
merge => {
"@output" => "event1"
}
}
}
Unstrukturierten Text mit einer Grok-Funktion parsen
Wenn Sie mit einer Grok-Funktion Werte aus unstrukturiertem Text extrahieren,
vordefinierte Grok-Muster und Anweisungen für reguläre Ausdrücke verwenden. Grok-Muster
damit der Code leichter zu lesen ist. Wenn der reguläre Ausdruck keine Kurzschreibweise enthält
Zeichen (z. B. \w
oder \s
) können Sie die Anweisung direkt kopieren und einfügen.
in den Parsercode ein.
Da Grok-Muster eine zusätzliche Abstraktionsebene in der Anweisung darstellen, können sie die Fehlerbehebung bei einem Fehler komplexer. Hier ein Beispiel Grok-Funktion, die sowohl vordefinierte Grok-Muster als auch reguläre Ausdrücke enthält.
grok {
match => {
"message" => [
"%{NUMBER:when}\\s+\\d+\\s%{SYSLOGHOST:srcip} %{WORD:action}\\/%{NUMBER:returnCode} %{NUMBER:size} %{WORD:method} (?P<url>\\S+) (?P<username>.*?) %{WORD}\\/(?P<tgtip>\\S+).*"
]
}
}
Eine Extraktionsanweisung ohne Grok-Muster kann leistungsstärker sein. Für dass im folgenden Beispiel weniger als die Hälfte der Verarbeitungsschritte für eine Übereinstimmung erforderlich ist. Bei einer Logquelle mit potenziell hohem Volumen ist dies eine wichtige Überlegung.
Unterschiede zwischen regulären RE2- und PCRE-Ausdrücken verstehen
Google Security Operations-Parser verwenden RE2 als reguläre Ausdrücke. Wenn Sie mit der PCRE-Syntax vertraut sind, Unterschiede wahrnehmen. Hier ein Beispiel:
Das ist eine PCRE-Anweisung: (?<_custom_field>\w+)\s
Im Folgenden finden Sie eine RE2-Anweisung für den Parsercode: (?P<_custom_field>\\w+)\\s
Achten Sie darauf, die Escape-Zeichen zu maskieren.
Google Security Operations speichert eingehende Logrohdaten im JSON-codierten Format. Damit möchten wir
Zeichenzeichenfolgen, bei denen es sich offenbar um Abkürzungen für reguläre Ausdrücke handelt
als literaler String interpretiert. Beispiel: \t
wird als
anstelle eines Tabulatorzeichens.
Das folgende Beispiel zeigt ein Original-Rohlog und das JSON-codierte Format-Log.
Beachten Sie das Escape-Zeichen, das vor jedem umgekehrten Schrägstrich hinzugefügt wird.
rund um den Begriff entry
.
Hier sehen Sie das ursprüngliche Rohlog:
field=\entry\
Im Folgenden sehen Sie das Log, das in das JSON-codierte Format konvertiert wurde:
field=\\entry\\
Bei Verwendung eines regulären Ausdrucks im Parsercode müssen Sie ein zusätzliches Escapezeichen hinzufügen. Zeichen, wenn Sie nur den Wert extrahieren möchten. Um einen umgekehrten Schrägstrich in des ursprünglichen Rohprotokolls in der Extraktionsanweisung vier umgekehrte Schrägstriche.
Im Folgenden finden Sie einen regulären Ausdruck für Parsercode:
^field=\\\\(?P<_value>.*)\\\\$
Im Folgenden sehen Sie das generierte Ergebnis. Die benannte Gruppe _value
speichert den Begriff entry
:
"_value": "entry"
Wenn Sie eine standardmäßige Anweisung für einen regulären Ausdruck in den Parsercode verschieben, maskieren Sie
Kurzzeichen für reguläre Ausdrücke in der Extraktionsanweisung.
Ändern Sie beispielsweise \s
in \\s
.
Lassen Sie Sonderzeichen für reguläre Ausdrücke unverändert, wenn sie im Feld
Extraktionsanweisung. Beispielsweise bleibt \\
unverändert als \\
.
Im Folgenden sehen Sie einen standardmäßigen regulären Ausdruck:
^.*?\\\"(?P<_user>[^\\]+)\\\"\s(?:(logged\son|logged\soff))\s.*?\\\"(?P<_device>[^\\]+)\\\"\.$
Der folgende reguläre Ausdruck wird so geändert, dass er im Parsercode funktioniert.
^.*?\\\"(?P<_user>[^\\\\]+)\\\"\\s(?:(logged\\son|logged\\soff))\\s.*?\\\"(?P<_device>[^\\\\]+)\\\"\\.$
In der folgenden Tabelle wird zusammengefasst, wann ein regulärer regulärer Ausdruck Folgendes enthalten muss: zusätzliche Escape-Zeichen ein, bevor sie in den Parsercode aufgenommen werden.
Regulärer Ausdruck | Geänderter regulärer Ausdruck für Parsercode | Beschreibung der Änderung |
---|---|---|
\s |
\\s |
Kürzel müssen maskiert werden. |
\. |
\\. |
Reservierte Zeichen müssen maskiert werden. |
\\" |
\\\" |
Reservierte Zeichen müssen maskiert werden. |
\] |
\\] |
Reservierte Zeichen müssen maskiert werden. |
\| |
\\| |
Reservierte Zeichen müssen maskiert werden. |
[^\\]+ |
[^\\\\]+ |
Sonderzeichen in einer Zeichenklassengruppe müssen ist entkommen. |
\\\\ |
\\\\ |
Sonderzeichen außerhalb einer Zeichenklassengruppe oder Für Kurzzeichen ist kein zusätzliches Escape-Zeichen erforderlich. |
Reguläre Ausdrücke müssen eine benannte Erfassungsgruppe enthalten
Ein regulärer Ausdruck wie "^.*$"
ist eine gültige RE2-Syntax. Im Parser
Code schlägt er mit dem folgenden Fehler fehl:
"ParseLogEntry failed: pipeline failed: filter grok (0) failed: failed to parse data with all match
patterns"
Sie müssen dem Ausdruck eine gültige Erfassungsgruppe hinzufügen. Bei Verwendung von Grok enthalten diese standardmäßig eine benannte Erfassungsgruppe. Bei Verwendung der regulären Ausdrucksüberschreibungen enthalten, müssen Sie eine benannte Gruppe einfügen.
Hier sehen Sie ein Beispiel für einen regulären Ausdruck im Parsercode:
"^(?P<_catchall>.*$)"
Im Folgenden finden Sie das Ergebnis mit dem Text, der der benannten Gruppe _catchall
zugewiesen ist.
"_catchall": "User \"BOB\" logged on to workstation \"DESKTOP-01\"."
Verwenden Sie eine universelle benannte Gruppe, um mit dem Erstellen des Ausdrucks zu beginnen
Beginnen Sie beim Erstellen einer Extraktionsanweisung mit einem Ausdruck, der die mehr als Sie möchten. Erweitern Sie dann den Ausdruck um ein Feld nach dem anderen.
Im folgenden Beispiel wird zuerst eine benannte Gruppe (_catchall
) verwendet, die mit
der gesamten Nachricht. Anschließend wird der Ausdruck in Schritten erstellt, indem er
zusätzliche Teile des Textes. Bei jedem Schritt hat die benannte Gruppe _catchall
enthält weniger vom Originaltext. Fahren Sie fort und iterieren Sie Schritt für Schritt,
mit der Nachricht abgleichen, bis Sie die benannte Gruppe _catchall
nicht mehr benötigen.
Schritt | Regulärer Ausdruck im Parsercode | Ausgabe der benannten Erfassungsgruppe _catchall |
---|---|---|
1 | "^(?P<_catchall>.*$)" |
User \"BOB\" logged on to workstation \"DESKTOP-01\". |
2 | ^User\s\\\"(?P<_catchall>.*$) |
BOB\" logged on to workstation \"DESKTOP-01\". |
3 | ^User\s\\\"(?P<_user>.*?)\\\"\s(?P<_catchall>.*$) |
logged on to workstation \"DESKTOP-01\". |
Fahren Sie fort, bis der Ausdruck mit der gesamten Textzeichenfolge übereinstimmt. |
Escapezeichen für Kurzzeichen im regulären Ausdruck
Denken Sie daran, Escape-Zeichen für reguläre Ausdrücke zu maskieren, wenn Sie die Methode
Ausdruck im Parser-Code. Es folgt ein Beispiel für eine Textzeichenfolge und den
Standardausdruck mit regulärem Ausdruck zum Extrahiert das erste Wort, This
.
This is a sample log.
Mit dem folgenden regulären regulären Ausdruck wird das erste Wort, This
, extrahiert.
Wenn Sie diesen Ausdruck jedoch im Parsercode ausführen, fehlt im Ergebnis der Buchstabe
s
Regulärer Ausdruck (Standardausdruck) | Ausgabe der benannten Erfassungsgruppe _firstWord |
---|---|
"^(?P<_firstWord>[^\s]+)\s.*$" |
"_firstWord": "Thi", |
Das liegt daran, dass reguläre Ausdrücke im Parsercode ein zusätzliches Escapezeichen erfordern.
-Zeichen zu Kurzzeichen hinzugefügt. Im vorherigen Beispiel muss \s
in \\s
geändert werden.
Überarbeiteter regulärer Ausdruck für Parsercode | Ausgabe der benannten Erfassungsgruppe _firstWord |
---|---|
"^(?P<_firstWord>[^\\s]+)\\s.*$" |
"_firstWord": "This", |
Dies gilt nur für Kurzzeichen wie \s
, \r
und \t
.
Andere Zeichen wie `` müssen nicht weiter mit Escapezeichen versehen werden.
Vollständiges Beispiel
In diesem Abschnitt werden die vorherigen Regeln als End-to-End-Beispiel beschrieben. Hier ist ein unstrukturierte Textzeichenfolge und der reguläre reguläre Ausdruck, der zum Parsen geschrieben wurde die Zeichenfolge. Schließlich enthält sie den modifizierten regulären Ausdruck, der im Parser-Code enthalten.
Im Folgenden sehen Sie die ursprüngliche Textzeichenfolge.
User "BOB" logged on to workstation "DESKTOP-01".
Im Folgenden finden Sie einen regulären regulären Ausdruck für RE2, der den Textstring parst.
^.*?\\\"(?P<_user>[^\\]+)\\\"\s(?:(logged\son|logged\soff))\s.*?\\\"(?P<_device>[^\\]+)\\\"\.$
Mit diesem Ausdruck werden die folgenden Felder extrahiert.
Übereinstimmungsgruppe | Zeichenposition | Textstring |
---|---|---|
Vollständige Übereinstimmung | 0-53 | User \"BOB\" logged on to workstation \"DESKTOP-01\". |
Gruppe „_user“ | 7-10 | BOB |
Gruppe 2: | 13-22 | logged on |
Gruppe „_device“ | 40-50 | DESKTOP-01 |
Dies ist der geänderte Ausdruck. Der reguläre reguläre Ausdruck „RE2“ wurde geändert, damit er im Parsercode funktioniert.
^.*?\\\"(?P<_user>[^\\\\]+)\\\"\\s(?:(logged\\son|logged\\soff))\\s.*?\\\"(?P<_device>[^\\\\]+)\\\"\\.$