我有格式的JSON:
{
"SOURCE":"Source A",
"Model":"ModelABC",
"Qty":"3"
}
我尝试使用logstash解析此JSON。基本上我希望logstash输出是一个key:value对的列表,我可以使用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模式,或者是否存在一些JSON的通用内容,这些内容将为我提供一个具有键值的事件:我在上面的一个事件中得到的值对?我找不到任何能够揭示这一点的文件。任何帮助,将不胜感激。我的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 }
}
答案 0 :(得分:5)
我想我找到了解决问题的方法。我不确定它是否是一个干净的解决方案,但它有助于解析上述类型的多线JSON。
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 { source => message }
的JSON。因此mutate过滤器:
replace => [ "message", "%{message}}" ]
这增加了缺失的支撑。和
gsub => [ 'message','\n','']
删除引入的\n
个字符。最后,我有一个可以由json { source => message }
如果有更简洁/更简单的方式将原始多行JSON转换为单行JSON,请执行POST,因为我觉得上面的内容不太干净。
答案 1 :(得分:4)
您需要使用multiline
编解码器。
input {
file {
codec => multiline {
pattern => '^{'
negate => true
what => previous
}
path => ['/opt/mount/ELK/json/mytestjson.json']
}
}
filter {
json {
source => message
remove_field => message
}
}
您将遇到的问题与文件中的最后一个事件有关。它不会出现,直到文件中有另一个事件(所以基本上你将丢失文件中的最后一个事件) - 你可以在文件中添加一个{
之前轮流处理这种情况。