ELK 专题:4. Logstatsh 的索引与模版文件 (template)

教程基于 ELK 6.5.4 版本实现并测试通过,理论上支持 6.x 版本。

TL; DR

通过编写指定了字段格式的索引模版文件,使得 ElasticSearch 索引字段的数据类型符合我们的预期。


简介

我在开始使用 ELK 套件的时候发现了一些小瑕疵,即我生成的 Index 索引中的 IP 字段并不是 IP 格式而是普通的字符串类型(还不让修改),而一些应该是数字类型的字段却不能通过设定变为更易索引的数字类型。

而后续发现,我们可以通过预设一/多个 template (模版文件)来提前为即将进入 ElasticSearch 的数据的格式进行定义,同时 template 可以通过在 Logstash 的 tag 来区分使用哪一个模版文件。


编写 Template 模版文件

Template 模版文件的编写格式

template (以下简称模版)是一个 JSON 文件,符合 JSON 的风格与限制格式。
需要注意,模版的文件名即是模版的名称,会在 Logstash 指定采用模版文件时需要用上。(可以根据参数指定)

下面提供一个日志数据的模版文件范例,且该模版名为 nginxLogTemplate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* nginxLogTemplate.json */
{
"index_patterns": ["nginx*", "log*"],
"order": 1,
"settings": {
"index.refresh_interval" : "5s"
},
"mappings": {
"_default_": {
"properties": {
"ip" : {"type":"ip"},
"body_bytes_sent" : {"type":"long"},
"http_version" : {"type":"half_float"},
"response_status" : {"type":"short"},
"geoip": {
"properties": {
"location": { "type":"geo_point" }
}
}
}
}
}
}

解释:

  1. index_patterns: 定义这个模版文件适用于哪些符合该正则的索引
  2. order: 定义该模版的优先级(在下一章节中有介绍)
  3. index.refresh_interval: 定义该索引的刷新频率
  4. _default_: 除非有特别指定映射的类型,否则,遵从这个配置。
  5. properties: 定义具体其中某些字段的格式,形如 field(字段名称): {"type": "format(数据类型)"}。想知道能够设置的类型有什么,请查看官方文档
  1. 模版只会在新建索引时生效,修改模版中某字段的格式,并不会对已经存在的索引产生影响。
  2. 如果索引中的字段是个二维数组,这需要在其中再包裹一层 properties 然后再对具体的字段进行指定,如范例中的 gepip 字段。

模版文件的优先级

模版文件存在优先级之分,如果一个索引同时满足多个模版文件的正则,那么这时候会出现,到底引用哪一个的问题。
那么实际上,模版文件是通过其中的 order 字段进行区分。该字段是一个数字类型,数字越往大则优先级越高

引用官方的范例并做了改动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/* 模版1 */
{
"index_patterns" : ["*"],
"order" : 0,
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"_doc" : {
"_source" : { "enabled" : false },
"body_request" : { "enabled" : true },
}
}
}

/* 模版2 */
{
"index_patterns" : ["te*"],
"order" : 1,
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"_doc" : {
"_source" : { "enabled" : true }
}
}
}

当一个名为 testLog 的索引加入到 ElasticSearch,其同时符合模版 1 以及模版 2 的正则条件,这时候,则根据两个模版的优先级选用了模版 2 的配置,所以最后是采用了模版 2 的 _source 配置,即 true

  1. 如果 1 个索引同时符合多个模版,实际上,是一种继承关系,即索引会继承所有的模版设置,但是存在相同字段设置冲突时,会用更高优先级的模版设置覆盖更低优先级的模版设置。
  2. 如果多个索引处于同一优先级,但是又在某些字段上的设置存在冲突,则这时候谁覆盖谁是不明确的,所以要考虑好优先级的设定。

加载 Template 模版

如何让 ElasticSearch 加载模版

直接进行 CURL 把模版文件推入 ElasticSearch 即可,如以下范例:
推入一个名为 nginxLogTemplate 的模版文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PUT /_template/nginxLogTemplate
{
"index_patterns" : ["*"],
"order" : 0,
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"_doc" : {
"_source" : { "enabled" : false },
"body_request" : { "enabled" : true },
}
}
}

如何让 Logstash 加载模版

可以通过设置 Logstash.conf 的输出进行加载

1
2
3
4
5
6
7
8
9
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "nginx-%{+YYYY.MM.dd}"
template => "/opt/logstash/config/nginxLogTemplate.json" # 模版文件的实际路径
template_name => "nginx*" # 模版名字
template_overwrite => true # 是否覆盖 ElasticSearch 的模版
}
}


了解更多 ELK 专题

  1. ELK on Docker with X-Pack [了解一下]
  2. 破解 X-Pack [了解一下]
  3. 非交互式修改 ElasticSearch 密码 [了解一下]
  4. Logstatsh 的索引与模版文件 (template) [了解一下]

致谢

  1. Index Templates/Elasticsearch Reference
  2. Logstash学习(六)elasticsearch插件——设置ES的Template