Kibana:Heatmap 可视化介绍及 how-to

在 Kibana 中,你拥有完整的数据图形表示形式,大多数情况下,这可以通过简单的折线图或条形图来完成。 但是每隔一段时间,你就需要采取不同的观点,以充分利用数据。 热图是 Kibana 可视化武器库的重要组成部分,值得关注。

 

什么是 heatmap?

heatmap 是一种可视化类型,它使用颜色显示你要表示的数据的大小。 它们用于各种数据和几种不同的类型。 对于开发人员世界中的大多数人来说,我们遇到最多的人可能是GitHub Commit Graph。比如下面就是我的 github 的活动图:

上面的图清晰地表明了我在每个月在 github 上的 commit 图。颜色深的代表 commit 多一些,颜色浅代表 commit 少一些。

 

在 Kibana 中如何运作

现在,Kibana 热图非常适合可视化何时,何地甚至暗示某些事件发生的原因。 对于大多数使用 Kibana 的情况,我们正在检查,消化或尝试解释日志数据,那么这对我们有什么帮助? 使用热图,如果我们有不同类型或某种形式的分组标签的日志,我们可以轻松地确定最普遍的日志类型。

热图是一个简单的二维矩阵。 你最多只能有两个 bucket 聚合,并且只能计算一个指标聚合。 这两个 bucket 聚合将定义 X 轴和 Y 轴,而指标将定义单元格中颜色的强度。 我们来看一个简单的例子。首先,我们参阅之前文章 “Elasticsearch:透彻理解 Elasticsearch 中的 Bucket aggregation” 的一个索引。

iduseragecountrycategory
1Bill30FRA
2Marie32USA
3Clarie32USA
4Tom44DEB
5John40USB
6Emma26USB

在上面的表格中,我们可以看到一个很规整的关于用户的名单。每个用户具有 iduseragecountrycategory

我们可以使用如下的命令,把上面的数据导入到 Elasticsearch 中:

POST _bulk
{ "index" : { "_index" : "users", "_id": 1} }
{"user":"bill", "age": 30, "country": "FR", "category": "A"}
{ "index" : { "_index" : "users", "_id": 2} }
{"user":"Marie", "age": 32, "country": "US", "category": "A"}
{ "index" : { "_index" : "users", "_id": 3} }
{"user":"Clarie", "age": 32, "country": "US", "category": "A"}
{ "index" : { "_index" : "users", "_id": 4} }
{"user":"Tom", "age": 44, "country": "DE", "category": "B"}
{ "index" : { "_index" : "users", "_id": 5} }
{"user":"John", "age": 40, "country": "US", "category": "B"}
{ "index" : { "_index" : "users", "_id": 6} }
{"user":"Emma", "age": 26, "country": "US", "category": "B"}

等导入上面的数据后,我们可以通过如下的命令来查看 users 这个索引:

GET _cat/indices/users?v

上面的命令将显示如下的内容:

health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   users X3lrW6b4RueGzXr09lUkPQ   1   1          6            0      5.5kb          5.5kb

创建 heatmap 可视化

为了能够实现可视化化,我们必须为上面的 users 索引创建一个 index pattern:

 

点击 Next step:

点击 Create index pattern 按钮,这样我们的 users 索引模式就创建好了。

我们接下来创建 heatmap。如上面所述,我们需要有有两个 bucket 来分别标明 x 轴 及 y 轴。针对我们的设计,我们想针对 category 以及 country 来显示平均年龄的情况。我们选择 heatmap 可视化来完成这个个工作。

我选择 x 轴上为 country.keyword。点击上面的 Add 链接:

选择添加 Y-axis:

 我们选择 category.keyword 为 Y 轴上的聚合。点击 Update 按钮。上面显示的是文档的个数,虽然这个不是我们需要的。我们重新设置指标:计算平均年龄:

从上面的图中,我们可以看出来 category 为 B,并且 country 为 DE 的年龄最大,因为它显示的颜色最深。同时 country 为 FR, category 为 A 的平均年龄最小,颜色最浅。

我们甚至可以点击上面的 Inspect 来查看数据:

 

从上面,我们可以看到数据的显示情况。你如果有兴趣的话,也可以直接下载 csv 文件。

我们也可以点击上面的 Requests:

我们可以看到请求的命令。我们甚至直接可以把上面的命令拷贝到 Dev Tools 中去运行:

GET users/_search
{
  "aggs": {
    "2": {
      "terms": {
        "field": "country.keyword",
        "order": {
          "1": "desc"
        },
        "size": 5
      },
      "aggs": {
        "1": {
          "avg": {
            "field": "age"
          }
        },
        "3": {
          "terms": {
            "field": "category.keyword",
            "order": {
              "1": "desc"
            },
            "size": 5
          },
          "aggs": {
            "1": {
              "avg": {
                "field": "age"
              }
            }
          }
        }
      }
    }
  },
  "size": 0,
  "stored_fields": [
    "*"
  ],
  "script_fields": {},
  "docvalue_fields": [],
  "_source": {
    "excludes": []
  },
  "query": {
    "bool": {
      "must": [],
      "filter": [
        {
          "match_all": {}
        }
      ],
      "should": [],
      "must_not": []
    }
  }
}

我们可以看到运行的结果是:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "2" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "DE",
          "doc_count" : 1,
          "1" : {
            "value" : 44.0
          },
          "3" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "B",
                "doc_count" : 1,
                "1" : {
                  "value" : 44.0
                }
              }
            ]
          }
        },
        {
          "key" : "US",
          "doc_count" : 4,
          "1" : {
            "value" : 32.5
          },
          "3" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "B",
                "doc_count" : 2,
                "1" : {
                  "value" : 33.0
                }
              },
              {
                "key" : "A",
                "doc_count" : 2,
                "1" : {
                  "value" : 32.0
                }
              }
            ]
          }
        },
        {
          "key" : "FR",
          "doc_count" : 1,
          "1" : {
            "value" : 30.0
          },
          "3" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "A",
                "doc_count" : 1,
                "1" : {
                  "value" : 30.0
                }
              }
            ]
          }
        }
      ]
    }
  }
}