1

ログの解析には ELK がとても気に入っています。ただし、辞書のリストを解析する必要がある時点で立ち往生しています。以下は私のログです: -

IP - - 0.000 0.000 [24/May/2015:06:51:13 +0000] *"POST /c.gif HTTP/1.1"* 200 4 * user_id=UserID&package_name=SomePackageName&model=Titanium+S202&country_code=in&android_id=AndroidID&eT=1432450271859&eTz=GMT%2B05%3A30&events=%5B%7B%22eV%22%3A%22com.olx.southasia%22%2C%22eC%22%3A%22appUpdate%22%2C%22eA%22%3A%22app_activated%22%2C%22eTz%22%3A%22GMT%2B05%3A30%22%2C%22eT%22%3A%221432386324909%22%2C%22eL%22%3A%22packageName%22%7D%5D * "-" "-" "-"

上記のログの URL デコード バージョンは次のとおりです。

IP - - 0.000 0.000 [24/May/2015:06:51:13  0000] *"POST /c.gif HTTP/1.1"* 200 4 * user_id=UserID&package_name=SomePackageName&model=Titanium S202&country_code=in&android_id=AndroidID&eT=1432450271859&eTz=GMT+05:30&events=[{"eV":"com.olx.southasia","eC":"appUpdate","eA":"app_activated","eTz":"GMT+05:30","eT":"1432386324909","eL":"packageName"}] * "-" "-" "-"

どこで解析しようとしても、 が表示されます_jsonparsefailure。私もこの質問を経験し、さまざまなフォーラムも経験しましたが、同じことに対する完璧な解決策は見つかりませんでした. logstashでjsonリストを解析するにはどうすればよいですか?? 今まで存在しない場合、同じ問題を回避するにはどうすればよいですか??

以下は私の設定ファイルです。

filter {
    mutate {
        gsub => [
            "message", "\+", "%20"
        ]
    }

    urldecode{
        field => "message"
    }
    grok {
        match => [
            'message', '%{IP:clientip}%{GREEDYDATA} \[%{GREEDYDATA:timestamp}\] \*"%{WORD:method}%{GREEDYDATA}'
        ]
    }

    kv {
        field_split => "&?"
    }

    json{
        source => "events"
    }

    geoip {
        source => "clientip"
    }
}
4

1 に答える 1

2

この質問は、logstash のリストにある Parse jsonの正確なコピーです。同じログエントリでも?! 誰でもそれを理解できますか?

そこに私の答えが表示されますが、要約します...オプションe)がおそらく最良のアプローチです


どうやら、角括弧が原因でjsonparsefailureが発生するようです。回避策として、それらを手動で削除できます。kv の後、json フィルターの前に、次の mutate フィルターを追加します。

mutate  {
    gsub => [ "events","\]",""]
    gsub => [ "events","\[",""]
}

ただし、 のような入力では機能しません[{"foo":"bar"},{"foo":"bar1"}]。したがって、ここに 4 つのオプションがあります。

オプション a) 醜い gsub

醜い回避策は、別の gsub です。

gsub => [ "event","\},\{",","]

しかし、これは内部関係を削除するので、あなたはそれをしたくないと思います.

オプション b) 分割

より良いアプローチは、分割フィルターを使用することです。

split {
    field => "event"
    terminator => ","
}
mutate  {
    gsub => [ "event","\]",""]
    gsub => [ "event","\[",""]
   }
json{
    source=> "event"
}

これにより、複数のイベントが生成されます。(最初は でfoo = bar、2 番目は でfoo1 = bar1)

オプション c) ミューテート スプリット

すべての値を 1 つの logstash イベントに含めることができます。mutate => split フィルターを使用して配列を生成し、エントリが存在する場合は json を解析できます。残念ながら、logstash は設定でループをサポートしていないため、エントリごとに条件を設定する必要があります。

mutate  {
    gsub => [ "event","\]",""]
    gsub => [ "event","\[",""]
    split => [ "event", "," ]
   }

json{
    source=> "event[0]"
    target => "result[0]"
}

if 'event[1]' {
    json{
        source=> "event[1]"
        target => "result[1]"
    }
    if 'event[2]' {
        json{
            source=> "event[2]"
            target => "result[2]"
        }
    }
    # You would have to specify more conditionals if you expect even more dictionaries
}

オプション d) Ruby1

次の作品(kvフィルターの後):代わりにオプションe)を使用してください

mutate  {
    gsub => [ "event","\]",""]
    gsub => [ "event","\[",""]
}

ruby  {
    init => "require 'json'"
    code => "
        e = event['event'].split(',')
        ary = Array.new
        e.each do |x|
            hash = JSON.parse(x)
            hash.each do |key, value|
                ary.push( { key =>  value } )
            end
        end
        event['result'] = ary
    "
}

アップデート

オプション e) Ruby2

いくつかのテストの後、これが最良のアプローチである可能性があります。kv フィルターの後にこれを使用します。

ruby  {
    init => "require 'json'"
    code => "event['result'] = JSON.parse(event['event'])"
}
于 2015-08-04T11:57:15.253 に答える