Splunk Rex: извлечение повторяющихся ключей и значений в таблицу - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть несколько журналов в Splunk, для которых я пытаюсь извлечь несколько значений. Мои записи в журнале выглядят так:

host-03.company.local:9011[read 3617, write 120 bytes] host-05.company.local:9011[read 370658827, write 177471 bytes] host-07.company.local:9011[read 99, write 96 bytes] host-07.company.local:9011[read 96, write 96 bytes] host-05.company.local:9011[read 120, write 120 bytes] host-05.company.local:9011[read 120, write 120 bytes] host-03.company.local:9015[read 42955, write 120 bytes] host-05.company.local:9015[read 3048879, write 86677386 bytes] host-02.company.local:7035[read 120, write 120 bytes] host-03.company.local:9015[read 120, write 120 bytes] host-05.company.local:9015[read 809077, write 120 bytes] host-02.company.local:7035[read 120, write 120 bytes] host-03.company.local:9015[read 120, write 120 bytes] host-05.company.local:9015[read 120, write 120 bytes] host-02.company.local:7035[read 120, write 120 bytes]

Шаблон, по которому следуют эти записи журнала: host:port[read xxx, write yyy bytes]

В этой строке журнала может быть от 1 до 20 записей хоста.

В Splunk я надеюсь извлечь эти поля из таблицы так, чтобы результат выглядел следующим образом:

hostname                   readBytes WriteBytes
-----------------------------------------------
host-03.company.local:9011      3617        120
host-05.company.local:9011 370658827     177471
host-07.company.local:9011        99         96
host-05.company.local:9011       120        120

Logi c, здесь я извлекаю записи read и write для каждого хоста, так что каждый из них становится строкой в ​​этой таблице.

Я добился определенного прогресса в извлечении хостов с помощью rex:

index=myApplication <mySearch>
  | rex field=_raw "(?<hostsTmp>([a-zA-Z0-9\-\.]+:[0-9]+))"
  | table hostsTmp

Однако даже этот результат кажется неправильным, некоторые результаты - просто пустые строки. Кроме того, поле hostsTemp не является многопараметрическим полем. mvcount (hostsTemp) ничего не возвращает для каждой записи.

mvcount(hostsTmp)   len(hostsTmp)   hostsTmp
--------------------------------------------
    -                    -          host-05.company.local:9011
    -                    -          -
    -                    -          host-05.company.local:9011
    -                    -          -
    -                    -          host-05.company.local:9011
    -                    -          -

Обратите внимание, что здесь я использую символ - для обозначения недостатка данных в моей таблице. Каждая вторая строка просто пуста, а значения mvcount и len для hostsTmp всегда пусты.

Относительно новичок в Splunk и не является экспертом по регулярным выражениям, поэтому любая помощь приветствуется.

1 Ответ

1 голос
/ 11 февраля 2020

Я предлагаю разделить результаты каждого хоста на отдельное событие, а затем выполнить rex для каждого события.

Это займет ваше полное событие и создаст поле с несколькими значениями (с именем ev) для каждого из ваших хостов и их данных.

| eval ev=split(raw,"]")
| mvexpand ev

Затем для извлечения данных можно использовать простой rex.

| rex field=ev "^\s*(?<hostname>[^\[]+)\[read\s+(?<readBytes>\d+),\s+write\s+(?<writeBytes>\d+)\s+bytes"

И использовать table отформатировать его соответствующим образом.

| table hostname readBytes writeBytes

Вот пример, демонстрирующий его работу. Возможно, вам придется изменить split(raw, чтобы он указывал на поле в вашем собственном событии, или использовать _raw.

| makeresults | eval raw="host-03.company.local:9011[read 3617, write 120 bytes] host-05.company.local:9011[read 370658827, write 177471 bytes] host-07.company.local:9011[read 99, write 96 bytes] host-07.company.local:9011[read 96, write 96 bytes] host-05.company.local:9011[read 120, write 120 bytes] host-05.company.local:9011[read 120, write 120 bytes] host-03.company.local:9015[read 42955, write 120 bytes] host-05.company.local:9015[read 3048879, write 86677386 bytes] host-02.company.local:7035[read 120, write 120 bytes] host-03.company.local:9015[read 120, write 120 bytes] host-05.company.local:9015[read 809077, write 120 bytes] host-02.company.local:7035[read 120, write 120 bytes] host-03.company.local:9015[read 120, write 120 bytes] host-05.company.local:9015[read 120, write 120 bytes] host-02.company.local:7035[read 120, write 120 bytes]"
| eval ev=split(raw,"]")
| mvexpand ev
| rex field=ev "^\s*(?<hostname>[^\[]+)\[read\s+(?<readBytes>\d+),\s+write\s+(?<writeBytes>\d+)\s+bytes"
| table hostname readBytes writeBytes
...