2014-08-31 45 views
4

神交我已經得到了格式的JSON:解析多JSON在logstash

{ 
    "SOURCE":"Source A", 
    "Model":"ModelABC", 
    "Qty":"3" 
} 

我試圖解析使用logstash這個JSON。基本上我想讓logstash輸出成爲我可以使用kibana分析的key:value對的列表。我認爲這可以開箱即用。從大量的閱讀中,我明白我必須使用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 } 
} 

回答

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來json { source => message }。因此,變異濾波器:

replace => [ "message", "%{message}}" ] 

這增加了缺失的大括號。和

gsub => [ 'message','\n',''] 

刪除引入的\n字符。在最後,我有一個可以通過json { source => message }

讀取的單行JSON如果有更簡單/更簡單的方法將原始多行JSON轉換爲單行JSON,請執行POST操作感覺上面不太乾淨。

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 
    } 
} 

您遇到的問題必須與文件中的最後一個事件有關。直到文件中出現另一個事件(因此基本上會丟失文件中的最後一個事件),它纔會顯示出來 - 您可以在文件輪換處理這種情況之前在文件中附加一個{

+0

感謝Alcanzar,我得到一個JSON解析失敗,但: [0] 「_jsonparsefailure」 試圖改變模式 模式=> '^ \ {' ,但仍是同樣的事情。而且我的文件每個文件只有1個JSON,即只有一個{或}字符。每個文件都將是一個事件(1個文件= 1個JSON = 1個事件) – Dan 2014-09-04 15:30:56

+0

您可能需要將'start_postion =>開始'添加到您的文件輸入以確保它始於記錄的開頭......還有什麼其他人在你的文件? (你可以刪除過濾器,只需添加一個'output {stdout {}}'來查看它傳遞給json過濾器的過程) – Alcanzar 2014-09-04 15:34:09

+0

我注意到我的生產JSON確實有額外的「{」和「}」:(So我的JSON實際上是:{「SOURCE」:「Source A」,「Model」:「ModelABC」,「Qty」:「3」「DESC」:「{\」New prod-125 \「}」}在評論中沒有很好地解析) 我無法對這些JSON進行更改,我們從另一個源接收它們,並且需要按原樣使用 – Dan 2014-09-04 17:16:19