Splunkでループ処理ってどうやるの? 邪道な方法だが実行してみた


はじめに

Splunkの SPLってめちゃくちゃ便利なんですが、唯一困るのがループ処理になんですよね〜。一部の streamingコマンド (eval, regex, rename など)は foreach コマンドで実装可能なのですが、それ以外のコマンド (stats,timechartなど) だと、このforeachコマンドが使えません。

例えば、複数の型番をリストして、その型番ごとに色々と計算した結果を表示したい。などの場合には以下のようなプロセスが必要です。
1. 型番をリスト化
2. 型番を一つごとに計算処理を実行
3. 同じことを全部の型番に対してループで実行 

最近は機械学習などと組み合わせる機会も多く、このようなループ処理は避けては通れなくなってきております。

そこで、今回は邪道かもしれませんが、 RestAPIを利用してリモートからループ処理を実行するパワープレイをご紹介します。 (Splunkだけでシンプルにできる方法知っていたら是非教えてください)

構成概要イメージ

今回はこんな感じでループ実行させます。 pythonで実行させるので、運用の中で定期実行が必要な場合は lambda などと連携するといいと思います。

Splunk側での準備

Splunk側では RestAPIが利用できるようにデフォルト管理ポートの8089ポートへのアクセス許可。そして、実行したいループ処理をマクロ設定しておきます。(こうしておくとコードがシンプルになります。短いSPLなら不要です)

今回は以下のような マクロ(make_price_feature)を作成しました。引数でループさせる値が入るようにしておきます。以下の場合、引数で入れた値(code)が "Local Code" に入るようにしております。

上記にあるとおり、コード毎に streamstats や、 autoregress を使っているため、foreachでは実行できませんでした。

python実装

コードをこちらにご紹介します。変数指定箇所と、最初のList取得のためのSPLを変更すれば流用できます。

# 変数指定
SERVER = 'https://<hostname>'   # Splunk Server URL (do not include port)
USER =  '<user-name>'
PASSWD = '<passwd>'
MACRO = 'make_price_feature'  # Splunkのマクロ名
OUTPUT = 'test.csv'   # 最後に結果を書き込む lookup file名

# List 取得のための SPL 
search_list_query = """
search index=hoge source=*stock_price.csv | table "Local Code" | dedup "Local Code"
"""

以下のコードはそのままコピーで使えます。

##  リストデータの取得
import requests

data = {
  'search': search_list_query,
  'exec_mode': 'oneshot',
  'output_mode': 'json',
  'count': '0'   # default だと 100個しかリターンされない
}

response = requests.post(SERVER + ':8089/services/search/jobs' , data=data, verify=False, auth=(USER, PASSWD))

## 出力結果のうち、値だけを抜き出す
lists = list()
result=response.json()['results']
for i in result:
  lists.append(list(i.values()))

# 抜き出した値ごとに、特定のマクロを実行させて、最後はファイルに保存
for j in lists:

  data1 = {
    'search': '| `' + MACRO + '(' + j[0] + ')` | outputlookup ' + OUTPUT + ' append=t',
    'exec_mode': 'oneshot',
    'output_mode': 'json'
  }
  response = requests.post(SERVER + ':8089/services/search/jobs' , data=data1, verify=False, auth=(USER, PASSWD))

さいごに

この仕組みを使えばループに限らず、複雑な処理をプログラミングを組むことができますね。

こちらにも上記のコードを置いておきますので、ご自由にご利用ください。