Я использую filebeat для отправки своего журнала в Elasticsearch через, или использую модуль nginx для filebeat. Это хорошее решение для моей среды, и оно работает нормально.
Теперь я добавил собственный заголовок моего nginx журнала доступа, я отредактировал шаблон для nginx в filebeat, чтобы обновить шаблон, но я могу не вижу изменений в kibana (илиasticsearch).
Мой журнал похож на
0.0.0.0 - - [04/Feb/2020:15:04:58 +0000] "POST /v1/login HTTP/1.1" 200 819 "-" "Postman" "Edu"
Мой шаблон выглядит так:
"?%{IP:nginx.access.remote_ip_list} - %{DATA:nginx.access.user_name} \[%{HTTPDATE:nginx.access.time}\] \"%{GREEDYDATA:nginx.access.info}\" %{NUMBER:nginx.access.response_code:long} %{NUMBER:nginx.access.body_sent.bytes:long} \"%{DATA:nginx.access.referrer}\" \"%{DATA:nginx.access.agent}\" \"%{DATA:nginx.access.thirdparty}\"
И это смоделируйте результат в инструменте разработки kibana:
Я могу "переустановить" filebeat без ошибок, я могу снова запустить службу filebeat, но я могу не вижу новый элемент в индексе или в журналах (но я могу прочитать журнал непосредственно в контейнер и увидеть элемент в строке).
Я забыл что-нибудь сделать? Мне нужно добавить еще одну вещь в шаблон? Любое предложение для меня?
--- Больше информации ---
Filebeat version 6.8.6
Elastisearch версия 6.8.1
Kibana версия 6.8.1
Это мой файл шаблона:
{
"description": "Pipeline for parsing Nginx access logs. Requires the geoip and user_agent plugins.",
"processors": [
{
"grok": {
"field": "message",
"patterns": [
"\"?%{IP_LIST:nginx.access.remote_ip_list} - %{DATA:nginx.access.user_name} \\[%{HTTPDATE:nginx.access.time}\\] \"%{GREEDYDATA:nginx.access.info}\" %{NUMBER:nginx.access.response_code:long} %{NUMBER:nginx.access.body_sent.bytes:long} \"%{DATA:nginx.access.referrer}\" \"%{DATA:nginx.access.agent}\" \"%{DATA:nginx.access.thirdparty}\""
],
"pattern_definitions": {
"IP_LIST": "%{IP}(\"?,?\\s*%{IP})*"
},
"ignore_missing": true
}
},
{
"grok": {
"field": "nginx.access.info",
"patterns": [
"%{WORD:nginx.access.method} %{DATA:nginx.access.url} HTTP/%{NUMBER:nginx.access.http_version}",
""
],
"ignore_missing": true
}
},
{
"remove": {
"field": "nginx.access.info"
}
},
{
"split": {
"field": "nginx.access.remote_ip_list",
"separator": "\"?,?\\s+"
}
},
{
"script": {
"lang": "painless",
"source": "boolean isPrivate(def dot, def ip) { try { StringTokenizer tok = new StringTokenizer(ip, dot); int firstByte = Integer.parseInt(tok.nextToken()); int secondByte = Integer.parseInt(tok.nextToken()); if (firstByte == 10) { return true; } if (firstByte == 192 && secondByte == 168) { return true; } if (firstByte == 172 && secondByte >= 16 && secondByte <= 31) { return true; } if (firstByte == 127) { return true; } return false; } catch (Exception e) { return false; } } def found = false; for (def item : ctx.nginx.access.remote_ip_list) { if (!isPrivate(params.dot, item)) { ctx.nginx.access.remote_ip = item; found = true; break; } } if (!found) { ctx.nginx.access.remote_ip = ctx.nginx.access.remote_ip_list[0]; }",
"params": {
"dot": "."
}
}
},
{
"remove": {
"field": "message"
}
},
{
"rename": {
"field": "@timestamp",
"target_field": "read_timestamp"
}
},
{
"date": {
"field": "nginx.access.time",
"target_field": "@timestamp",
"formats": [
"dd/MMM/yyyy:H:m:s Z"
],
{< if .convert_timezone >}"timezone": "{{ beat.timezone }}",{< end >}
"ignore_failure": true
}
},
{
"remove": {
"field": "nginx.access.time"
}
},
{
"user_agent": {
"field": "nginx.access.agent",
"target_field": "nginx.access.user_agent",
"ecs": false
}
},
{
"thirdparty": {
"field": "nginx.access.thirdparty",
"target_field": "nginx.access.thirdparty",
"ecs": false
}
},
{
"rename": {
"field": "nginx.access.agent",
"target_field": "nginx.access.user_agent.original"
}
},
{
"geoip": {
"field": "nginx.access.remote_ip",
"target_field": "nginx.access.geoip",
"ignore_missing": true
}
}
],
"on_failure": [
{
"set": {
"field": "error.message",
"value": "{{ _ingest.on_failure_message }}"
}
}
]
}