Я настроил стек ELK и пытаюсь проанализировать записи журнала Squid.
И у меня возникла проблема при попытке преобразовать следующее время UNIX/Epoc как
1442469455.757
в удобочитаемый формат.
При устранении неполадок возникает следующая ошибка:
Получено событие, кодировка символов которого отличается от настроенной вами.
и это идет с "_dateparsefailure"
тегом, который означает, что это не удалось.
Я использовал следующий фильтр logstash
filter {
if [type] == "squid" {
grok {
patterns_dir => [ "/etc/logstash/patterns" ]
match => { message => "%{SQUID_LOG}" }
}
date {
match => [ "timestamp", "UNIX" ]
}
}
}
Шаблон регулярного выражения, определенный для соответствия временной метке в основном шаблоне, "%{SQUID_LOG}"
выглядит следующим образом:(%{DATA:timestamp})
Пожалуйста, дайте мне знать, существует ли постоянное решение или обходной путь для этой проблемы.
Заранее спасибо.
ОБНОВЛЯТЬ:
По-видимому, это вызвано дополнительным пробелом после временной метки, как указано ниже:
value=>"1438744871.647\\xA0\\xA0\\xA0\\xA0\\xA0", :exception=>"Invalid UNIX epoch value '1438744871.647\\xA0\\xA0\\xA0\\xA0\\xA0'", :config_parsers=>"UNIX", :config_locale=>"default=en_GB", :level=>:warn
Есть ли способ избавиться от них '\\xA0\\xA0\\xA0\\xA0\\xA0'
после временной метки?
Конфигурация:
input { stdin { } }
filter {
grok {
match => { message => "((%{DATA:time_stamp}) (%{NUMBER:time_elapsed_ms}) (%{IPV4:client_ip}) (%{WORD:req_stat})/(%{INT:reply_code}) (%{INT:request_size}) (%{WORD:http_method}) (%{URIPROTO:request_protocol}://)?%{IPORHOST:request_hostname}(?::%{POSINT:port})?(?:%{URIPATHPARAM:uri_param}|) (%{USERNAME:user}) (%{WORD:squid_hierarchy})/(%{HOST:server}|-) (%{DATA:content_type}) (%{WORD:snaction}|-))" }
add_tag => "NONU"
}
mutate {
strip => [ "time_stamp" ]
}
date {
match => [ "time_stamp", "UNIX" ]
}
}
output {
stdout { codec => rubydebug }
}
Образец данных:
1442469456.136 1 19.108.217.100 DENIED/407 3864 CONNECT fei.wsp.microsoft.com:443 - HIER_NONE/- text/html -
решение1
Если ошибки действительно вызваны лишним пробелом в time_stamp
поле, вы можете использовать mutate
фильтр, чтобы strip
его убрать. Тогда ваш фильтр будет выглядеть так:
filter {
if [type] == "squid" {
grok {
patterns_dir => [ "/etc/logstash/patterns" ]
match => { message => "%{SQUID_LOG}" }
}
mutate {
strip => ["time_stamp"]
}
date {
match => [ "time_stamp", "UNIX" ]
}
}
}
Обновлять
Если все записи журнала имеют ровно 6 дополнительных пробелов после временной метки, обновите шаблон Grok следующим образом. Обратите внимание на дополнительные пробелы между time_stamp
и time_epapsed_ms
.
((%{DATA:time_stamp}) (%{NUMBER:time_elapsed_ms}) (%{IPV4:client_ip}) (%{WORD:req_stat})/(%{INT:reply_code}) (%{INT:request_size}) (%{WORD:http_method}) (%{URIPROTO:request_protocol}://)?%{IPORHOST:request_hostname}(?::%{POSINT:port})?(?:%{URIPATHPARAM:uri_param}|) (%{USERNAME:user}) (%{WORD:squid_hierarchy})/(%{HOST:server}|-) (%{DATA:content_type}) (%{WORD:snaction}|-))
Если есть вероятность, что пробелов будет больше или меньше 6, то следующее должно сработать.
((%{DATA:time_stamp})%{SPACE}(%{NUMBER:time_elapsed_ms}) (%{IPV4:client_ip}) (%{WORD:req_stat})/(%{INT:reply_code}) (%{INT:request_size}) (%{WORD:http_method}) (%{URIPROTO:request_protocol}://)?%{IPORHOST:request_hostname}(?::%{POSINT:port})?(?:%{URIPATHPARAM:uri_param}|) (%{USERNAME:user}) (%{WORD:squid_hierarchy})/(%{HOST:server}|-) (%{DATA:content_type}) (%{WORD:snaction}|-))
решение2
Подозреваю, что это что-то при анализе SQUID_LOG (например, токен отсутствует или расположен не на своем месте).
Вы можете увидеть больше, если поместите код фильтра между:
input {
file {
path => "/opt/logstash/squid.log"
type => "squid"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
[filter]
output {
stdout { codec => rubydebug }
}
где /opt/logstash/squid.log — это всего лишь несколько проблемных строк журнала.
С:
/opt/logstash/bin/logstash -f this_test_conf_file.conf
Вы увидите на экране, что происходит.