Elasticsearch 没有正确映射 logstash 日期
Elasticsearch not mapping logstash date correctly
我正在使用 ELK 来集中我们所有的日志,并且我正在转发 Artifactory 请求日志。
这将是一个示例行:
20160615130655|1|REQUEST|123.456.789.012|non_authenticated_user|GET|/9spj7rhd.fts|HTTP/1.1|401|0
这是 Logstash 过滤器:
filter{
if [type] == 'artifactory-request'{
grok {
'match' => {"message" => "%{DATESTAMP_EVENTLOG:logtime:string}\|%{NUMBER:request_time}\|%{DATA:request_type}\|%{IP:request_ip}\|%{DATA:request_username}\|%{DATA:request_method}\|%{DATA:resource_path}\|HTTP/%{NUMBER:http_version}\|%{NUMBER:response_code}\|%{NUMBER:size}"}
'remove_tag' => ["_grokparsefailure"]
}
date {
'match' => ["logtime", "yyyyMMddHHmmss"]
}
}
}
这似乎工作正常,如果我查看 Logstash 日志,我发现它正确映射了值:
Jun 15 13:10:30 elk docker[22890]: "@version" => "1",
Jun 15 13:10:30 elk docker[22890]: "@timestamp" => "2016-06-15T13:10:24.000Z",
Jun 15 13:10:30 elk docker[22890]: "file" => "/mnt/artifactory/logs/request.log",
Jun 15 13:10:30 elk docker[22890]: "host" => "artifactory",
Jun 15 13:10:30 elk docker[22890]: "offset" => "4667597",
Jun 15 13:10:30 elk docker[22890]: "type" => "artifactory-request",
Jun 15 13:10:30 elk docker[22890]: "tags" => [],
Jun 15 13:10:30 elk docker[22890]: "logtime" => "20160615131024",
Jun 15 13:10:30 elk docker[22890]: "request_time" => "1",
Jun 15 13:10:30 elk docker[22890]: "request_type" => "REQUEST",
Jun 15 13:10:30 elk docker[22890]: "request_ip" => "123.456.789.012",
Jun 15 13:10:30 elk docker[22890]: "request_username" => "non_authenticated_user",
Jun 15 13:10:30 elk docker[22890]: "request_method" => "GET",
Jun 15 13:10:30 elk docker[22890]: "resource_path" => "/login.php",
Jun 15 13:10:30 elk docker[22890]: "http_version" => "1.1",
Jun 15 13:10:30 elk docker[22890]: "response_code" => "401",
Jun 15 13:10:30 elk docker[22890]: "size" => "0"
Jun 15 13:10:30 elk docker[22890]: }
不过,ES好像不喜欢我的logtime
字段。
Jun 15 13:18:00 elk docker[22580]: [2016-06-15 13:18:00,288][DEBUG][action.bulk ] [Stellaris] [logstash-2016.06.15][4] failed to execute bulk item (index) index {[logstash-2016.06.15][artifactory-request][AVVUNhxaSE2i6S9oVvq2], source[{"message":"20160615131757|0|REQUEST|123.456.789.012|non_authenticated_user|GET|/|HTTP/1.1|302|0","@version":"1","@timestamp":"2016-06-15T13:17:57.000Z","file":"/mnt/artifactory/logs/request.log","host":"artifactory","offset":"4668979","type":"artifactory-request","tags":[],"logtime":"20160615131757","request_time":"0","request_type":"REQUEST","request_ip":"123.456.789.012","request_username":"non_authenticated_user","request_method":"GET","resource_path":"/","http_version":"1.1","response_code":"302","size":"0"}]}
Jun 15 13:18:00 elk docker[22580]: MapperParsingException[failed to parse [logtime]]; nested: IllegalArgumentException[Invalid format: "20160615131757" is malformed at "31757"];
查看映射(我猜是自动生成的,因为我还没有这样做)我明白为什么它不喜欢它
"logtime" : {
"type" : "date",
"format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
}
ES是如何判断logtime是日期的?我该如何修复它才能接受我输入的这种新格式?这曾经有效,但我没有真正改变任何东西,所以我很困惑。
这是我在 Logstash 端唯一的输出相关配置:
output {
elasticsearch { hosts => ["elasticsearch:9200"] }
stdout { codec => rubydebug }
}
而且我没有更改 Elasticsearch 上的任何配置,我使用的是默认设置。
有什么想法吗?我错过了什么?
非常感谢。
正如你所说,问题出在映射上。
您可以将日志时间字段从字符串转换为日期。
使用第二个日期过滤器,目标是日志时间字段:
date {
'match' => ["logtime", "yyyyMMddHHmmss"]
'target' => "logtime"
}
这会将字符串替换为日期,并且不会显示映射问题。
带有 'target' => "logtime"
的日期过滤器必须放在没有的日期过滤器之后,否则它将不起作用。
这是一个修复,但您应该尝试调查为什么会有这样的映射。 ES 映射与索引相关联并在接收文档时创建。
它们取决于本文档的字段。
所以这意味着到达 ES 的第一个 artifactory-request
文档在字段 logtime
中有一个日期。
或者ES中有模板用来创建索引,将logtime和date类型关联起来。
我正在使用 ELK 来集中我们所有的日志,并且我正在转发 Artifactory 请求日志。
这将是一个示例行:
20160615130655|1|REQUEST|123.456.789.012|non_authenticated_user|GET|/9spj7rhd.fts|HTTP/1.1|401|0
这是 Logstash 过滤器:
filter{
if [type] == 'artifactory-request'{
grok {
'match' => {"message" => "%{DATESTAMP_EVENTLOG:logtime:string}\|%{NUMBER:request_time}\|%{DATA:request_type}\|%{IP:request_ip}\|%{DATA:request_username}\|%{DATA:request_method}\|%{DATA:resource_path}\|HTTP/%{NUMBER:http_version}\|%{NUMBER:response_code}\|%{NUMBER:size}"}
'remove_tag' => ["_grokparsefailure"]
}
date {
'match' => ["logtime", "yyyyMMddHHmmss"]
}
}
}
这似乎工作正常,如果我查看 Logstash 日志,我发现它正确映射了值:
Jun 15 13:10:30 elk docker[22890]: "@version" => "1",
Jun 15 13:10:30 elk docker[22890]: "@timestamp" => "2016-06-15T13:10:24.000Z",
Jun 15 13:10:30 elk docker[22890]: "file" => "/mnt/artifactory/logs/request.log",
Jun 15 13:10:30 elk docker[22890]: "host" => "artifactory",
Jun 15 13:10:30 elk docker[22890]: "offset" => "4667597",
Jun 15 13:10:30 elk docker[22890]: "type" => "artifactory-request",
Jun 15 13:10:30 elk docker[22890]: "tags" => [],
Jun 15 13:10:30 elk docker[22890]: "logtime" => "20160615131024",
Jun 15 13:10:30 elk docker[22890]: "request_time" => "1",
Jun 15 13:10:30 elk docker[22890]: "request_type" => "REQUEST",
Jun 15 13:10:30 elk docker[22890]: "request_ip" => "123.456.789.012",
Jun 15 13:10:30 elk docker[22890]: "request_username" => "non_authenticated_user",
Jun 15 13:10:30 elk docker[22890]: "request_method" => "GET",
Jun 15 13:10:30 elk docker[22890]: "resource_path" => "/login.php",
Jun 15 13:10:30 elk docker[22890]: "http_version" => "1.1",
Jun 15 13:10:30 elk docker[22890]: "response_code" => "401",
Jun 15 13:10:30 elk docker[22890]: "size" => "0"
Jun 15 13:10:30 elk docker[22890]: }
不过,ES好像不喜欢我的logtime
字段。
Jun 15 13:18:00 elk docker[22580]: [2016-06-15 13:18:00,288][DEBUG][action.bulk ] [Stellaris] [logstash-2016.06.15][4] failed to execute bulk item (index) index {[logstash-2016.06.15][artifactory-request][AVVUNhxaSE2i6S9oVvq2], source[{"message":"20160615131757|0|REQUEST|123.456.789.012|non_authenticated_user|GET|/|HTTP/1.1|302|0","@version":"1","@timestamp":"2016-06-15T13:17:57.000Z","file":"/mnt/artifactory/logs/request.log","host":"artifactory","offset":"4668979","type":"artifactory-request","tags":[],"logtime":"20160615131757","request_time":"0","request_type":"REQUEST","request_ip":"123.456.789.012","request_username":"non_authenticated_user","request_method":"GET","resource_path":"/","http_version":"1.1","response_code":"302","size":"0"}]}
Jun 15 13:18:00 elk docker[22580]: MapperParsingException[failed to parse [logtime]]; nested: IllegalArgumentException[Invalid format: "20160615131757" is malformed at "31757"];
查看映射(我猜是自动生成的,因为我还没有这样做)我明白为什么它不喜欢它
"logtime" : {
"type" : "date",
"format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
}
ES是如何判断logtime是日期的?我该如何修复它才能接受我输入的这种新格式?这曾经有效,但我没有真正改变任何东西,所以我很困惑。
这是我在 Logstash 端唯一的输出相关配置:
output {
elasticsearch { hosts => ["elasticsearch:9200"] }
stdout { codec => rubydebug }
}
而且我没有更改 Elasticsearch 上的任何配置,我使用的是默认设置。
有什么想法吗?我错过了什么?
非常感谢。
正如你所说,问题出在映射上。
您可以将日志时间字段从字符串转换为日期。 使用第二个日期过滤器,目标是日志时间字段:
date {
'match' => ["logtime", "yyyyMMddHHmmss"]
'target' => "logtime"
}
这会将字符串替换为日期,并且不会显示映射问题。
带有 'target' => "logtime"
的日期过滤器必须放在没有的日期过滤器之后,否则它将不起作用。
这是一个修复,但您应该尝试调查为什么会有这样的映射。 ES 映射与索引相关联并在接收文档时创建。
它们取决于本文档的字段。
所以这意味着到达 ES 的第一个 artifactory-request
文档在字段 logtime
中有一个日期。
或者ES中有模板用来创建索引,将logtime和date类型关联起来。