SplunkのSearchTutorialでいろいろと調べてみる（sourcetype=access_combined_wcookie）

[SearchTutorial](https://docs.splunk.com/Documentation/Splunk/8.0.4/SearchTutorial/WelcometotheSearchTutorial)のデータを利用して、いろいろと調べてみる。

データについては[こちら](https://docs.splunk.com/Documentation/Splunk/latest/SearchTutorial/Aboutthetutorialdata)

今回はデータを`index=tutorial`に取り込んだので、自分の環境に合わせてください。

#頻繁にアクセスしているIPアドレスを調べる
```sql:many_session.spl
index=tutorial sourcetype="access_combined_wcookie" 
| stats count as counts range(_time) as duration list(action) min(_time) as firsttime max(_time) as endtime by clientip JSESSIONID
| sort 0  clientip firsttime
| streamstats current=f last(endtime) as endtime_p by clientip
| where firsttime - endtime_p < 300
| convert ctime(firsttime) ctime(endtime)
| top clientip
```

このログにはJSESSIONID毎にアクセスが分かれるので、前回のアクセスから５分以内にアクセスしているIPアドレスを調べてみた。

##結果
| clientip | count | percent |
|:--|--:|--:|
| 87.194.216.51 | 12 | 16.666667 |
| 211.166.11.101 | 6 | 8.333333 |
| 107.3.146.207 | 3 | 4.166667 |
| 97.117.230.183 | 2 | 2.777778 |

`87.194.216.51`と`211.166.11.101`についてはなんかいろいろとやっていそう

#何をやっているか状況をみてみる

```sql:access_timechart.spl
index=tutorial sourcetype="access_combined_wcookie" (clientip=87.194.216.51 OR clientip=211.166.11.101)
| stats count as counts range(_time) as duration list(action) min(_time) as firsttime max(_time) as endtime by clientip JSESSIONID
| sort 0  clientip firsttime
| rename firsttime as _time
| xyseries _time clientip counts
```

`timechart`は使ってないけど`timechart`で表示してみる。

##結果

| _time | 211.166.11.101 | 87.194.216.51 |
|:--|--:|--:|
| 2020-05-15 19:43:16 |   | 1 |
| 2020-05-15 20:33:55 | 2 |   |
| 2020-05-15 20:46:00 |   | 3 |
| 2020-05-15 21:44:57 | 2 |   |
| 2020-05-15 22:35:07 | 4 |   |

![trellis_tutorial.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/d4b2eacc-03e7-6598-8a08-1047eff763ec.png)

ショッピングサイトにこんなアクセスをしてくるのはロクでもないことをしてそう。

##解説

- `stats`の集計はほとんど使っていない。
- `timechart`の時間は`_time`なので、`JSESSIONID`の最初の時刻にしている。
- `stats`の後の`xyseries`でトレリスが使えるのはいい発見

#アクセス状況を調べる。その２
```sql:access_state.spl
index=tutorial sourcetype="access_combined_wcookie" (clientip=87.194.216.51 OR clientip=211.166.11.101) status!=200
| stats list(file) as file list(status) as status by clientip
```

いわゆる目grep用出力

なにやってるかな〜ってときは`stats values()`とか`stats list()`でいったん出力してざっとみるとわかりやすい時がある。


##結果

```sql:access_state_output.spl
index=tutorial sourcetype="access_combined_wcookie" (clientip=87.194.216.51 OR clientip=211.166.11.101) status!=200
| stats list(file) as file list(status) as status by clientip
| eval tmp=mvzip(file,status)
| stats values(clientip) as clientip by tmp
| mvexpand clientip
```

| tmp | clientip |
|:--|:--|
| anna_nicole.html,404 | 211.166.11.101 |
| anna_nicole.html,404 | 87.194.216.51 |
| cart.do,400 | 211.166.11.101 |
| cart.do,400 | 87.194.216.51 |
| cart.do,403 | 87.194.216.51 |
| cart.do,406 | 211.166.11.101 |
| cart.do,406 | 87.194.216.51 |
| cart.do,408 | 211.166.11.101 |
| cart.do,408 | 87.194.216.51 |
| cart.do,500 | 211.166.11.101 |

IPアドレスを変えているけど、同じ人がやってそうな雰囲気がする。

#不正なproductIdを調べる

```sql:status_invalid.spl
index=tutorial sourcetype="access_combined_wcookie" (clientip=87.194.216.51 OR clientip=211.166.11.101) status!=200
```
これで調べると`productId`のフィールドの詳細が`SF-BVS-G01`と出てくる。

```spl:invalid_productId.spl
index=tutorial sourcetype="access_combined_wcookie" (clientip=87.194.216.51 OR clientip=211.166.11.101) productId="SF-BVS-G01"
| reverse
```
戻って、こちらで検索すると`categoryId`が`NULL`となっており、なんか設定に問題がありそう。

#購買数の多い商品を調べる
```sql:must_buy.spl
index=tutorial sourcetype="access_combined_wcookie" action=purchase
| eval prod_cat=categoryId.":".productId
| stats count by clientip prod_cat
| stats sum(count) as total dc(clientip) as clientip by prod_cat
| untable prod_cat type count
```
今度は指向を変えて、数えてみる
この頃はなんでもトレリス表示

##結果

| prod_cat | type | count |
|:--|:--|--:|
| ACCESSORIES:WC-SH-A01 | clientip | 108 |
| ACCESSORIES:WC-SH-A01 | total | 182 |
| ACCESSORIES:WC-SH-A02 | clientip | 127 |
| ACCESSORIES:WC-SH-A02 | total | 205 |
| ARCADE:BS-AG-G09 | clientip | 106 |
| ARCADE:BS-AG-G09 | total | 151 |
| ARCADE:FI-AG-G08 | clientip | 104 |

![stats_trellis.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/2097eb9f-84b1-14c2-59a7-f76f000e1160.png)

`stats by`の第一引数を動かさなければ、`xyseries`、`untable`しても問題ないとは。

##解説

- 後々の縦横変換のため、一緒にでてくるフィールドは`eval`でまとめてあげると楽
- ２つ目の`stats`の結果を`untable`してあげると、`trellis`表示向けになる。
- 一括で表示する場合はいらない。

#まとめ
`trellis`表示の練習にはちょうどいいと思いました。

[Using Subsearh](https://docs.splunk.com/Documentation/Splunk/8.0.4/SearchTutorial/Useasubsearch)があんまり良い例文じゃないのは、subsearch自体がチュートリアルじゃないよねってことなんでしょうね。