Панель терминов Logstash + Kibana без слов
У меня есть приложение Java, которое пишет в файл журнала в формате JSON. Поля, которые входят в журналы, являются переменными. Logstash читает этот файл журнала и отправляет его в Kibana.
Я настроил logstash с помощью следующего файла:
input {
file {
path => ["[log_path]"]
codec => "json"
}
}
filter{
json {
source => "message"
}
date {
match => [ "data", "dd-MM-yyyy HH:mm:ss.SSS" ]
timezone => "America/Sao_Paulo"
}
}
output {
elasticsearch_http {
flush_size => 1
host => "[host]"
index => "application-%{+YYYY.MM.dd}"
}
}
Мне удалось правильно показать все в Кибане без каких-либо карт. Но когда я пытаюсь создать панель терминов для отображения количества серверов, отправивших эти сообщения, у меня возникает проблема. В моем json есть поле с именем server, которое показывает имя сервера (например: a1-name-server1), но панель терминов разделяет имя сервера из-за "-". Также я хотел бы подсчитать, сколько раз появляется сообщение об ошибке, но возникает та же проблема, потому что панель терминов разделяет сообщение об ошибке из-за пробелов.
Я использую Kibana 3 и Logstash 1.4. Я много искал в Интернете и не мог найти никакого решения. Я также попытался использовать.raw из logstash, но это не сработало.
Как я могу справиться с этим?
Спасибо за помощь.
2 ответа
Ваша проблема здесь в том, что ваши данные токенизируются. Это полезно для поиска по вашим данным. ES (по умолчанию) разделит ваше поле message
разделить на разные части, чтобы иметь возможность искать их. Например, вы можете искать слово ERROR
в ваших журналах, так что вы, вероятно, хотели бы видеть в результатах сообщения типа "Произошла ошибка в вашем кластере" или "Ошибка обработки чего угодно". Если вы не проанализируете данные для этого поля с помощью токенизаторов, вы не сможете выполнять поиск таким образом.
Это проанализированное поведение полезно, когда вы хотите что-то искать, но не позволяет группировать разные сообщения с одинаковым содержанием. Это ваш случай использования. Решением этой проблемы является обновление вашего картографического not_analyzed
для того конкретного поля, которое вы не хотите разбивать на токены. Это, вероятно, будет работать для вашего host
поле, но, вероятно, прервет поиск.
Что я обычно делаю в таких ситуациях - это использование шаблонов индексов и мультиполей. Шаблон индекса позволяет мне устанавливать сопоставление для каждого индекса, который соответствует регулярному выражению, а мультиполя позволяют мне иметь analyzed
а также not_analyzed
поведение в той же области.
Использование следующего запроса поможет решить вашу проблему:
curl -XPUT https://example.org/_template/name_of_index_template -d '
{
"template": "indexname*",
"mappings": {
"type": {
"properties": {
"field_name": {
"type": "multi_field",
"fields": {
"field_name": {
"type": "string",
"index": "analyzed"
},
"untouched": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}'
И тогда в вашей панели условий вы можете использовать field.untouched
, чтобы рассмотреть все содержимое поля при подсчете количества различных элементов.
Если вы не хотите использовать шаблоны индексов (возможно, ваши данные находятся в одном индексе), настройка сопоставления с помощью API Put Mapping также сделает эту работу. И если вы используете мультиполя, нет необходимости переиндексировать данные, потому что с того момента, как вы установите новое отображение для индекса, новые данные будут дублироваться в этих двух подполях (field_name
а также field_name.untouched
). Если вы просто измените отображение из analyzed
в not_analyzed
вы не сможете увидеть никаких изменений, пока не переиндексируете все свои данные.
Поскольку вы не определили отображение в asticsearch, настройки по умолчанию применяются для каждого поля вашего типа в вашем индексе. Настройки по умолчанию для строковых полей (например, поля вашего сервера) - это анализ поля, то есть эластичный поиск будет разбивать содержимое поля на токены. Вот почему это разделяет ваши имена серверов на части.
Вы можете преодолеть эту проблему, определив сопоставление. Вам не нужно определять все свои поля, а только те, которые вы не хотите, чтобы эластичный поиск анализировал. В вашем конкретном случае отправка следующей команды put сделает свое дело:
http://[host]:9200/[index_name]/_mapping/[type]
{
"type" : {
"properties" : {
"server" : {"type" : "string", "index" : "not_analyzed"}
}
}
}
Вы не можете сделать это на уже существующем индексе, потому что переключение с проанализированного на not_analyzed является основным изменением в отображении.