如何使用Elasticsearch从时间序列日志中确定ETL健康状态?

时间:2019-03-19 15:29:52

标签: elasticsearch indexing

TL; DR:Elasticsearch等同于此Postgres查询?

    SELECT latest_pipeline_logs.* FROM (
      SELECT pipeline_logs.*, 
      rank() OVER (
          PARTITION BY pipeline_name
          ORDER BY updated_at DESC
      )
      FROM pipeline_logs
    ) latest_pipeline_logs WHERE RANK = 1

我有数百条带有日志的ETL管道,这些日志已转储到Elasticsearch中。它们各自以不同的间隔独立执行。我想使用Elasticsearch聚合为每个ETL管道得出一个简单的健康状态。

每个管道在执行时都会记录其状态。我目前的思维过程是根据succeededfailed这两个最重要的状态来确定每个管道的运行状况。

我知道我可以对每个管道进行聚合查询并通过状态的子聚合进行分组。例如,与此类似的东西:

{
  ...

  "aggs": {
    "pipelines": {
      "field": "pipeline_name"
    },
    "aggs": {
      "states": {
        "terms": {
          "field": "pipeline_state"
        }
      }
    }
  }
}

上面的示例的问题是由于时间序列数据集,我可能会得到多个状态,例如:

{
  "key": "some-pipeline-name",
  "buckets": [
    {
      "key": "succeeded",
      "doc_count": 123
    },
    {
      "key": "failed",
      "doc_count": 567
    }
  ]
}

从理论上讲,我可以根据管道执行的日期来过滤结果,但是由于某些管道每隔一个月左右运行一次,所以我认为这不是一个选择。

最终状态是使用看起来像这样的Elasticsearch结果集来驱动简单的仪表板:

[
  {
    "key": "some-pipeline-name",
    "latest-status": "succeeded"
  },
  {
    "key": "some-other-pipeline",
    "latest-status": "failed"
  }
]

要注意的一件事是,在这种用例中,历史数据并不重要。仪表板将仅传达每个管道的最新状态。

您将如何通过Elasticsearch实现这一目标?

1 个答案:

答案 0 :(得分:1)

如果您只对每个管道的最新状态感兴趣,则可以将top_hits用作子聚合,然后按时间排序

{
  "size": 0,
  "aggs": {
    "pipeline": {
      "terms": {
        "field": "pipeline_name",
        "size": 1000
      },
      "aggs": {
        "top_hits_status": {
          "top_hits": {
            "size": 1,
            "sort": [
              {
                "timestamp": {
                  "order": "desc"
                }
              }
            ],
            "_source": {
              "includes": [
                "pipeline_state"
              ]
            }
          }
        }
      }
    }
  }
}