web-dev-qa-db-ja.com

LogstashがJSONを解析しない

Kibanaで結果を見ると、JSONからのフィールドがないことがわかります。さらに、messageフィールドには"status" : "FAILED"のみが含まれています。

Jsonからフィールドを解析し、それらをKibanaで表示することは可能ですか?次の設定があります:

input {
  file {
    type => "json"
    path => "/home/logstash/test.json"
    codec => json
    sincedb_path => "/home/logstash/sincedb"
  }
} 

output {
  stdout {}
  elasticsearch {
    protocol => "http"
    codec => "json"
    Host => "elasticsearch.dev"
    port => "9200"
  }
}

そして次のJSONファイル:

[{"uid":"441d1d1dd296fe60","name":"test_buylinks","title":"Testbuylinks","time":{"start":1419621623182,"stop":1419621640491,"duration":17309},"severity":"NORMAL","status":"FAILED"},{"uid":"a88c89b377aca0c9","name":"test_buylinks","title":"Testbuylinks","time":{"start":1419621623182,"stop":1419621640634,"duration":17452},"severity":"NORMAL","status":"FAILED"},{"uid":"32c3f8b52386c85c","name":"test_buylinks","title":"Testbuylinks","time":{"start":1419621623185,"stop":1419621640826,"duration":17641},"severity":"NORMAL","status":"FAILED"}]
10
avasin

はい。このようなフィルターを設定に追加する必要があります。

filter{
    json{
        source => "message"
    }
}

それはドキュメントでかなりよく説明されています here

[〜#〜] edit [〜#〜]jsonコーデックは、配列が渡されるのを好まないようです。単一の要素がこれで動作します設定:

入力:

{"uid":"441d1d1dd296fe60","name":"test_buylinks","title":"Testbuylinks","time":{"start":1419621623182,       "stop":1419621640491,"duration":17309      },      "severity":"NORMAL",      "status":"FAILED"   }

Logstashの結果:

{
      "message" => "{\"uid\":\"441d1d1dd296fe60\",\"name\":\"test_buylinks\",\"title\":\"Testbuylinks\",\"time\":{\"start\":1419621623182,       \"stop\":1419621640491,\"duration\":17309      },      \"severity\":\"NORMAL\",      \"status\":\"FAILED\"   }",
     "@version" => "1",
   "@timestamp" => "2015-02-26T23:25:12.011Z",
         "Host" => "emmet.local",
          "uid" => "441d1d1dd296fe60",
         "name" => "test_buylinks",
        "title" => "Testbuylinks",
         "time" => {
          "start" => 1419621623182,
           "stop" => 1419621640491,
       "duration" => 17309
   },
     "severity" => "NORMAL",
       "status" => "FAILED"

}

今配列で:

入力

[{"uid":"441d1d1dd296fe60","name":"test_buylinks","title":"Testbuylinks","time":{"start":1419621623182,       "stop":1419621640491,"duration":17309      },      "severity":"NORMAL",      "status":"FAILED"   }, {"uid":"441d1d1dd296fe60","name":"test_buylinks","title":"Testbuylinks","time":{"start":1419621623182,       "stop":1419621640491,"duration":17309      },      "severity":"NORMAL",      "status":"FAILED"   }]

結果:

Trouble parsing json {:source=>"message", :raw=>"[{\"uid\":\"441d1d1dd296fe60\",\"name\":\"test_buylinks\",\"title\":\"Testbuylinks\",\"time\":{\"start\":1419621623182,       \"stop\":1419621640491,\"duration\":17309      },      \"severity\":\"NORMAL\",      \"status\":\"FAILED\"   }, {\"uid\":\"441d1d1dd296fe60\",\"name\":\"test_buylinks\",\"title\":\"Testbuylinks\",\"time\":{\"start\":1419621623182,       \"stop\":1419621640491,\"duration\":17309      },      \"severity\":\"NORMAL\",      \"status\":\"FAILED\"   }]", :exception=>#<TypeError: can't convert Array into Hash>, :level=>:warn}
{
      "message" => "[{\"uid\":\"441d1d1dd296fe60\",\"name\":\"test_buylinks\",\"title\":\"Testbuylinks\",\"time\":{\"start\":1419621623182,       \"stop\":1419621640491,\"duration\":17309      },      \"severity\":\"NORMAL\",      \"status\":\"FAILED\"   }, {\"uid\":\"441d1d1dd296fe60\",\"name\":\"test_buylinks\",\"title\":\"Testbuylinks\",\"time\":{\"start\":1419621623182,       \"stop\":1419621640491,\"duration\":17309      },      \"severity\":\"NORMAL\",      \"status\":\"FAILED\"   }]",
     "@version" => "1",
   "@timestamp" => "2015-02-26T23:28:21.195Z",
         "Host" => "emmet.local",
         "tags" => [
       [0] "_jsonparsefailure"
   ]
}

これはコーデックのバグのようですが、メッセージを配列ではなくオブジェクトに変更できますか?

18
stringy05

jsonの代わりにjson_linesコーデックを試してください。これは最近追加されたはずです。特定のケースでは、最初に出力をjsonのリストから改行区切りのjsonに変更します。

http://logstash.net/docs/1.4.0/codecs/json_lines

このコーデックは、改行で区切られたストリーミングされたJSONをデコードします。たとえば、redis入力のJSONペイロードをデコードするには、代わりにjsonコーデックを使用します。エンコーディングは '\ n'で終わる単一のJSON文字列を出力します

2
Banjer

JSON配列を含むファイルの読み取りは、本来よりもはるかに困難です。以下は、有効なパイプライン構成です

input {
  exec {
    command => "cat /path/file_containing_json_array.txt"
    codec => "json"
    interval => 3600
  }
}

output {
  stdout {
    codec => rubydebug
  }
}
2
Nathan Reese