JSON 形式ログの parse
JSON operator でほとんどの JSONPath 式を指定して JSON ログから値を抽出できます。下記「サポートされる JSONPath 構文要素」を参照してください。
JSON では順序が指定された値のシーケンスを含むネストされたキーおよび配列の両方が使用できるため、Sumo Logic の JSON operator は次の値を抽出できます。
- 単一最上位レベル フィールド。
- 複数フィールド。
- ネストされたフィールド。
- キーの配列。
構文
| json "<name_or_key>"[, "<name_or_key>", ...] [as <field> ...]
| json "<name_or_key>"[, "<name_or_key>", ...] [as <field>] [nodrop]
| json [field=<field_name>] "<name_or_key>"[, "<name_or_key>", ...] [as <field> ...]
| json auto [field=<field_name>] [maxdepth <#>]
| json auto [field=<field_name>] [extractarrays]
| json auto keys "<key1>"[, "<key2>", ...] [refonly] [as <field> ...]
オプション
nodrop
- 無効な JSON 値を含むメッセージを表示できます。詳細については、「parse nodrop」と「nodrop オプションの使用」を参照してください。field=<field_name>
- フィールドを指定してデフォルト メッセージ以外を parse できます。詳細については、「Parse field」を参照してください。auto
- ログ内の JSON オブジェクトを自動的に検出し、キー/値ペアを抽出します。詳細については「JSON auto オプション」を参照してください。
これ以降の例では、次のログ メッセージの例を使用します。
2014-03-11 15:00:42,611 -0700 INFO [hostId=prod-search-6] [explainJsonPlan.stream] {"module":"stream","logMessage":"exiting search","sessionId":"90D97000","customerId": "00B12CD0" ... { "baselineIntervals":[ "2014-03-11T23:00:00:000-07:00\/2014-03-12T05:00:00.000-07:00", "2014-03-12T05:00:00.000-07:00\/2014-03-12T11:00:00.000-07:00"], "meta":{ "type": "timestamps", "version": "1" } } ...
サポートされる JSONPath 構文要素
JSON operator は以下の JSONPath 式をサポートします。
JSONPath | 説明 |
$ | root オブジェクトまたは要素。 |
@ | 現在のオブジェクトまたは要素。 |
. or [] | child operator。 |
n/a | parent operator。 |
.. | 再帰的下降。JSONPath は E4X のこの構文を使用します。 |
* | ワイルドカード。その名前に関わらず、すべてのオブジェクトまたは要素を表します。 |
n/a | 属性アクセス。JSON 構造に属性は含まれません。 |
[] | subscript operator。XPath は、要素コレクションの繰り返しまたは predicates で、この operator を使用します。JavaScript と JSON では、native array operator になります。 |
[,] | ノード セットの組み合わせの XPath 結果の join operator。JSONPath では名前や配列インデックスをセットとして選択できます。 |
[start:end] | array slice operator。 |
() | スクリプト式。基盤となるスクリプト エンジンを使用します。 |
n/a | XPath でのグループ化。 |
単一最上位レベル フィールドの抽出
JSON operator で単一最上位レベル フィールドを抽出できます。たとえば、accountId
を抽出するには、次のように記述します。
_index=audit_events
| json "accountId"
| fields accountId
結果は次のようになります。
複数のフィールドの抽出
1 つの操作で複数のフィールドを抽出することもできます。たとえば、accountId
と eventName
を抽出するには、次のように記述します。
_index=audit_events
| json "accountId", "eventName"
| fields accountId, eventName
結果は次のようになります。
また、元のキー名とは異なる名前をフィールドに割り当てできます。accountId
の代わりに aID
、eventName
の代わりに eName
を使用するには、as
オプションを次のように使用します。
_index=sumologic_audit_events
| json "accountId", "eventName" as aID, eName
| fields aID, eName
結果は次のようになります。
ネストされたキーの抽出
ログ メッセージの例にはネストされたキーがあります。ドット表記を使用してパスを指定すると、これらのキーを抽出できます。
たとえば、meta
からネストされたキー type
を抽出するには、次のクエリを使用します。
* | json field=jsonobject "meta.type"
JSON 配列の値の検索
フィールド値が、ログ メッセージの例の baselineIntervals
のように、配列の場合があります。
JSON operator を使用して次のように @baselineIntervals
を抽出できます。
* | json field=jsonobject "baselineIntervals"
配列 ["2014-03-10T23:...", ""2014-03-11T05:..."]
の値のリストが
次のように返されます。
配列内の特定の 1 つのエントリを参照するには、配列のインデックスを次のように指定します。
* | json field=jsonobject "baselineIntervals[1]"
ネストされた配列。ドット表記を使用してネストされた配列の parse ができます。
_sourceCategory=O365*
| json "Actor[0].Type" as Actortype0
| json "Actor[1].Type" as Actortype1
このクエリの結果は次のようになります。
nodrop オプションの使用
デフォルトでは、JSON operator は指定されたキーがないメッセージや無効な JSON キーを使用するメッセージをドロップして、結果を最適化します。次のように nodrop オプションを使用すると、この最適化をせずに parse されたフィールドの値を Null (空白) にします。
* | json field=jsonobject "baselineIntervals[0]" nodrop
ワイルドカード (*) の使用
ワイルドカード (*) を使用して JSON の配列要素にアクセスできます。
たとえば、ワイルドカードを使用して O365 JSON メッセージの Actor Type にアクセスできます。
_sourceCategory=O365*
| json "Actor[*].Type" as Actortype
このクエリの結果は次のようになります。
次に、必要に応じて配列要素を使用して追加の操作を実行できます。たとえば、次のクエリを使用して CreationTime と Id の Type の最大値を検索できます。
_sourceCategory=O365*
| json field=_raw "CreationTime", "Id"
| json "Actor[*].Type" as Actortype
| extract field=ActorType"(?<Type>\d+)" multi
| max(type) by CreationTime, Id
結果は次のようになります。
JSON auto オプション
クエリで json auto オプションを使用して、parse ステートメントでフィールドを指定しなくても、ログ内の JSON オブジェクトを自動的に検出し、キー/値ペアを抽出します。クエリを実行すると、フィールド ブラウザを使用して、表示するフィールドを選択できます。後でクエリで parse されたフィールドを操作することもできます。
パラメータを追加して指定しない場合、JSON オブジェクトは自動的に検出され、すべてのキー/値ペアが抽出されます。JSON がないメッセージはドロップされません。
ログ メッセージ全体が JSON である必要はありません。JSON 部分の前後にテキストを配置することができます。json auto operator は、JSON オブジェクトの位置を自動検出し、parse します。
たとえば、次のメッセージがあるとします。
2015-05-04 21:51:43,289 -0700 INFO ["hostId"=stream] ["module"=stream] {"foo":{"bar":"baz"}} ...
operator は自動的に次の JSON オブジェクトを検出します。
{"foo":{"bar":"baz"}}.
json auto は、このメッセージの終わりにある json blob の開始を検索することによって機能することに注意してください。ほとんどのログはタイムスタンプなどの序文で始まり、次が json blob になります。json blob の後のメッセージの終わりにコンテンツがある場合、抽出が失敗することがあります。
メッセージの終わりに json blob を配置することをお勧めします。メッセージの中間に配置すると、抽出が失敗することがあります。
例
"{" | json auto
その他のオプション
* | json auto field=fieldname
フィールドを指定して操作します。デフォルトでは、json auto は未処理ログ メッセージ全体から JSON フィールドを抽出しようとします。他のフィールドで操作するには、field オプションを使用します。
例:
* | json auto field=<myfield>
* | json auto keys
json の特定のキーを参照します。as を使用してキーの名前を変更 (エイリアスを指定) できます。例:
* | json auto keys "<key1>", "<key2>" as <field1>, <field2>
参照されるキーのみを抽出する場合は refonly オプションを使用します。このオプションを使用しない場合、json auto はメッセージ内のその他の JSON フィールドもすべて抽出します。
例:
* | json auto keys "<key1>", "<key2>" refonly
* | json auto maxdepth
JSON のデータは階層構造になっており、複数のレベルのオブジェクトと配列を格納できます。たとえば、次のデータの深さのレベルは 4 です。
{ "foo": { "bar": [ { "k1": "v1" }, { "k2": "v2" } ], "baz": "qux" } }
深さ 1 は foo を含むオブジェクトです。深さ 2 は bar と baz を含むオブジェクトです。深さ 3 は 2 つのオブジェクトを含む配列です。深さ 4 はキー k1 と k2 を含む 2 つのオブジェクトです。
JSON を平板化するレベルを指定するには maxdepth を使用します。
次の例では、maxdepth 値を適用すると、前述の例がどのように変化するかを示します。
json auto maxdepth 1:
field: foo value: {"bar": [{"k1": "v1"}, {"k2", "v2"}], "baz": "qux"}
json auto maxdepth 2:
field: foo.bar value: [{"k1": "v1"}, {"k2", "v2"}]
field: foo.baz value: qux
例:
* | json auto maxdepth 2
* | json auto extractarrays
個別のキー/値ペアとして各配列要素を持つ平板化された配列から要素を抽出します。平板化されていない配列 (その他の JSON オブジェクトや配列を含む配列) がデフォルトでは抽出されます。
次のような例があるとします。
{"foo": [1,2,3]}
extractarrays オプションを指定しないと、json auto は次のように出力します。
field: foo value: [1,2,3]
extractarrays オプションを指定すると、json auto は次のようにフィールド/値ペアを出力します。
field: foo[0] value:
1
field
: foo[1] value:
2
field
: foo[2] value: 3
その他の重要な注意事項:
- 後でクエリで使用する場合、json auto を使用して parse されたフィールドを明示的に参照する必要はありません。たとえば、ユーザは次のクエリを実行する必要はありません。
* | json auto keys "username" | count by username
次のように記述するだけですみます。
username は json auto で extracted field と解釈され、そのように処理します。* | json auto | count by username
- json から抽出されたキーには、ドットと角括弧が含まれる場合があります。json 内の階層エンティティでは、異なるレベルの区切りとしてドットが使用されます。配列インデックスは角括弧で囲んで指定します。次は parse されたフィールドの名前の例です。
users[2].address.street
通常フィールド名にドットや角括弧は使用できないため、後でクエリでこのフィールド名を使用すると失敗します。これらのフィールドを使用するには、パーセント記号 (%) を使用してフィールドをエスケープします。
たとえば、次の例は失敗します。
* | json auto | count by users[2].address.street
しかし、次の場合は機能します。
* | json auto | count by %users[2].address.street
- FER (Field Extraction Rules) で抽出されるフィールドを json auto からのフィールドに置き換えるには、json auto でそれらのフィールドの名前を指定する必要があります。
たとえば、FER で抽出される source_ip フィールドではなく、json auto operator で抽出された source_ip フィールドを使用する場合は、次のクエリを使用します。
* | json auto "source_ip"
検索の警告
Unable to parse input as json (入力を json として parse できません)
デフォルトでは、JSON operator はクエリで指定されたフィールドやキーがないメッセージや JSON が無効なメッセージをドロップして結果を最適化します。メッセージがドロップされると、ユーザ インターフェイスに次の警告メッセージが表示されます。
これは、クエリの範囲で返された 1 つ以上のログに指定のキーが存在しないことを示す警告メッセージにすぎません。
この最適化をしない場合は、nodrop オプションを使用します。たとえば、次のクエリは event
キーを検索しますが、このキーを含まないメッセージをドロップしないように指定されています。
_sourceCategory="nginx"
| json "event" nodrop
次のようにクエリの範囲で必要なキーを指定すると、キーが見つからないという警告は削除できます。
_sourceCategory="nginx" "event"
| json "event"
event
がクエリの範囲で指定されているため、json operator は event
を含むログだけを取得します。