Задать вопрос
@zdravnik

Как склеить строки в logstash идущие не по порядку?

Есть логи ммногострочные postgresql следующего вида:
Jul 22 17:03:27 my.host example.com[24977]: [137-1] 2016-07-22 17:03:27.339 MSK User: username Database: my_db Host: 192.168.0.52(38494) Proc ID: 24977 etc1
Jul 22 17:03:27 my.host example.com[24977]: [137-2] 2016-07-22 17:03:27.339 MSK User: username Database: my_db Host: 192.168.0.52(38494) Proc ID: 24977 etc2
Jul 22 17:03:27 my.host example.com[24597]: [2953-1] 2016-07-22 17:03:27.339 MSK User: username Database: my_db Host: 192.168.0.52(38053) Proc ID: 24597 etc
Jul 22 17:03:27 my.host example.com[3637]: [3779-1] 2016-07-22 17:03:27.340 MSK User: username Database: my_db Host: 192.168.0.52(17809) Proc ID: 3637 etc
Jul 22 17:03:27 my.host example.com[24977]: [138-1] 2016-07-22 17:03:27.339 MSK User: username Database: my_db Host: 192.168.0.52(38494) Proc ID: 24977 etc1
Jul 22 17:03:27 my.host example.com[3637]: [3780-1] 2016-07-22 17:03:27.340 MSK User: username Database: my_db Host: 192.168.0.52(17809) Proc ID: 3637 etc
Jul 22 17:03:27 my.host example.com[24977]: [138-2] 2016-07-22 17:03:27.339 MSK User: username Database: my_db Host: 192.168.0.52(38494) Proc ID: 24977 etc2
Jul 22 17:03:27 my.host example.com[24977]: [139-1] 2016-07-22 17:03:27.340 MSK User: username Database: my_db Host: 192.168.0.52(38494) Proc ID: 24977 etc
Jul 22 17:03:27 my.host example.com[24597]: [2954-1] 2016-07-22 17:03:27.340 MSK User: username Database: my_db Host: 192.168.0.52(38053) Proc ID: 24597 etc1
Jul 22 17:03:27 my.host example.com[24597]: [2954-2] #011 SELECT count(*) FROM table#015


Для дальнейшего распарсивания логов с помощью grok, необходимо склеить их средствами logstash. Склейка должна получиться вида
line 1: ...[137-1] and [137-2]...
line 2: ...[2953-1]...
line 3: ...[3779-1]...
line 4: ...[3780-1]...
line 5: ...[138-1] and [138-2]...
line 6: ...[139-1]...
line 7: ...[2954-1] and [2954-2]...


порядок строк не важен в принципе, потому что в результате все равно идет привязка ко времени, важно чтобы строки с метками [x-1], [x-2], [x-3] и т.д. собирались в одну строку [x-1] [x-2] [x-3].

Все зацепки на которые можно опираться это метка с номером строки (например [139-1] и т.д.) и pid процесса из квадратных скобок после имени хоста (например [24977]). Другие переменные в качестве опоры при склейки не подходят ибо не гарантируют что строки не будут перепутаны, только pid гарантирует что в рамках одного пида не будет путаницы, ну и сам номер строки тоже дает гарантию.

Я так понимаю для решения задачи подходит codec multiline и/или комбинации с использованием оператора if и т.д. К сожалению перепробовал кучу вариантов за последние пару суток, но ответа так и не нашел пока.

К сожалению варианты типа
multiline {
pattern => "... \[\d+-1\]"
negate => true
what => "previous"
}

Не прокатывают потому что в данном случае склейка идет в перемешку, т.е. на выходе получаю
line 1: ...[137-1] and [137-2]...
line 2: ...[2953-1]...
line 3: ...[3779-1]...
line 4: ...[138-1]...
line 5: ...[3780-1] and [138-2]...
line 6: ...[139-1]...
line 7: ...[2954-1]...


Коллеги выручайте.
  • Вопрос задан
  • 1022 просмотра
Подписаться 1 Оценить 5 комментариев
Решения вопроса 1
@zdravnik Автор вопроса
ВОт решение моей задачи:

grok {
match => [ "message", "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:logsource} %{SYSLOGPROG}: \[%{INT:line}-%{INT:part_of_line}\] %{GREEDYDATA:ostatok}" ]
}

aggregate {
task_id => "%{line}%{pid}"
code => "
map.merge!(event) if map.empty?
map['full_message'] ||= ''
map['full_message'] += event['ostatok']
"
timeout => 10
push_map_as_event_on_timeout => true
timeout_code => "event.tag('aggregated')"
}

if "aggregated" not in [tags] {
drop {}
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы