Разбор многострочного JSON с grok в logstash
У меня есть JSON формата:
{
"SOURCE":"Source A",
"Model":"ModelABC",
"Qty":"3"
}
Я пытаюсь разобрать этот JSON с помощью logstash. В основном я хочу, чтобы вывод logstash был списком пар ключ: значение, которые я могу анализировать с помощью kibana. Я думал, что это можно сделать из коробки. Из большого количества прочитанного я понимаю, что должен использовать плагин grok (я все еще не уверен, для чего нужен плагин json). Но я не могу получить событие со всеми полями. Я получаю несколько событий (по одному даже для каждого атрибута моего JSON). Нравится Итак:
{
"message" => " "SOURCE": "Source A",",
"@version" => "1",
"@timestamp" => "2014-08-31T01:26:23.432Z",
"type" => "my-json",
"tags" => [
[0] "tag-json"
],
"host" => "myserver.example.com",
"path" => "/opt/mount/ELK/json/mytestjson.json"
}
{
"message" => " "Model": "ModelABC",",
"@version" => "1",
"@timestamp" => "2014-08-31T01:26:23.438Z",
"type" => "my-json",
"tags" => [
[0] "tag-json"
],
"host" => "myserver.example.com",
"path" => "/opt/mount/ELK/json/mytestjson.json"
}
{
"message" => " "Qty": "3",",
"@version" => "1",
"@timestamp" => "2014-08-31T01:26:23.438Z",
"type" => "my-json",
"tags" => [
[0] "tag-json"
],
"host" => "myserver.example.com",
"path" => "/opt/mount/ELK/json/mytestjson.json"
}
Следует ли мне использовать многострочный кодек или кодек json_lines? Если да, то как я могу это сделать? Нужно ли мне написать свой собственный шаблон grok или есть что-то общее для JSONs, что даст мне одно событие с парами key:value, которые я получаю для одного события выше? Я не смог найти никаких документов, которые пролили бы свет на это. Любая помощь будет оценена по достоинству. Мой файл conf показан ниже:
input
{
file
{
type => "my-json"
path => ["/opt/mount/ELK/json/mytestjson.json"]
codec => json
tags => "tag-json"
}
}
filter
{
if [type] == "my-json"
{
date { locale => "en" match => [ "RECEIVE-TIMESTAMP", "yyyy-mm-dd HH:mm:ss" ] }
}
}
output
{
elasticsearch
{
host => localhost
}
stdout { codec => rubydebug }
}
2 ответа:
Я думаю, что нашел рабочий ответ на свою проблему. Я не уверен, что это чистое решение, но оно помогает анализировать многострочные JSONs типа выше.
input { file { codec => multiline { pattern => '^\{' negate => true what => previous } path => ["/opt/mount/ELK/json/*.json"] start_position => "beginning" sincedb_path => "/dev/null" exclude => "*.gz" } } filter { mutate { replace => [ "message", "%{message}}" ] gsub => [ 'message','\n',''] } if [message] =~ /^{.*}$/ { json { source => message } } } output { stdout { codec => rubydebug } }
Мой кодек mutliline не обрабатывает последнюю скобку, и поэтому он не выглядит как JSON для
json { source => message }
. Отсюда и фильтр мутаций:replace => [ "message", "%{message}}" ]
Это добавляет недостающую скобку. и
gsub => [ 'message','\n','']
Удаляет введенные символы
\n
. В конце его у меня есть однострочный JSON, который может быть прочитанjson { source => message }
Если есть более чистый / простой способ преобразовать оригинальный многострочный JSON в однострочный JSON, пожалуйста, напишите, поскольку я чувствую, что выше не слишком чистый.
Вам потребуется использовать кодек
multiline
.input { file { codec => multiline { pattern => '^{' negate => true what => previous } path => ['/opt/mount/ELK/json/mytestjson.json'] } } filter { json { source => message remove_field => message } }
Проблема, с которой вы столкнетесь, связана с последним событием в файле. Он не будет отображаться до тех пор, пока в файле не появится другое событие (поэтому в основном вы потеряете последнее событие в файле) - вы можете добавить один
{
к файлу, прежде чем он будет повернут, чтобы справиться с этой ситуацией.