⛏️

Splunk lookupテーブル利用時の重複レコードの扱い

2021/02/27に公開

lookupテーブルの中に重複レコードがある時の振る舞い

表題の通りなのだけれど、そういうことした時のsplunkでの扱いが少々意外だったので、TIPSまで。

重複レコードがある場合って?

具体的には、こんなケースです。
192.168.1.1の行が2つあります。

Group address
Office A 192.168.1.1
Office B 192.168.1.1
Office C 192.168.1.2

SQL的に考えると、addressで別テーブルと突合した場合、例えば以下のようなテーブルとjoinすると、、、

address useragent
192.168.1.1 Mozilla ...
192.168.1.1 curl ...
192.168.1.2 Mozilla ...

こうなるはずなんですよね。

Group address useragent
Office A 192.168.1.1 Mozilla ...
Office A 192.168.1.1 curl ...
Office B 192.168.1.1 Mozilla ...
Office B 192.168.1.1 curl ...
Office C 192.168.1.2 Mozilla ...

Splunkのlookupを使うとそうはならん、という話です。

SplunkのLookupで同じことをすると、、?

以下のように、<search>の部分でGroup-addressのテーブルを作り、lookupで読み込んだaddress-useragentのテーブルと結合すると、、、

<search (Group-address)>
| lookup (address-useragent) address

こーなる。

Group address useragent
Office A 192.168.1.1 Mozilla ..., curl ...
Office B 192.168.1.1 Mozilla ..., curl ...
Office C 192.168.1.2 Mozilla ...

lookup側からとってきた要素(useragent)について、addressが同じものはmultivalueとして束ねた上で結合されるんですね。。

Lookup結合の厄介なケース

上記のようなシンプルなケースなら、処理後にmvexpand useragenとすれば、SQLの時と同じ、1行1データの形式に変換できます。
ただ厄介なのが、lookupから持ってくる要素が複数ある場合。
例えば、、

Group address useragent priority
Office A 192.168.1.1 Mozilla ..., curl ... High, Low
Office B 192.168.1.1 Mozilla ..., curl ... High, Low
Office C 192.168.1.2 Mozilla ... High

これをmvexpand useragentすると、、、

Group address useragent priority
Office A 192.168.1.1 Mozilla ... High, Low
Office A 192.168.1.1 curl ... High, Low
Office B 192.168.1.1 Mozilla... High, Low
Office B 192.168.1.1 curl ... High, Low
Office C 192.168.1.2 Mozilla ... High

えぇぇ、、、、
じゃぁmvexpand useragent | mvexpand priorityとすると、、

Group address useragent priority
Office A 192.168.1.1 Mozilla ... High
Office A 192.168.1.1 Mozilla ... Low
Office A 192.168.1.1 curl ... High
Office A 192.168.1.1 curl ... Low
Office B 192.168.1.1 Mozilla High
Office B 192.168.1.1 Mozilla Low
Office B 192.168.1.1 curl ... High
Office B 192.168.1.1 curl ... Low
Office C 192.168.1.2 Mozilla ... High

。。。うん、わかってた。。

一応、eval description=mvzip(useragent, priority, "-") | mvexpand descriptionとすれば、意図に近いことはできるのだけど、そうじゃないんだよな。。。

Group address description
Office A 192.168.1.1 Mozilla ...-High
Office A 192.168.1.1 curl ...-Low
Office B 192.168.1.1 Mozilla ...-High
Office B 192.168.1.1 curl ...-Low
Office C 192.168.1.2 Mozilla ...-High

備考 join処理としてみた時の振る舞い

Left outer joinです。
元のserchの結果(上記だと、Group-address)側がLeft。
引数で制御はできないようですので、right outer join相当にしようとすると、かなり泥臭い方法をとらないといけなくなる。。。
inner join化も泥臭行っちゃ泥臭いですが、where NOT isnull(Rightにしかないfield)を挟めばinner相当のデータに絞り込めます。

まとめ

正しいやり方があるんじゃなかろうかという気はしつつも、現状は思いつかず。

Discussion