Как сделать минус-операцию на отметках времени в asticsearch?

У меня есть некоторые журналы сервера, сброшенные в asticsearch. Журналы содержат записи, такие как 'action_id':'AU11nP1mYXS3pt6INMtU','action':'start','time':'March 31st 2015, 19:42:07.121' а также 'action_id':'AU11nP1mYXS3pt6INMtU','action':'complete','time':'March 31st 2015, 23:06:00.271', Идентичный action_id относится к одному действию, и меня интересует, сколько времени потребовалось для завершения действия.

Я на самом деле не знаю, как изобразить свой вопрос, чтобы задать вопрос, но постараюсь изо всех сил: как сделать агрегацию для 'action_id' на основе пользовательской метрики, определяемой промежутком времени, который потребовался для перехода от 'action':'start' в 'action':'complete'?

я использую kibana для визуализации, если это поможет.

2 ответа

Похоже, что asticsearch не предназначен для непосредственного расчета продолжительности времени. Похоже, что asticsearch использует logstash для выполнения таких задач.

https://www.elastic.co/guide/en/logstash/current/plugins-filters-elasticsearch.html

if [action] == "complete" {
   elasticsearch {
      hosts => ["es-server"]
      query => "action:start AND action_id:%{[action_id]}"
      fields => ["time", "started"]
   }

  date {
     match => ["[started]", "ISO8601"]
     target => "[started]"
  }

  ruby {
     code => "event['duration_hrs'] = (event['@timestamp'] - event['started']) / 3600 rescue nil"   
  }
}

Я посмотрел на пример, приведенный для агрегированного метрического агрегирования и изменил его для этой проблемы:

{
   "aggs": {
      "actions": {
         "terms": {
            "field": "action_id"
         },
         "aggs": {
            "duration": {
               "scripted_metric": {
                  "init_script": "_agg['delta'] = 0",
                  "map_script": "if (doc['action'].value == \"complete\"){ _agg.delta += doc['time'].value } else {_agg.delta -= doc['time'].value}",
                  "combine_script": "return _agg.delta",
                  "reduce_script": "duration = 0; for (d in _aggs) { duration += d }; return duration"
               }
            }
         }
      }
   }
}

Сначала он создает сегменты для каждого action_id с агрегацией терминов.

Затем для каждого сегмента рассчитывается метрика, основанная на сценариях.

На map На шаге он принимает "полные" временные метки в качестве положительных значений, а другие (т. е. "начальные") как отрицательные для каждого шарда. Затем на combine шаг это просто возвращает их. И на reduce шаг, он суммирует длительности для действия над всеми шардами (так как события 'start' и 'complete' могут быть на разных шардах), чтобы получить фактическую длительность.

Я не уверен в производительности этой агрегации, но вы можете попробовать ее в своем наборе данных. И обратите внимание, что он помечен как экспериментальный.

Другие вопросы по тегам