Недопустимая ссылка на поле произошла при попытке создать индекс с тем же именем, что и значение пути запроса, используя выходные данные ElasticSearch

#elasticsearch #elasticsearch-plugin

#elasticsearch #elasticsearch-плагин

Вопрос:

Это мой logstash.conf файл:

 input {
    http {
        host => "127.0.0.1"
        port => 31311 
    }
}

filter {
    mutate {
        split => ["%{headers.request_path}", "/"]
        add_field => { "index_id" => "%{headers.request_path[0]}" }
        add_field => { "document_id" => "%{headers.request_path[1]}" }
    }
}

output {
  elasticsearch {
    hosts => "http://localhost:9200"
    index => "%{index_id}"
    document_id => "%{document_id}"
  }
  stdout {
    codec => "rubydebug"
  }
}
  

Когда я отправляю PUT запрос, подобный

C:UsersBolverkXRDownloadscurl-7.64.1-win64-mingwbin > .curl.exe -XPUT ‘http://127.0.0.1:31311/twitter

Я хочу, чтобы новый индекс создавался с именем twitter , а не с использованием значения по умолчанию ElasticSearch.

Однако Logstash немедленно завершается сбоем со следующим (усеченным) сообщением об ошибке:

Исключение в pipelineworker, конвейер перестал обрабатывать новые события, пожалуйста, проверьте конфигурацию фильтра и перезапустите Logstash. org.logstash.Исключение FieldReference$IllegalSyntaxException: недопустимая ссылка на поле: headers.request_path[0]

Я уверен, что где-то допустил синтаксическую ошибку, но я не вижу, где она. Как я могу это исправить?

Редактировать:

Та же ошибка возникает, когда я меняю filter сегмент на следующий:

 filter {
    mutate {
        split => ["%{[headers][request_path]}", "/"]
        add_field => { "index_id" => "%{[headers][request_path][0]}" }
        add_field => { "document_id" => "%{[headers][request_path][1]}" }
    }
}
  

Ответ №1:

Для разделения поля %{foo} синтаксис не используется. Также вы должны начать с позиции [1] массива, потому что в позиции [0] будет пустая строка( "" ) по причине отсутствия символов слева от первого разделителя ( / ) . Вместо этого ваш раздел фильтра должен быть примерно таким:

  filter {
    mutate {
        split => ["[headers][request_path]", "/"]
        add_field => { "index_id" => "%{[headers][request_path][1]}" }
        add_field => { "document_id" => "%{[headers][request_path][2]}" }
    }
}
  

Теперь вы можете использовать значение в %{index_id} и %{document_id} . Я протестировал это, используя logstash 6.5.3 version и использовал Postman для отправки ‘http://127.0.0.1:31311/twitter/1 ‘ HTTP-запрос и вывод в консоль были следующими:

 {
        "message" => "",
       "index_id" => "twitter",
    "document_id" => "1",
       "@version" => "1",
           "host" => "127.0.0.1",
     "@timestamp" => 2019-04-09T12:15:47.098Z,
        "headers" => {
             "connection" => "keep-alive",
           "http_version" => "HTTP/1.1",
            "http_accept" => "*/*",
          "cache_control" => "no-cache",
         "content_length" => "0",
          "postman_token" => "cb81754f-6d1c-4e31-ac94-fde50c0fdbf8",
        "accept_encoding" => "gzip, deflate",
           "request_path" => [
            [0] "",
            [1] "twitter",
            [2] "1"
        ],
              "http_host" => "127.0.0.1:31311",
        "http_user_agent" => "PostmanRuntime/7.6.1",
         "request_method" => "PUT"
    }
}
  

Раздел вывода вашей конфигурации не изменяется. Итак, ваш конечный файл logstash.conf будет выглядеть примерно так:

 input {
    http {
        host => "127.0.0.1"
        port => 31311 
    }
}

filter {
    mutate {
        split => ["[headers][request_path]", "/"]
        add_field => { "index_id" => "%{[headers][request_path][1]}" }
        add_field => { "document_id" => "%{[headers][request_path][2]}" }
    }
}

output {
  elasticsearch {
    hosts => "http://localhost:9200"
    index => "%{index_id}"
    document_id => "%{document_id}"
  }
  stdout {
    codec => "rubydebug"
  }
}