🐨コアラでもわかるSplunkシリーズ　時間毎集計する

やあ、みんな　:koala:だよ
いつもの作者は「記事の内容がよくわからない」と言われて凹んだので、僕が呼ばれたよ
よろしくね。 
今回はみんながよく使う`timechart`コマンドを説明するよ。
Macosxで動かしているので、WindowsやLinuxの人はディレクトリやフォルダを読み替えてね。

#今回使うもの
<img width="1392" alt="スクリーンショット 2020-05-11 20.31.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/3592e332-a36f-139b-ab44-b1e2c997f313.png">
:koala:今回は、この起動した時のそのままの画面を使用するよ。
真っ黒い背景にSPL（エス・ピー・エル）を書いていくので、それを<font color="red">**赤枠**</font>の中、`ここにサーチを入力．．．`と書いているところにコピー＆ペーストしてもらって、🔍をクリックすると動くよ

:koala:時間:`過去２４時間`やモード:`スマートモード`は変更しないでね

#timechartについて
:koala: Splunk>docsは[こちら](https://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Timechart)
>対応する統計量の表を持つ時系列チャートを作成します。

だって。

:koala:基本的な構文は

|コマンド|集計かeval|by|列で分割するフィールド|
|:-:|:-:|:-:|:-:|
|timechart | count | by | host|

になるよ。　オプションでよく使うのは

オプション|説明
|:-:|:-:|
|span|集計する時間間隔<br/> _過去２４時間_の検索だと `span=30min`となる。
|limit|表示する列数、その以外の列は_OTHER_として集計<br/>デフォルトだと11以上の列は_OTHER_となる。
|useother|_OTHER_を表示を制御。<br/>limitで制限していなければ全ての列の表示となる

かな。
#基本的な使い方
```sql:count_internal.spl
index=_internal
| timechart count as Counts
```
| _time | Counts |
|:--|--:|
|2020/05/09 06:00:00|8700|
|2020/05/09 06:30:00| ...|

:koala:とても簡単な検索。`index=_internal`はSplunk自体のログで指定した時間、今回だと_過去２４時間_で数えてる。

:koala:あとあと使うときはコマンドの名前は変更したほうがいいよね。
#基本的な使い方(byで区切る）
```sql:count_internal_by.spl
index=_internal
| timechart count as Counts by sourcetype
```
| _time | mlspl-3 | mongod | scheduler | splunk_archiver-2 | splunk_web_access | splunk_web_service | splunkd | splunkd_access | splunkd_stdout | splunkd_ui_access | OTHER |
|:--|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|
| 2020/05/09 06:00:00 | 0 | 0 | 1 | 1 | 0 | 0 | 8676 | 22 | 0 | 0 | 0 |
| 2020/05/09 06:30:00 | 0 | 0 | 1 | 1 | 0 | 0 | 8676 | 22 | 0 | 0 | ...|

:koala:さっきと少し変えて`by sourcetype`をつけて検索すると、`soucetype`で列が区切られた表ができたよ。

:koala:`soucetype`の値が１０以上あるから、数が少ないものは`OTHER`でまとめられているね。
#基本的な使い方(limitで区切る)
```sql:count_internal_limit.spl
index=_internal
| timechart limit=5 count as Counts by sourcetype
```

| _time | mongod | splunk_web_service | splunkd | splunkd_access | splunkd_ui_access | OTHER |
|:--|--:|--:|--:|--:|--:|--:|
| 2020/05/09 06:00:00 | 0 | 0 | 8676 | 22 | 0 | 2 |
| 2020/05/09 06:30:00 | 0 | 0 | 8676 | 22 | 0 | ... |

:koala:今度はさっきの検索に`limit`をつけてみたよ。表示する列を制限できているのがわかるよね。

#基本的な使い方(usuotherでOTHERを消す)
```sql:count_internal_useother_F.spl
index=_internal
| timechart limit=5 useother=false count as Counts by sourcetype
```

| _time | mongod | splunk_web_service | splunkd | splunkd_access | splunkd_ui_access 
|:--|--:|--:|--:|--:|--:|--:|
| 2020/05/09 06:00:00 | 0 | 0 | 8676 | 22 | 0 |
| 2020/05/09 06:30:00 | 0 | 0 | 8676 | 22 | ...|

:koala: 今度はさっきの検索に`useother=false`をつけてみたよ。_OTHER_がなくなったよね。

#基本的な使い方(limitなしでusuotherでOTHERを消す)
```sql:count_internal_useother_no_limit.spl
index=_internal
| timechart  useother=false count as Counts by sourcetype
```

| _time | mlspl-3 | mongod | scheduler | splunk_archiver-2 | splunk_web_access | splunk_web_service | splunkd | splunkd_access | splunkd_stdout | splunkd_ui_access | 
|:--|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|
| 2020/05/09 06:00:00 | 0 | 0 | 1 | 1 | 0 | 0 | 8676 | 22 | 0 | 0 | 
| 2020/05/09 06:30:00 | 0 | 0 | 1 | 1 | 0 | 0 | 8676 | 22 | 0 | ... | 


:koala: 今度はさっきの検索から` limit`をはずしてみたよ。
[基本的な使い方(byで区切る）][1]の結果から_OTHER_がなくなったよね。

:koala:**ただなくなっただけだから全部の値を表示しているわけではないよ。**

 [1]:https://qiita.com/toshikawa/items/8fa44753bc8f2a4c9cb0#%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B9by%E3%81%A7%E5%8C%BA%E5%88%87%E3%82%8B

#基本的な使い方(全ての値を表示)
```sql:count_internal_no_limit.spl
index=_internal
| timechart  limit=0 count as Counts by sourcetype
```

| _time | mlspl-3 | mongod | scheduler | splunk_archiver-2 | splunk_btool | splunk_web_access | splunk_web_service | splunkd | splunkd_access | splunkd_conf | splunkd_stderr | splunkd_stdout | splunkd_ui_access |
|:--|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|
| 2020/05/09 06:00:00 | 0 | 0 | 1 | 1 | 0 | 3 | 4 | 9299 | 61 | 0 | 0 | 0 | 843 |
| 2020/05/09 06:30:00 | 0 | 0 | 1 | 1 | 0 | 3 | 4 | 9299 | 61 | 0 | 0 | 0 | ... |

:koala: `soucetype`は１３種類あったんだね。`limit=0`で全部表示してくれたよ。

#応用編（evalとuntable)
:koala:さっきまでで基本的な使い方は大丈夫だよね。
これからは応用編。いきなりすごい事になってるけど気にしないでね。

```sql:eval_untable.spl
index=_internal
| timechart limit=5 useother=f span=10min count as Counts by sourcetype
| untable _time sourcetype Counts
| timechart span=1h eval(round(avg(Counts),0)) by sourcetype
```

| _time | mongod | splunk_web_service | splunkd | splunkd_access | splunkd_ui_access |
|:--|--:|--:|--:|--:|--:|
| 2020/05/09 07:00 | 0 | 2 | 3082 | 15 | 235 |
| 2020/05/09 08:00 | 22 | 45 | 3162 | 47 | 393 |
| 2020/05/09 09:00 | 43 | 89 | 3343 | 182 | ... |

:koala:`timechart`は`eval`が使えるんだ！と言いたいだけなのに、なんでこんなクエリー作っちゃうんだろう。説明がたいへんだよ・・・。

:koala:ちょうどいいから`untable`も説明してみよう。

##timechartとuntableとstats

:koala:いきなりだけど、次の２つの検索をやってみて、結果を比べて欲しいな。

```sql:timechart_untable.spl
index=_internal
| timechart limit=5 useother=f span=10min count as Counts by sourcetype
| untable _time sourcetype Counts
```

```sql:bin_stats.spl
index=_internal
| bin _time span=10min
| stats count as Counts by _time sourcetype
```

| _time | sourcetype | Counts |
|:--|:--|--:|
| 2020/05/09 07:00:00 | splunk_web_access | 3 |
| 2020/05/09 07:00:00 | splunk_web_service | 4 |
| 2020/05/09 07:00:00 | splunkd | 3101 |
| 2020/05/09 07:00:00 | splunkd_access | 28 |
| 2020/05/09 07:00:00 | splunkd_ui_access | ... |


:koala:出てきた結果の列は一緒だね。
でも **`timechart`は５つのsourcetypeの１０分毎の数がでているのに、`stats`はない時間やsourcetypeも時間によってはないよね**

:koala:このように **`timechart`は指定した時間で表を作ってくれるんだ。これが`timechart`の特徴なんだよ。**

:koala:なので検索する時には、単純にログに書かれている時間だけを集計したいのか、それとも特定の時間内での数を集計したいのかで`timechart`と`bin` `stats`使い分けるといいよ。

:koala:`timechart`は普通に使っていると表示の制限がかかっているので、間違いやすいというとこもあるよ。

:koala: `untable`のことを話していないって？

| _time | mongod | splunk_web_service | splunkd | splunkd_access | splunkd_ui_access |
|:--|--:|--:|--:|--:|--:|
| 2020/05/09 07:00 | 0 | 2 | 3082 | 15 | 235 |
| 2020/05/09 08:00 | 22 | 45 | 3162 | 47 | 393 |

:koala:このあと、この数字をいろいろ加工しようとした時、困っちゃうから、`untable`しようね。

:koala:`timechart`の後はこれ、と覚えるといいよ。

|コマンド |引数１|引数２|引数3|
|:-:|:-:|:-:|:-:|
|untable| _time |timechart byの引数|値の列名|

:koala: 詳しい話は[Splunk>docs](https://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Untable)を読んでね。

##eval
:koala:ようやく`eval`に戻ってきた。

```sql:eval_untable.spl
index=_internal
| timechart limit=5 useother=f span=10min count as Counts by sourcetype
| untable _time sourcetype Counts
| timechart span=1h eval(round(avg(Counts),0)) by sourcetype
```

:koala:前の話が長すぎて忘れちゃったから、も一回だすね。

:koala:このクエリーはいったん10分毎集計して、１時間毎の平均を出しているんだ。
:koala:`timechart`は`eval`が使えるから、`avg()`を使っても数字がきれいにできるんだよ。

>If you use an eval expression, the split-by clause is required.
eval式を使用する場合はsplit-by句が必要です。

なので、`by`で列を分ける時に使えるんだよ

##合計値に対してのパーセント
:koala:パーセント表示がみんな好きそうだから、やり方を書いておくね

```sql:percent.spl
index=_internal
| timechart limit=5 useother=f span=1h count as Counts by sourcetype
| untable _time sourcetype Counts
| eventstats sum(Counts) as total by sourcetype
| eval perc = round(Counts / total * 100,2)."%"
```

:koala:いったん`timechart`で時間毎の表を作った後`untable`して、`eventstats`で合計を計算するんだ。

:koala:あとは`eval`で計算するとパーセントがでるよ。

:koala:お好みで`table`とか使って綺麗にしてね。

:koala:これを`stats`で作ると、[さっき](https://qiita.com/toshikawa/items/8fa44753bc8f2a4c9cb0#timechartとuntableとstats)説明したとおり、ない時間とかができるから、あんまりよくないよね。

#まとめ
:koala:いろいろと話してきたけど、大丈夫かな？

:koala:`timechart`はもっといろいろなことができるんだけど、これ以上話すと👹が出てきそうなのでやめとくね。

:koala:じゃ、またね〜

:koala:リクエストまってま〜す

-----
:sweat:SPLはガチなので、結構わかりづらいかもしれない。