Splunk: как получить N самых последних значений для каждой группы?

#sorting #grouping #splunk

#сортировка #группировка #splunk

Вопрос:

Я боролся с этим запросом в течение нескольких часов, и кажется, что это должно быть довольно просто, но по какой-то причине я нахожу это довольно сложным. Мой клиент хочет увидеть 2 самых последних «ключа» для каждого типа клиента.

(На самом деле это верхний N — но больше, чем «первый» или «последний»)

Хотя перед шагом, о котором я спрашиваю, выполняется некоторый перевод, у меня есть данные, которые выглядят следующим образом в качестве выходных данных запроса (примечание: из-за личных причин я не могу предоставить фактические шаги выше этого, и это не реальные данные, но я думаю, что они должны быть переведены НОРМАЛЬНО). Я выделил записи, которые должны попасть в выходные данные.

 out?  clientType  key            _time
----  ----------  -------------  -----------------
 *    Mobile      asfk129458715  2020-10-13 12:10Z
 *    Online      askg259750505  2020-10-12 11:59Z
 *    Email       dh8iwwih33e99  2020-10-12 11:58Z
      Online      schf38hrnf98u  2020-10-12 11:00Z
 *    Online      vn8n34rf9v83j  2020-10-12 11:56Z
 *    Mobile      sjvn98h3idv9d  2020-10-12 11:56Z
 *    Email       92hnfi928rdh9  2020-10-12 11:55Z
 *    Fax         jkcni983iiff4  2020-10-09 06:54Z
  

Теперь я смог заставить это работать в меньшем масштабе, скажем, за 1 день. но некоторые типы клиентов встречаются не очень часто, и нам также нужно просмотреть самые последние из них. Вывод этого должен использоваться для определенных целей аудита, и я обнаружил, что когда я расширяю поиск до нескольких дней (возвращая> 10 000 событий), вывод является ошибочным, и я вижу результаты, которые не в порядке, не самые последние или иным образом искажены.

Что я хочу видеть, так это это — только верхние 2 для каждого типа клиента, отсортированные по времени убывания в каждой группе

 clientType  key            _time
----------  -------------  --------------
Mobile      asfk129458715  2020-10-13 12:10Z
Mobile      sjvn98h3idv9d  2020-10-12 11:56Z
Online      askg259750505  2020-10-12 11:59Z
Online      vn8n34rf9v83j  2020-10-12 11:56Z
Email       dh8iwwih33e99  2020-10-12 11:58Z
Email       92hnfi928rdh9  2020-10-12 11:55Z
Fax         jkcni983iiff4  2020-10-09 06:54Z
  

для некоторых «что я пробовал» я пытался использовать некоторый код запроса в разных порядках, в основном вращающихся вокруг stats list(key) sort 0 -_time и т.д., с различными предложениями «by». Выходные данные этого запроса также будут подвергнуты некоторому дополнительному преобразованию для использования в нашей системе аудита, которая принимает список ключей, каждый из которых заключен в одинарные кавычки и разделен запятыми.

Я использовал stats delim="','" и mvcombine с некоторым успехом на этом этапе запроса, чтобы получить результаты, которые в конечном итоге выглядят так. Я хотел включить это как часть вопроса, чтобы было ясно, как должно выглядеть конечное состояние, на случай, если что-то нужно изменить где-то в разделе группировки и сортировки, чтобы упростить задачу.

 clientType  keys           
----------  -------------
Mobile      'asfk129458715','sjvn98h3idv9d'
Online      'askg259750505','vn8n34rf9v83j'
Email       'dh8iwwih33e99','92hnfi928rdh9'
Fax         'jkcni983iiff4'
  

Ответ №1:

Чтобы получить два (или «N») самых последних события по определенному полю, сначала выполните сортировку по времени, а затем используйте dedup команду для выбора первых N результатов.

 <your query>
| sort - _time
| dedup 2 clientType
  

Ответ №2:

Хотя dedup вариант @RichG может работать, вот тот, который использует stats и mvindex :

 index=ndx sourcetype=srctp clientType=* key=*
| eval comb=_time " | " key
| stats values(comb) as comb by clientType
  

Использование mvindex в форме диапазона вместо выбора только последнего элемента

 | eval mostrecents=mvindex(comb,-1-N,-1)
  

(Конечно, подзаголовок для N всего, что вам нужно)

 | fields - comb
| mvexpand mostrecents
| rex field=mostrecent "(?<timemost>d )s|s(?<keymost>. )"
| table clientType timemost keymost
| eval timemost=strftime(timemost,"%c")
  

Комментарии:

1. Это может сработать для случая, когда N = 2, я считаю, что ответ RichG действительно удовлетворяет требованию [(На самом деле это top N), но больше, чем «первый» или «последний»)]

2. @user10946195 — Я отредактировал вопрос, чтобы отразить ваше желание, чтобы он был не просто «2 самых последних»

3. @user10946195 — обратите внимание на изменения в ответе, отражающие изменения, о которых идет речь