从logstash -> output -> elasticsearch动态模板说起

logstash索引映射

"mappings": {
    "_default_": { "dynamic_templates": [ { "string_fields": { "mapping": { "index": "analyzed", "omit_norms": true, "type": "string", "fields": { "raw": { "index": "not_analyzed", "ignore_above": 256, "type": "string" } } }, "match": "*", "match_mapping_type": "string" } } ], "_all": { "enabled": true }, "properties": { "@version": { "type": "string", "index": "not_analyzed" }, "geoip": { "dynamic": "true", "properties": { "location": { "type": "geo_point" } } } } },
    "hkt_log": { "dynamic_templates": [ { "string_fields": { "mapping": { "index": "analyzed", "omit_norms": true, "type": "string", "fields": { "raw": { "index": "not_analyzed", "ignore_above": 256, "type": "string" } } }, "match": "*", "match_mapping_type": "string" } } ], "_all": { "enabled": true }, "properties": { "@timestamp": { "type": "date", "format": "dateOptionalTime" }, "@version": { "type": "string", "index": "not_analyzed" }, "geoip": { "dynamic": "true", "properties": { "location": { "type": "geo_point" } } }, "host": { "type": "string", "norms": { "enabled": false }, "fields": { "raw": { "type": "string", "index": "not_analyzed", "ignore_above": 256 } } }, "message": { "type": "string", "norms": { "enabled": false }, "fields": { "raw": { "type": "string", "index": "not_analyzed", "ignore_above": 256 } } }, "path": { "type": "string", "norms": { "enabled": false }, "fields": { "raw": { "type": "string", "index": "not_analyzed", "ignore_above": 256 } } }, "type": { "type": "string", "norms": { "enabled": false }, "fields": { "raw": { "type": "string", "index": "not_analyzed", "ignore_above": 256 } } } } } }

_ default _映射

当logstash的输出插件为elasticsearch时,logstash在向ES中index数据,会自动为当前创建一个“default“的映射,后面所有该索引下新建的type mapping都将继承这个default的映射。
这个default映射,_all字段默认是disabled,这里将其enabled
默认增加@version字段
geoip字段dynamic true表示该字段下可以动态的添加新字段

下面的type hkt_log继承了default的映射内容。

dynamic_templates

通过dynamic_templates,你可以拥有对新字段的动态映射规则拥有完全的控制。你设置可以根据字段名称或者类型来使用一个不同的映射规则。

每个模板都有一个名字,可以用来描述这个模板做了什么。同时它有一个mapping用来指定具体的映射信息,和至少一个参数(比如match)用来规定对于什么字段需要使用该模板。

模板的匹配是有顺序的 - 第一个匹配的模板会被使用。

上面logstash的模板中定义一个所有字符串字段的统计设置模板:

{
    "string_fields": { "mapping": { "index": "analyzed", "omit_norms": true, "type": "string", "fields": { "raw": { "index": "not_analyzed", "ignore_above": 256, "type": "string" } } }, "match": "*", "match_mapping_type": "string" } }
  • string_fields 是模板名称,所有字符串字段统一映射定义。
  • match_mapping_type允许你只对特定类型的字段使用模板,正如标准动态映射规则那样,比如string,long等。
  • match参数只会匹配字段名。
  • 另外还有path_match参数用于匹配对象中字段的完整路径,比如address.*.name可以匹配如下字段:

    {
        "address":
            "city":
                "name": "New York"
            }
        }
    }
  • unmatch和path_unmatch模式能够用来排除某些字段,没有被排除的字段则会被匹配。

  • fields 是一个多字段属性,假如有一个字段叫message,那么表示会有一个子段message.raw,其中保存着message字段的原始内容,不会被分析器分析。

    • ”index”: “not_analyzed” 不分析字段内容
    • “ignore_above”: 256 最长处理256字符
    • “type”: “string” 字符串类型

hkt_log类型映射

我们可以看到hkt_log类型的映射完全继承了default的映射内容,同时动态的添加了特定字段,但是可以看到所有字符串字段都遵循着string_fields模板的定义,如message字段:

"message": {
    "type": "string",
    "norms": {
        "enabled": false
    },
    "fields": {
        "raw": {
            "type": "string",
            "index": "not_analyzed",
            "ignore_above": 256
        }
    }
}

message会有一个子段raw,保存着未经分析器分析过的原始内容。

那了多了这样一个字段有什么好处呢?
我们先向hkt_log中增加一个文档:

put logstash-2015.10.01/hkt_log/1
{
    "message": "jfy/zhyy?123",
    "@version": "1",
    "@timestamp": "2015-11-12T03:14:41.435Z",
    "type": "hostapd1_log",
    "host": "server114",
    "path": "/root/hostapd/hostapd1.log"
}

下面查询message字段中包含”?”的文档:

{
  "query":{ "regexp":{ "message":{"value":".*\\?.*"} } } }

查不到结果,改成:

{
  "query":{ "regexp":{ "message.raw":{"value":".*\\?.*"} } } }

可以查询到。

这是因为message字段内容”jfy/zhyy?123”被分析器分析后,变成了三个单词:jfy,zhyy,123,其中的”/”和”?”分析器是忽略掉的。

POST logstash-2015.10.01/_analyze
jfy/zhyy?123

{
    "tokens": [
        {
            "token": "jfy",
            "start_offset": 0,
            "end_offset": 3,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "zhyy",
            "start_offset": 4,
            "end_offset": 8,
            "type": "<ALPHANUM>",
            "position": 2
        },
        {
            "token": "123",
            "start_offset": 9,
            "end_offset": 12,
            "type": "<NUM>",
            "position": 3
        }
    ]
}

而message.raw是原样存储,因此用通配符就能查询。

你可能感兴趣的:(elasticsearch,logstash)