从 ElasticSearch 中的文本中提取数字

Extract number from text in ElasticSearch

我正在使用 logstash 将日志发送到 ElasticSearch 5.1 实例,并使用 Kibana 5.1 显示所有结果。

如何只从日志的已知模式字符串中提取数字,然后每分钟汇总所有数字?

例如,我的日志行包含以下文本:

"Processing 53 records"

"Processing 45 records"

"Processing 97 records"

我想创建一个名为 processed_records 的字段,它分别获得值 53、45、97,然后我想创建另一个名为 [=26= 的字段]processed_records_sum,其中包含每分钟processed_records的摘要。

我是 ELK 的新手,所以我不知道是否需要在 logstash conf 文件中进行更改 and/or Kibana

要提取记录数,需要将日志文件与 Grok 解析器进行匹配,例如:

%{WORD} %{NUMBER:processed_records} %{WORD}

由于您的日志文件可能比这更复杂,有在线工具可以提供帮助:

一旦您的日志文件被解析,记录数将存储在 Elasticsearch 的 processed_records 字段中。

Summing (processed_records_sum) 数据将需要在查询时完成 - 您无法在将日志记录插入 Elasticsearch 时计算总和。

在查询时求和时,要么使用 Kibana UI,要么如果编写 Elasticsearch DSL,则使用聚合。

虽然性能不佳,但如果您必须避免重建索引,您可以在 kibana 中使用脚本化字段。

介绍在这里:https://www.elastic.co/blog/using-painless-kibana-scripted-fields

  • 通过在您的 elasticsearch.yaml 中添加以下内容来启用无痛正则表达式支持:

    script.painless.regex.enabled: true

  • 重启elasticsearch
  • 通过管理 -> 索引模式 -> 脚本字段在 Kibana 中创建一个新的脚本字段
  • select无痛如语言,数字如类型
  • 创建实际脚本,例如:
def logMsg = params['_source']['log_message'];
if(logMsg == null) {
 return -10000;
}
def m = /.*Processing ([0-9]+) records.*$/.matcher(params['_source']['log_message']);
if ( m.matches() ) {
   return Integer.parseInt(m.group(1))
} else {
   return -10000
}
  • 您必须完全重新加载网站才能执行新字段,仅在打开的发现网站上重新搜索不会获取新字段。 (这几乎让我放弃尝试让它工作 -.-)
  • 在发现或可视化中使用脚本

虽然我明白,为数百万日志条目编写字段的脚本效率不高,但我的用例是一个非常具体的日志条目,每天总共记录 10 次,我只使用结果字段来创建一个可视化或分析,我提前通过常规查询减少候选人。

如果可以只在您需要它们的情况下计算这些字段(或者它们是有意义的并且从一开始就是可计算的;即使 "return -1000" 变得不必要),那将会很有趣。目前它们将被应用并显示在每个日志条目中。
您可以在这样的查询中生成脚本化字段:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html 但这似乎隐藏在引擎盖下太多了,难以维护:/

您也可以使用 dissect 插件来实现相同的目的;

dissect { mapping => { "message" => "%{processing} %{processed_records} %{records}" }

然后您在 Kibana 中相应地配置了摘要!