Splunk CSV等を加工したあとインデックスに取り込む


https://community.splunk.com/t5/Getting-Data-In/Index-time-field-extraction-not-working-with-backslash-in-field/m-p/505360
で回答したもののまとめ。

前提

psv.log
XXmentid|XX_date|blnumber|node|mode_nm|mode_nm2
"020202"|"2020-05-06 00:00:00"|"\"SCT 33447 33276 33276\""|"FAPJ"|"SCT 33447 33276 33276"|"SCT 33447 33276 33276"

いわゆる PSV(Pipe Separated Values)形式のファイル
SplunkはPSVの取り込みも、もちろん可能

問題発生

props.conf
INDEXED_EXTRACTIONS = psv

で取り込もうとすると
blnumber=\"SCT 33447 33276 33276\""|"FAPJ
となってしまう。
\(back slash)が悪さをしていて、|を認識しない。

SEDCMDで削除する手があるけど、INDEXED_EXTRACTIONSが先に動いてしまう。
そのため、効果がない。

props.confの評価順は

  1. LINE_BREAKER
  2. INDEXED_EXTRACTION
  3. SEDCMD
  4. TRANSFORMS等フィールド抽出

の順番みたい。確か以前の記事にあったと思うので、あとで修正します。

解決方法

props.conf
[psv_test]
LINE_BREAKER = ([\r\n]+)
NO_BINARY_CHECK = true
SEDCMD-trim = s/\\"//g
SHOULD_LINEMERGE = false
category = Custom
description = psv
pulldown_type = true
PREAMBLE_REGEX = XX.*
disabled = false
DATETIME_CONFIG =
TRANSFORMS-psv = psv
transforms.conf
[psv]
REGEX = (?<XXmentid>[^\|]+)\|(?<XX_date>[^\|]+)\|(?<blnumber>[^\|]+)\|(?<node>[^\|]+)\|(?<mode_nm>[^\|]+)\|(?<mode_nm2>[^\|]+)
FORMAT = XXmentid::$1 XX_date::$2 blnumber::$3 node::$4 mode_nm::$5 mode_nm2::$6
WRITE_META = true

解説

props.conf

  1. PREAMBLE_REGEX でヘッダー行を削除。以前はTRANSFORMSnullqueue送りにしてたけど、これで良かった。
  2. SEDCMDは悪さする\|を削除

transforms.conf

  1. DELIMSFIELDのコンボはsearch time extractionなので今回は使えなかった。
  2. REGEXWRITE_METAで行けるかと思ったけど、ダメだった。FORMATは必須
    • * At index-time, FORMAT defaults to <stanza-name>::$1 ということらしい
  3. FORMATの区切り文字は特になかった、逆に,をつけていたら、値になってしまった。

確認

search.spl
sourcetype="psv_test" node::FAPJ

結果が返ってきたので、きちんとindexに取り込まれている。

フィールドを作ったり削除したり

sample.csv
2020/03/03,13:40:23,Ohio,1,200,30
2020/03/03,13:40:23,Ohio,2,33000,40.4173,82.9071

のサンプル。

props.conf
[double_csv]
INDEXED_EXTRACTIONS = csv
FIELD_NAMES = DATE,TIME, LOCATION,EVENT,altitude,latitude,longitude
DATETIME_CONFIG =
SHOULD_LINEMERGE = false
LINE_BREAKER = ([\r\n]+)
NO_BINARY_CHECK = true
category = Custom
pulldown_type = true
TRANSFORMS-csv = double_csv, double_csv1
disabled = false
transforms.conf
[double_csv]
INGEST_EVAL = speed=if(EVENT=1,altitude,NULL), tilt=if(EVENT=1,latitude,NULL)
WRITE_META = true

[double_csv1]
INGEST_EVAL = longitude:=if(EVENT=1,null(),logitude), altitude:=if(EVENT=1,null(),altitude), latitud
e:=if(EVENT=1,null(),latitude)
WRITE_META = true

INGEST_EVAL:=を思い出せなくて、とても苦労しました
evalで上書きできるので、途中で別なフィールドを作ったり、元のデータを削除したりはこのようにできる。

なお、一つにまとめることは可能です。

ヘッダーの付け替え

sample.csv
time,command,data1,data2,
2020/03/03,13:40:23,Ohio,1
2020/03/03,13:40:23,Ohio,2

このCSVのヘッダーを付け替える場合

props.conf
INDEXED_EXTRACTIONS = csv
KV_MODE=none
SHOULD_LINEMERGE=false
category=Structured
description=Comma-separated value format
disabled=false
pulldown_type=true
FIELD_NAMES=time,program,event,data
PREAMBLE_REGEX=command
  • FIELD_NAMESで新しいフィールド名をつける
  • PREAMBLE_REGEXでヘッダー削除

が一番早かった。

まとめ

SEDCMDINDEXED_EXTRACTIONSの後にしか効かないので、ちょっとログが変だと、こんな感じでいろいろとtransforms.conf側でやらなければいけない。

INDEXED_EXTRACTIONSが使えれば、props.confFIELD_NAMESで指定ができる。

ヘッダーからフィールドが自動的に取れれば楽だけど、仕方ないですね