Splunk>Answersの質問はなんか放置されてたけど、自分で納得できたので投稿します。
大体.confの資料に何故だかは書いてあった。
#課題
| makeresults
| eval _raw="Nov 14 03:23:42 hostname rsyslogd-pstats:{ \"name\": \"global\", \"origin\": \"dynstats\", \"values\": { } }
Nov 14 03:23:42 hostname rsyslogd-pstats:{ \"name\": \"imuxsock\", \"origin\": \"imuxsock\", \"submitted\": 0, \"ratelimit.discarded\": 0, \"ratelimit.numratelimiters\": 0 }
Nov 14 03:23:42 hostname rsyslogd-pstats:{ \"name\": \"action 0\", \"origin\": \"core.action\", \"processed\": 50996, \"failed\": 0, \"suspended\": 0, \"suspended.duration\": 0, \"resumed\": 0 }
Nov 14 03:23:42 hostname rsyslogd-pstats:{ \"name\": \"action 1\", \"origin\": \"core.action\", \"processed\": 50996, \"failed\": 0, \"suspended\": 0, \"suspended.duration\": 0, \"resumed\": 0 }"
| makemv delim="
" _raw
| stats count by _raw
| rex "(?<json>{.*)"
| spath input=json
JSONが途中から出てくるログをどうやったらprops.confで抽出できるのかを質問してみた。
この段階では、抽出したフィールドからINDEXED_EXTRACTIONS
とか使えると思っていた。
#解決方法
[json_sed]
TIME_FORMAT = %B %d %T
SEDCMD = s/.*?({.*)/\1/g
KV_MODE = json
LINE_BREAKER = ([\r\n]+)
NO_BINARY_CHECK = true
一番危惧していたのは、 SEDCMD
でログを加工してしまうとログの情報が取れなくなること。
でも順番で処理してくれるみたいで、最初に時刻情報の抽出をした後
SEDCMD
でログを加工してしまえばいいらしい。
transforms.confではなくprops.conf
でフィールド抽出はEXTRACT
です。
これはrex
の構文をそのまま使える。
今回はLINE_BREAKER
をデフォルトにしている。
通常のJSONだと LINE_BREAKER = }(,)
あたりがだいたい使えるかも。ここはログ次第
| makeresults
| eval _raw="Nov 14 03:23:42 hostname rsyslogd-pstats:{ \"name\": \"global\", \"origin\": \"dynstats\", \"values\": { } }
Nov 14 03:23:42 hostname rsyslogd-pstats:{ \"name\": \"imuxsock\", \"origin\": \"imuxsock\", \"submitted\": 0, \"ratelimit.discarded\": 0, \"ratelimit.numratelimiters\": 0 }
Nov 14 03:23:42 hostname rsyslogd-pstats:{ \"name\": \"action 0\", \"origin\": \"core.action\", \"processed\": 50996, \"failed\": 0, \"suspended\": 0, \"suspended.duration\": 0, \"resumed\": 0 }
Nov 14 03:23:42 hostname rsyslogd-pstats:{ \"name\": \"action 1\", \"origin\": \"core.action\", \"processed\": 50996, \"failed\": 0, \"suspended\": 0, \"suspended.duration\": 0, \"resumed\": 0 }"
| makemv delim="
" _raw
| stats count by _raw
| rex mode=sed "s/^.*?({.*})/\1/g"
こういった形で確認して、そのままSEDCMD
の引数に持っていけばいい。
|spath
が効くならKV_MODE=json
も使える。
なお、LINE_BREAKER
はrex "(?<line_breaker>なにか)"
してsplit(_raw,"なにか")
が使えるところと考えるといいと思います
わかりずらいですね
#JSONのJSON
| makeresults
| eval _raw="{
@timestamp: 2020-02-05T09:41:19.486+00:00
domain: capem
environment: sit
level: INFO
logger_name: com.test.dna.evthub.sse.impl.EventEncrypter
message: {\"data\":{\"errorDetails\":[{\"system\":\"OCS\",\"responseCode\":404,\"request\":{\"url\":\"https://slot4.org008.t-dev.test.net/application/ocsia/v1/ocs-provisioning/service/61474817171/products\",\"body\":[\"fb92a747-1cf7-09c8-33fc-0da0d0c16d80\"]},\"response\":{\"statusCode\":404,\"error\":{\"error\":10004,\"message\":\"Service not found in OCS\"}}}],\"transactionDetails\":{\"id\":\"30d49584-76fe-4e9e-b7b4-0c3a819e432e\",\"groupId\":\"6e2d25f3-6e77-90a2-689d-1e1476e79c8b\",\"parentId\":\"fb92a747-1cf7-09c8-33fc-0da0d0c16d80\",\"serviceId\":\"61474817171\",\"downstreams\":[{\"name\":\"OCS\",\"status\":\"FAILED\",\"statusCode\":404,\"error\":{\"error\":10004,\"message\":\"Service not found in OCS\"}}],\"orderItemId\":\"5065705155871632216\",\"actionStatus\":\"FAILED\",\"dependencies\":[],\"chargingSpecId\":\"CS_SVCLSUB_001\",\"chargingSpecType\":\"SERVICE_SUBSCRIPTION\",\"productActionCode\":\"CEASE\",\"productActionType\":\"cease\",\"productInstanceId\":\"fb92a747-1cf7-09c8-33fc-0da0d0c16d80\",\"chargingSpecSubType\":\"HANDSET_CONNECTION\",\"customerAccountUuid\":\"6b1b147c-2b98-2489-cf92-cefab92a77cf\",\"orderItemActionType\":\"Create\",\"effectiveDate\":\"2020-02-05T09:40:14+00:00\",\"sourceSystem\":\"B2C-Vlocity\",\"orderId\":\"B20052034417634\"}},\"correlationId\":\"30d49584-76fe-4e9e-b7b4-0c3a819e432e\",\"eventName\":\"WTC_SubscriptionLineItemCompletion_Failed\",\"timestamp\":\"2020-02-05T09:40:14+00:00\",\"eventPublisher\":\"WTC\"}
thread_name: main
}"
| rex "message: (?<message>{.*})"
| spath input=message
通常であれば、_message_だけ取り出すところ
#むりやりJSON
SEDCMD-trim1 = (\S+)\:\s(\w\S+)/\"\1\":\s\"\2\",/g
SEDCMD-trim2 = message:\s({.*})/\"message\": \1,/
KV_MODE = json
| rex mode=sed "s/(\S+)\: (\w\S+)/\"\1\": \"\2\",/g"
| rex mode=sed "s/message: ({.*})/\"message\": \1,/"
| spath
が効くので、そのままSEDCMD
に移植。
#まとめ
JSONなログはLINE_BREAKER
を気をつけないといけなかったり、まずは|spath
が効くかどうか確認しないとフィールドが抽出できない。
ネストが深くなければREGEXで抽出もありだけど、自動抽出が便利すぎて、無理やりJSONのほうがいいです。