我将一些服务器日志转储到elasticsearch中。日志包含'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
进行可视化。
答案 0 :(得分:0)
我查看了为scripted metric aggregation提供的示例,并针对此问题对其进行了修改:
{
"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
步骤中,它会对所有分片上的操作的持续时间进行求和(因为“开始”和“完整”事件可能位于不同的分片上)以获得实际持续时间。
我不确定此聚合的效果,但您可以在数据集上进行尝试。请注意,它已被标记为实验性功能。
答案 1 :(得分:0)
看起来弹性搜索并不是为了直接计算持续时间而设计的。似乎elasticsearch使用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"
}
}