Utilizzo di regex nell'interrogazione dei dati
È possibile utilizzare le espressioni regolari (regex) durante l'interrogazione dei dati di " IBM Cloud Logs " per la ricerca di pattern e la sostituzione di stringhe.
È possibile estrarre dati specifici dai log per facilitarne l'analisi e la visualizzazione. A volte si desidera acquisire dati specifici registrati. Altre volte, potrebbe essere necessario nascondere i dati sensibili nei registri prima che vengano salvati.
È anche possibile eseguire una corrispondenza utilizzando un modello regex anziché una ricerca di testo esatta.
Che cos’è un’espressione regolare e come funziona?
Le espressioni regolari, note anche come regex, sono un linguaggio specifico per il dominio (DSL) utilizzato per le ricerche e le sostituzioni di pattern.
Le informazioni contenute in questo argomento non intendono fornire un tutorial didattico completo sulle regex. Se non si ha familiarità con le regex, prima di cercare di capire i concetti specifici qui inclusi, si consiglia di consultare le informazioni disponibili pubblicamente sulle regex.
Concetti di Regex
Per comprendere gli esempi di questo argomento è necessario conoscere alcuni concetti di base.
- Gruppo di cattura
- Regex contenuto tra parentesi. Gli operatori vengono applicati al testo che corrisponde alla specifica all'interno delle parentesi.
- Gruppo di cattura nominato
- Un gruppo di acquisizione associato a un nome. I risultati della corrispondenza possono essere referenziati con il nome
- Classe di personaggi
- Un intervallo di caratteri da abbinare racchiuso tra parentesi quadre (
[]). Un trattino può essere usato come abbreviazione per elencare più caratteri:[1-5]è la stessa cosa di[12345].
Quando usare le regex
In alcuni casi non è necessario utilizzare un'espressione regolare e si può semplicemente cercare un testo specifico. Ad esempio, se si desidera trovare solo le righe del registro con il testo user logged in, è sufficiente inserire
questo testo nella ricerca del registro. Ma se le righe di log hanno questo aspetto: user_32 logged in non è possibile cercare il testo esatto, poiché l'ID utente è una variabile che cambia.
Fortunatamente, esiste un modello regex per questo caso che utilizza la sequenza match anything:
user_d+ logged in
Usare le regex per estrarre il testo nei campi JSON personalizzati
Si supponga di avere un registro non strutturato nel seguente formato:
${logLevel}: World-${worldName}: ${logText}
E si desidera convertire tutte le voci in questo formato in un oggetto JSON nel seguente formato:
{
"level": `${log-level}`,
"tag": `World-${worldName}`,
"text": `${logText}`
}
È possibile utilizzare questa regex per effettuare la conversione:
^(?P.*?):s*(?P.*?):
Dove:
^è il simbolo di inizio riga, significa che la corrispondenza deve iniziare con l'inizio di una riga.(?PX)doveXè l'oggetto della corrispondenza e la sintassi del gruppo di cattura con nome. Questa regex ha tre gruppi di cattura, uno per ogni chiave JSON necessaria.ssignifica "qualsiasi carattere di spazio bianco"..significa "un carattere qualsiasi".*significa "0 o più corrispondenze del simbolo o del carattere precedente"..*significa "1 o più corrispondenze del simbolo o del carattere precedente"..*?significa "qualsiasi carattere per un numero qualsiasi di volte, con il minor numero di gettoni necessari".
Quindi, la regex:
^(?P.*?):s*(?P.*?):
Verrà elaborato come segue:
-
Il testo che inizia all'inizio di una riga fino al primo simbolo
:viene catturato come gruppolevel. -
Dopo un numero qualsiasi di spazi bianchi, qualsiasi testo fino al successivo simbolo
:verrà catturato come gruppotag. -
Il testo del log viene impostato automaticamente sul campo
textda IBM Cloud Logs, quindi avremo automaticamente il campotext.
Utilizzando la stessa regex, si ottiene il seguente log:
"info: World-w-8: generate: new world"
Viene convertito in questo oggetto JSON:
{
"level": "info",
"tag": "World-w-8",
"text": "info: World-w-8: generate: new world"
}
Estrazione di testo in campi predefiniti
Si potrebbe voler estrarre il testo in campi predefiniti. Considerate questo registro:
"info: World-w-8: generate: new world"
Si potrebbe voler estrarre il testo info nella colonna Severity e il testo World nella colonna Class.
È possibile modificare la regex per impostare i nomi corretti dei gruppi di cattura come segue:
^(?P.*?):s*(?P.*?)-(?P.*?):
Questa regex formatta il log in modo che venga visualizzato come mostrato.
Estrazione di dati specifici da log strutturati
Un metodo simile può essere utilizzato per estrarre i dati dai log strutturati. Di seguito è riportato un esempio che mostra come estrarre i dati da un campo JSON specifico.
Supponiamo di avere una riga di registro strutturata in modo simile a questa:
{
"type": `${text}`,
"log": `${text}`,
"region": "rg-europe-2"
}
Ora, se il campo region ha la seguente forma:
`rg-${"europe"|"asia"|"na"}-${number}`
Vogliamo estrarre la parte che ci dice se la regione è europe, asia o na. La regex per estrarre i dati sarebbe:
"region"s*:s*"rg-(?P.*?)-
Il gruppo di cattura denominato regionName è quello che estrae il testo. Il nome della regione si trova dopo il nome della chiave region e i caratteri rg- secondo il nostro formato. Lo scopo dei simboli
s* è quello di far funzionare la regex se ci sono spazi bianchi prima o dopo il simbolo :.
Il risultato sarà simile al seguente:
{
"log" : "Bye",
"regionName" : "na",
"region" : "rg-na-1",
"type" : "ltest-w-9"
}
Sostituzione e rimozione di valori
Uno degli esempi più comuni in cui è necessario sostituire o rimuovere i valori è quello di nascondere i dati personali. Supponiamo di registrare i numeri di telefono da qualche parte e di non volerli salvare in IBM Cloud Logs.
Supponiamo di avere una riga di registro non strutturata come questa:
"info: Sender: sendSms: sending sms to phone number +12345678910 to user Andrew"
Si desidera rimuovere il numero di telefono e il nome da questa riga. Questa regex corrisponderà alla riga che inizia con "sending sms":
sending sms to phone number +*d+ to user .*
Il simbolo + deve essere preceduto da uno spazio vuoto perché + ha un significato speciale nella sintassi delle regex. Il significato è "1 o più caratteri precedenti".
Il simbolo d corrisponde a qualsiasi cifra singola. Ricordate che il simbolo * significa "0 o più caratteri precedenti". Quindi, +*d+ corrisponde a una o più cifre che possono essere precedute da un simbolo
+ (o meno).
Questa regex sostituirà il testo trovato dalla regex precedente con lo stesso testo, ma senza il numero di telefono e il nome:
sending sms to phone number * to user *
Ecco il risultato dell'applicazione della regola precedente:
"info: Sender: sendSms: sending sms to phone number * to user *"
Sostituzione dei valori JSON nei log strutturati
La sostituzione dei valori JSON nei log strutturati è simile alla sostituzione dei valori nei log non strutturati. L'intera stringa JSON viene utilizzata come input per la regola Replace.
Utilizzando la seguente struttura JSON:
{
"type": `${text}`,
"log": `${text}`,
"region": "rg-europe-2"
}
Si supponga di dover sostituire il valore del campo type con un altro valore. Ecco come si può abbinare il valore del campo type:
"type"s*:s*".*?"
Ricordate che abbiamo bisogno dei simboli s* per assicurarci che la regex funzioni se ci sono spazi bianchi prima o dopo il carattere :.
Ecco la regex per sostituire qualsiasi valore nel campo type con newType:
"type":"newType"
Utilizzo di riferimenti all'indietro
Supponiamo di dover sostituire europe con eu nelle stringhe nel formato west-europe-2. E supponiamo di doverlo fare non solo nel campo region, ma in qualsiasi altra parte del registro in cui
si trovi la stringa. La corrispondenza di questo schema è facilmente realizzabile con questa regex:
.+?-europe-d+
Tuttavia, sostituire la stringa con i metodi utilizzati in precedenza potrebbe essere piuttosto difficile. Questo perché dobbiamo inserire due stringhe prima e dopo il testo di europe e queste stringhe possono variare. Per fare
ciò, dobbiamo prima catturare le stringhe in gruppi di cattura:
(.+?)-europe-(d+)
Ricordate che il simbolo d significa "qualsiasi cifra" e insieme a + significa "qualsiasi cifra una o più volte". In modo simile, .+ indica qualsiasi simbolo una o più volte, ma con
il minor numero di gettoni per effettuare l'abbinamento.
Questa regex catturerà il testo prima di europe come gruppo di cattura 1, e il testo dopo europe come gruppo di cattura 2. La seguente regex utilizzerà i backreferences per inserire il contenuto corrispondente di questi
gruppi:
$1-eu-$2
Ad esempio, un log prima di applicare la nostra regola:
{
"log" : "Here region is east-europe-1. That's it",
"type" : "newType",
"region" : "east-europe-1"
}
E il log dopo aver applicato la regola:
{
"log" : "Here region is east-eu-1. That's it",
"type" : "newType",
"region" : "east-eu-1"
}
Ricerca con regex dalla barra di ricerca dei registri
Un altro punto in cui si possono usare le regex è la barra di ricerca della pagina IBM Cloud Logs UI Logs.
Quando si effettua una ricerca dalla barra di ricerca della pagina, è possibile inserire query di testo esatto, Lucene o Dataprime. È anche possibile cercare modelli particolari utilizzando le regex. Le query Regex hanno un formato proprio che è:
/${fieldName}.keyword:/REGEX//
Supponiamo di avere molti log strutturati in JSON nel seguente formato:
{
"log": `${text}` ,
"regionName": `${text}`,
"region": `${text}`,
"type" : `ltest-w-${number}`
}
Vogliamo trovare solo le voci in cui type è uguale a ltest-w-1, ltest-w-2 o ltest-w-3. La seguente query di ricerca è in grado di farlo:
/type.keyword:/ltest-w-[1-3]//
Il testo compreso tra le parentesi quadre [ e ], è chiamato classe di caratteri. Corrisponde a qualsiasi carattere elencato tra le parentesi quadre. Il trattino può essere usato come stenografia per elencare
diversi caratteri: [1-5] è lo stesso di [12345].
È possibile usare la stessa sintassi per abbinare i dati nei registri non strutturati con le regex. È sufficiente impostare il nome del campo su text.keyword. Ad esempio:
/text.keyword:/.*ltest-w-[1-3].*//
Questa regex cerca il testo ltest-w-1, ltest-w-2 o ltest-w-3 nel corpo del log principale.
Attivazione degli avvisi con le regex
Un altro caso d'uso popolare delle regex in IBM Cloud Logs è la definizione degli avvisi. La sintassi degli avvisi è la stessa della sintassi delle query di log.
Supponiamo di volere un avviso su una riga della seguente forma:
`App: init: World-${name}: generation error: ${err}`
E supponiamo di voler ricevere avvisi solo per i mondi w-1, w-2, w-3 o w-4. La nostra regex di avviso sarà simile a questa:
/text.keyword:/.*World-w-[1-4]: generation error.*//
Ricordate che [1-4] corrisponde a qualsiasi singolo carattere da 1 a 4, mentre .* corrisponde a qualsiasi carattere un numero qualsiasi di volte.
Per ulteriori informazioni sugli avvisi, consultare: