CMSITLinuxАдминистрирование

Как добавить произвольное поле в Elasticsearch: ingest pipeline, mapping и проверка

Ниже — рабочий пример добавления поля app.session_id на стороне Elasticsearch. Сначала задаём тип поля, затем создаём ingest pipeline, проверяем его через _simulate и только после этого отправляем реальные документы.

1. Проверяем доступ к Elasticsearch

export ES_URL=https://elasticsearch.example.com
export ES_API_KEY=CHANGE_ME

curl -sS -H "Authorization: ApiKey $ES_API_KEY" "$ES_URL/"
curl -sS -H "Authorization: ApiKey $ES_API_KEY" "$ES_URL/_cluster/health?pretty"

2. Создаём component template с mapping

curl -sS -X PUT "$ES_URL/_component_template/app-custom-fields" \
  -H "Authorization: ApiKey $ES_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "template": {
      "mappings": {
        "properties": {
          "app": {
            "properties": {
              "session_id": { "type": "keyword" },
              "environment": { "type": "keyword" }
            }
          }
        }
      }
    }
  }'

3. Подключаем template к тестовым индексам

curl -sS -X PUT "$ES_URL/_index_template/app-logs-template" \
  -H "Authorization: ApiKey $ES_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "index_patterns": ["app-logs-*"],
    "composed_of": ["app-custom-fields"],
    "priority": 200
  }'

4. Создаём ingest pipeline

curl -sS -X PUT "$ES_URL/_ingest/pipeline/app-add-fields" \
  -H "Authorization: ApiKey $ES_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "description": "Add application fields",
    "processors": [
      {
        "set": {
          "field": "app.environment",
          "value": "production",
          "override": false
        }
      },
      {
        "rename": {
          "field": "session_id",
          "target_field": "app.session_id",
          "ignore_missing": true
        }
      }
    ]
  }'

5. Проверяем pipeline через _simulate

curl -sS -X POST "$ES_URL/_ingest/pipeline/app-add-fields/_simulate?pretty" \
  -H "Authorization: ApiKey $ES_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "docs": [
      {
        "_source": {
          "message": "login ok",
          "session_id": "sess-123"
        }
      }
    ]
  }'

В результате должны появиться app.session_id и app.environment, а исходное поле session_id должно исчезнуть.

6. Отправляем тестовый документ

curl -sS -X POST "$ES_URL/app-logs-test/_doc?pipeline=app-add-fields&refresh=true" \
  -H "Authorization: ApiKey $ES_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "@timestamp": "2026-08-02T06:30:00Z",
    "message": "login ok",
    "session_id": "sess-123"
  }'

7. Проверяем mapping и документ

curl -sS -H "Authorization: ApiKey $ES_API_KEY" \
  "$ES_URL/app-logs-test/_mapping/field/app.session_id?pretty"

curl -sS -H "Authorization: ApiKey $ES_API_KEY" \
  "$ES_URL/app-logs-test/_search?q=app.session_id:sess-123&pretty"

8. Проверяем конфликт типов до production

curl -sS -X POST "$ES_URL/app-logs-test/_doc?refresh=true" \
  -H "Authorization: ApiKey $ES_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"app":{"session_id":123}}'

Запись должна завершиться ошибкой типа, потому что поле объявлено как keyword. Такую проверку лучше выполнить на тестовом индексе до подключения основного потока.

9. Пример Logstash

filter {
  if [session_id] {
    mutate {
      rename => { "session_id" => "[app][session_id]" }
      add_field => { "[app][environment]" => "production" }
    }
  }
}

10. Rollback

curl -sS -X DELETE -H "Authorization: ApiKey $ES_API_KEY" "$ES_URL/_ingest/pipeline/app-add-fields"
curl -sS -X DELETE -H "Authorization: ApiKey $ES_API_KEY" "$ES_URL/_index_template/app-logs-template"
curl -sS -X DELETE -H "Authorization: ApiKey $ES_API_KEY" "$ES_URL/_component_template/app-custom-fields"
curl -sS -X DELETE -H "Authorization: ApiKey $ES_API_KEY" "$ES_URL/app-logs-test"

Критерий успеха: _simulate формирует нужные поля, mapping показывает тип keyword, тестовый документ находится по точному значению, а конфликтующий тип отклоняется.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *