我已将ELK配置为脱机收集数据,日志文件如下所示:
Info 2015-08-15 09:33:37,522 User 3 connected
Info 2015-08-15 10:03:57,592 User 99 connected
Info 2015-08-15 11:42:37,522 User 99 disconnected
Info 2015-08-15 11:49:12,108 User 3 disconnected
我要找的是时间线上的平均连接时间。
我无法在消息中添加更多信息,特别是我无法在断开连接消息中添加连接时间。
答案 0 :(得分:6)
如果您使用Logstash加载ES,则可以使用aggregate
过滤器来组合相关的离散日志行。想法是注意一个持久事件何时开始(即用户连接),然后当同一用户的disconnected
事件飞过时结束它:(注意你的格式模式可能不同,但原则是相同)
filter {
grok {
match => [ "message", "%{LOGLEVEL:loglevel} %{TIMESTAMP_ISO8601:timestamp} %{WORD:entity} %{INT:userid} %{WORD:status}" ]
}
if [status] == "connected" {
aggregate {
task_id => "%{userid}"
code => "map['started'] = event['timestamp']"
map_action => "create"
}
}
if [status] == "disconnected" {
aggregate {
task_id => "%{userid}"
code => "event['duration'] = event['timestamp'] - map['started']"
map_action => "update"
end_of_task => true
timeout => 86400000
}
}
}
您最终会得到一个名为duration
的附加字段(以毫秒为单位),您可以使用该字段在Kibana上绘制以显示平均连接时间。
另请注意,我正在给出一天的任意超时,这可能适合您的情况,也可能不适合您的情况。随意玩。
答案 1 :(得分:1)
Elasticsearch的一个缺点是它不是关系型数据库 - 因此交叉引用更加有限。有关于它的好文章:Managing Relations inside Elasticsearch
但它的长短是 - 没有办法直接查询这类事情。每个事件都是索引中的离散文档,并且没有任何类型的交叉引用。
所以你必须以艰难的方式去做。在最简单的级别 - 查询所有连接事件,查询所有断开连接事件,并使用脚本语言自行关联它们。
通过使用grok
过滤器预过滤日志,可以使数据更容易,以便为数据库添加字段。
if [type] == "syslog" and [message] =~ /connected/ {
grok {
match => [ "message", "User %{POSINT:userid} %{WORD:conn}" ]
}
}
这将添加userid
和conn
字段(包含"已连接"或"已断开连接")。
但是您仍然需要使用您喜欢的脚本语言手动将查询与数据库提取相关联(因此可以在脚本中执行“搜索和过滤”)。