Logstash — разделить многострочное сообщение на начало и конец

Я пытаюсь разобрать файл журнала, содержащий XML и другой произвольный вывод. В конкретном случае я хочу проверить, были ли бронирования успешно отправлены клиенту или нет.

[11-28-51.440000] Sending reservation to customer
[11-28-51.492900] <?xml version="1.0" encoding="UTF-8"?><SendReservation><ReservationId>1289</ReservationId><Customer>2892</Customer>...</SendReservation>
[11-28-51.493000] Status: Successfull
[11-28-52.261000] Something different
[11-28-51.520000] Sending reservation to customer
[11-28-54.548900] <?xml version="1.0" encoding="UTF-8"?><SendReservation><ReservationId>2732</ReservationId><Customer>7856</Customer>...</SendReservation>
[11-28-54.600000] Status: Error: Reservation was rejected

Теперь с помощью logstash мне нужно разобрать некоторые поля резервирования, в том числе ReservationId. Для этого я могу использовать XML-фильтр logstash. Однако я должен объединить это со статусом успеха/ошибки, который печатается после вывода XML в виде обычного текста.

Я пытаюсь использовать многострочный ввод:

input {
  file {
    path => "test.log"
    start_position => "beginning"
    type => "reservation"
    codec => multiline {
      pattern => "\[(.*?)\](.*?)<\?xml[^>]*>"
      negate => true
      what => previous
    }
  }
}

При этом у меня будет сообщение в событии logstash:

"message" => "[11-28-51.492900] <?xml version="1.0" encoding="UTF-8"?><SendReservation><ReservationId>1289</ReservationId><Customer>2892</Customer>...</SendReservation>\n[11-28-51.493000] Status: Successfull\n[11-28-52.261000] Something different\n[11-28-51.520000] Sending reservation to customer

Чтобы иметь возможность анализировать XML с помощью фильтра XML, мне нужно иметь поле как источник, который содержит действительный XML. Поэтому я пытаюсь отрезать отметку времени до и после xml.

    mutate {
        gsub => [ "message", "^(.*?)<\?xml[^>]*>", "" ]
    }
    mutate {
        gsub => [ "message", "(?<=<\/SendReservation>).*$", "" ]
    } 

На данный момент я вижу, что сопоставление регулярных выражений работает только в первой строке сообщения (перед первым \n). Это означает, что удаление всего после конечного тега не будет иметь никакого эффекта. Это моя первая проблема, которая может иметь какое-то отношение к многострочному коду.

Вторая проблема заключается в том, что я понятия не имею, как перемещать XML-контент, я пытаюсь вырезать "сообщение" в новое поле, которое я могу использовать в XML-фильтре в качестве исходного поля. . Я попробовал grok перезаписать, но для этого требуется существующее поле, и мне нужно создать новое.

Итак, в заключение, все, что я хочу, это создать поле головы и хвоста из моего многострочного сообщения. Заголовок будет содержать первую строку с XML, содержащую основную информацию, а остальную часть — с некоторой дополнительной информацией, которую я должен связать.


person Danny    schedule 21.01.2017    source источник


Ответы (1)


Хорошо, спасибо https://regex101.com и http://grokconstructor.appspot.com Я сам нашел

я должен использовать

grok { match => { "message" => "(?<head>(\[(.*?)\](.*?)<\?xml[^>]*>(.*?)<\/SendReservation>))+(?<tail>(?<=<\/SendReservation>)(.|\n)*$)" } }

Ответ на первую проблему: я должен учитывать \n: ?<=<\/SendReservation>)(.|\n)*$

Ответ на вторую проблему: Logstash создает поля из всех имен групп регулярных выражений. В этом случае шаблон grok (?<head>(regex_for_xml))+(?<tail>(regex_for_text)) создаст поля head и tail.

person Danny    schedule 22.01.2017