Мы используем ElasticSearch для хранения и проверки журналов из нашей инфраструктуры. Некоторые из этих журналов требуются по закону, и мы не можем позволить себе потерять их.
Мы уже довольно давно занимаемся анализом журналов без какого-либо сопоставления. Это делает их практически непригодными для поиска и / или построения графиков. Например, некоторые целочисленные поля были автоматически распознаны как текст, и поэтому мы не можем агрегировать их в гистограммах.
Мы хотим представить шаблоны и отображение, которые решат проблему для новых индексов.
Однако мы заметили, что наличие сопоставления также открывает двери для сбоев анализа. Если поле определено как целое число, но внезапно получает нецелочисленное значение, синтаксический анализ завершится неудачно, и документ будет отклонен.
Можно ли куда-нибудь отправить эти документы и / или как сохранить их для проверки позже?
Сценарий Python здесь ниже работает с локальным экземпляром ES.
#!/usr/bin/env python3
import requests
import JSON
from typing import Any, Dict
ES_HOST = "http://localhost:9200"
def es_request(method: str, path: str, data: Dict[str, Any]) -> None:
response = requests.request(method, f"{ES_HOST}{path}", json=data)
if response.status_code != 200:
print(response.content)
es_request('put', '/_template/my_template', {
"index_patterns": ["my_index"],
"mappings": {
"properties": {
"some_integer": { "type": "integer" }
}
}
})
# This is fine
es_request('put', '/my_index/_doc/1', {
'some_integer': 42
})
# This will be rejected by ES, as it doesn't match the mapping.
# But how can I save it?
es_request('put', '/my_index/_doc/2', {
'some_integer': 'hello world'
})
Запуск скрипта дает следующую ошибку:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason":"failed to parse field [some_integer] of type [integer] in document with id '2'. Preview of field's value: 'hello world'"
}
],
"type": "mapper_parsing_exception",
"reason":"failed to parse field [some_integer] of type [integer] in document with id '2'. Preview of field's value: 'hello world'",
"caused_by": {
"type": "number_format_exception",
"reason": "For input string: \"hello world\""
}
},
"status": 400
}
А потом документ теряется, по крайней мере, так кажется. Могу ли я установить где-нибудь опцию, которая автоматически сохраняла бы документ в другом месте, что-то вроде очереди недоставленных писем?
tl; dr: Нам нужны сопоставления, но мы не можем позволить себе потерять строки журнала из-за ошибок синтаксического анализа. Можем ли мы автоматически сохранять документы, которые не соответствуют отображению в другом месте?
Оказывается, это так же просто, как разрешить "искаженные" атрибуты. Это можно сделать двумя способами. Либо по всему индексу:
PUT /_template/ignore_malformed_attributes
{
"index_patterns": ["my_index"],
"settings": {
"index.mapping.ignore_malformed": true
}
}
Или по атрибуту (см. Пример здесь: https://www.elastic.co/guide/en/elasticsearch/reference/current/ignore-malformed.html )
PUT my_index
{
"mappings": {
"properties": {
"number_one": {
"type": "integer",
"ignore_malformed": true
},
"number_two": {
"type": "integer"
}
}
}
}
# Will work
PUT my_index/_doc/1
{
"text": "Some text value",
"number_one": "foo"
}
# Will be rejected
PUT my_index/_doc/2
{
"text": "Some text value",
"number_two": "foo"
}
Обратите внимание, что вы также можете изменить свойство в существующем индексе, но сначала вам нужно закрыть его:
POST my_existing_index/_close
PUT my_existing_index/_settings
{
"index.mapping.ignore_malformed": false
}
POST my_existing_index/_open
НОТА: Изменение типа не будет видно в кибане, пока вы не обновите шаблон индекса. Тогда у вас возникнет конфликт типов, который потребует от вас переиндексации ваших данных для повторного поиска ... Какая боль.
POST _reindex
{
"source": {
"index": "my_index"
},
"dest": {
"index": "my_new_index"
}
}
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-reindex.html
Альтернативный подход, который может быть предпочтительнее для некоторых случаев использования, - это поместить журнал между производителями и Elasticseaech. Logstash может выполнять переформатирование и / или проверку и маршрутизацию по определенным индексам.
Или, конечно, если у вас есть собственные производители, позвольте им проверять и маршрутизировать.