Splunk: Splunk入門(SPL編 1/6) - SPL文の基本


###### 実施環境： Splunk Cloud 8.2.2104.1

### 0. 前置き

 Splunk の操作には、 SPL という独自の言語を使用します。
今回はその SPL について、基本的な情報とそれを用いた SPL 文の作り方を紹介していきます。

### 1. SPLとは

 Splunk では、取り込んだデータを検索、集計、加工するのに SPL という独自のデータベース言語を使用します。
その利用用途からしばしば同じデータベース言語の SQL と比較されますが、その構文はかなり異なり、むしろ UNIX 等のシェルコマンド言語に近いものとなります。
 SPL の基本的な構文は極めてシンプルであり、

* コマンドは先頭から順番に処理される
* コマンド同士は、パイプ(|)で繋ぐ

と、たったこれだけです。

:::note info
コマンドの処理順には例外もありますが、基本的には先頭から順番に処理されると考えてよいです。
:::

### 2. 最初の SPL 文

では早速、シンプルな SPL 文を実行してみましょう。

```Splunk:Splunk
search index="_internal"
```

「 search 」は SPL のコマンドの1つであり、条件を引数に指定してログを検索、出力するコマンドです。
「 index 」は収集したログデータを格納している容れ物 = インデックスの名前を表す項目であり、大抵はログの出力ファイル毎に分割します。
「 _internal 」は Splunk にデフォルトで存在するインデックスの1つで、 Splunk 自体の内部ログが格納されています。

すなわち上記の SPL 文の意味は、「 Splunk の内部ログを出力する」となります。

実際に実行した結果が以下の通りです。
 search コマンドだけだと集計処理は実施されないため、このように「イベント」タブにログの出力時間とログの内容のセットがリスト形式で出力されます。

![スクリーンショット 2022-02-15 21.52.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/91983582-2a3b-32cb-b127-401d64997bc4.png "search")

ところで画像からも分かる通り、上記の SPL 文を実行すると、入力フォームの「 search 」が消えてしまいます。
これは別にバグではなく、 SPL 文において先頭に指定される search コマンドは通常省略されるものだからです。
そのため、最初から以下のように入力しても同じ結果が得られます。

```Splunk:Splunk
index="_internal"
```

 search コマンドは SPL 文の中では特殊なコマンドで、明記することは少ないもののほとんどの SPL 文はこのコマンドから開始します。
以降の SPL 文ではわざわざ search コマンドは記載しませんが、このコマンドが常に先頭に存在していることは頭の片隅に置いておいてください。

:::note info
稀に search コマンドを使用しない SPL 文もありますが、その場合先頭のコマンドの前にはパイプ(|)が必要となり、またコマンドの省略も不可能です。
:::

### 3. パイプ

次に、検索により取り出されたログを集計する処理を先ほどの SPL 文に繋げてみましょう。
処理と処理は、パイプ(|)で繋ぎます。
なお、サーチフォーム中で改行を行いたい場合は、 Shift キーと Enter キーを同時に押すことで改行できます。
 Enter キーだけを押すと、即座にサーチが実行されてしまうので注意しましょう。
誤操作が心配な場合は、一旦テキストファイル SPL 文を書き、それをコピーして貼り付けるとよいです。

```Splunk:Splunk
index="_internal"
| stats count AS CNT BY source
```

「 stats 」は SPL のコマンドの1つであり、検索した結果に対して集計処理を実施します。
「 count 」は stats コマンドで使用できる関数(統計関数)の1つであり、ログの件数を出力します。
「 AS 」は項目名を変更する時に使用する前置詞で、ここでは count という項目の名前を CNT に変更しています。
「 BY 」は集計のキーを指定する時に使用する前置詞で、ここでは source という項目を集計のキーに指定しています。
「 source 」は Splunk で収集したログデータにデフォルトで付与される項目の1つで、収集元のログファイルのパスが記載されています。

すなわち上記の SPL 文の2行目は、「ログファイル毎のログ件数を CNT という項目名で集計する」という意味になります。

実際に実行した結果が以下の通りです。
 stats コマンドを使用して集計処理を行なったので、先ほどと異なり「統計情報」タブに集計結果がテーブル形式で表示されています。

![スクリーンショット 2022-02-15 21.53.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/a2a362ba-5032-404c-93bc-a88ce8ac7c3a.png "stats")

### 4. 処理の順番

さらにもう1つ、今度は並べ替え処理を繋げてみます。

```Splunk:Splunk
index="_internal"
| stats count AS CNT BY source
| sort - CNT
```

「 sort 」は SPL のコマンドの1つであり、引数に指定した項目をキーに出力結果の並べ替えを行います。
デフォルトの順番は昇順(小さい値を前にする)で、「-」を引数に指定すると降順(大きい値を前にする)になります。

すなわち上記の SPL 文の3行目は、「 CNT という項目の降順でデータを並び替える」という意味になります。

実際に実行した結果が以下の通りです。
集計結果に対し並べ替えが実行されているので、 SPL 文が上から順番に処理されていることがわかります。

![スクリーンショット 2022-02-15 21.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/8de6a74b-0108-45b1-ce89-d633a135024f.png "sort")

 SPL の基本的な構文は以上です。

### 5. SPL 文の作り方

以下は私の個人的な考え方ですので、ご参考程度に。
 SPL 文の作り方ですが、私は SPL 文を作る際に以下の 3 つのフェイズに分けて考えています。

* 検索 : 元ログから必要な情報を抽出する (主なコマンド : search, eval, ... )

* 集計 : 抽出した情報から集計値を算出する (主なコマンド :stats, chart, ... )

* 整形 : 算出した集計値を使いやすい形式に整える (主なコマンド : table, rename, ... )

![スクリーンショット 2022-03-21 22.20.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/c1849630-2ebf-38f6-f48b-7ce5f320ffa9.png "フェイズ")

例えば、以下の SPL 文を考えます。

```Splunk:Splunk
index="_internal" sourcetype="splunkd" source="*/splunkd.log"
| eval log_level_head = substr(log_level, 1, 1)
| stats count BY log_level_head
| table log_level_head, count
| rename log_level_head AS "ログレベル", count AS "件数"
```

1行目では、検索条件を指定してログを検索しています。
2行目では、ログの項目の1つから集計に使う値を別の項目に切り出しています。
1、2行目は集計に必要な情報を集めている段階なので、フェイズは「検索」となります。
この段階で終わった場合、 SPL 文の結果はリスト形式(「イベント」タブ)で表示されます。

3行目では、2行目で切り出した項目をキーに1行目で抽出したログの件数を集計しています。
3行目は1行目と2行目で得られた情報から集計している段階なので、フェイズは「集計」となります。
この段階以降では、 SPL 文の結果は表形式(「統計情報」タブ)で表示されます。

4行目では、3行目で得られた集計結果について列の並び替えを行っています。
5行目では、3行目で得られた集計結果について列名の変更を行っています。
4、5行目は3行目の結果を見やすい形に加工している段階なので、フェイズは「整形」となります。

![スクリーンショット 2022-03-20 22.20.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/03d529c3-baeb-abb4-dc8c-95054acde0a8.png "組み立て")

この「検索 → 集計 → 整形」という考え方は必ずしも全ての SPL 文に当てはめられるわけではありませんが、大抵の場合はこの形で考えるとわかりやすいかと思います。

### 6. SPL の向き不向き

 SPL という言語は、決して万能ではありません。
処理によっては、実現が難しいものもあります。

全てのログにまとめて実行するような処理は、 SPL の最も得意とするところです。

例) レベル毎のログ件数を集計する

![スクリーンショット 2022-03-20 22.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/e6e3895e-4ad8-24fc-f192-e10de1702983.png "全て")

1つ1つのログについて同じように行う処理も、 SPL は問題ないです。

例) 転送バイト数をキロバイト単位からメガバイト単位に変換する

![スクリーンショット 2022-03-20 22.46.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/70216128-3b28-7eda-e6dd-731aeba7a716.png "同じ")

ただ、1つ1つのログについて別々の処理を行うことは SPL では難しいです。
特にあるログが別のログを参照するような処理は、 SPL で実現しようとすると少々面倒です。

例) 終了ログをその直前の起動ログと結合して処理の実行時間を算出する

![スクリーンショット 2022-03-20 22.58.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/e5c4f853-c805-d5a2-a7db-d028f2410cb1.png "別々")

このような SPL での実現が難しい処理が含まれる場合は、無理に SPL だけで全て実現しようとせず、一旦 CSV データとして Splunk からダウンロードした後に VBA マクロにかけるなど、他のツールを併用することも考えたほうがよいです。

ここまで、 SPL 文の基本的な情報を見てきました。
あとはコマンドさえわかれば、大抵のことは実現できます。

[カテゴリ別 SPL コマンド一覧 (英語)](https://docs.splunk.com/Documentation/SplunkCloud/8.2.2107/SearchReference/Commandsbycategory)

ただ、SPL のコマンドはなかなか多彩で、一通り見ていくと結構な時間がかかります。
その上 Splunk 公式のコマンド一覧は英語のため、非常にとっつきにくいです。
そこで次回は、私の独断と偏見で選出したよく使うコマンドをいくつか紹介します。

[戻る](https://qiita.com/frozencatpisces/items/fb8dcaf0094abe9e5bd3)