ターミナルで簡単にグラフを描くツール termeter

ターミナル上で簡単にグラフを描くために[termeter](https://github.com/atsaki/termeter)というツールを作成してみました。

## Getting Started

termeterは通常のコマンドラインツールとして使用することができます。タブ区切りやカンマ区切りのデータを標準入力かファイルであたえることでグラフを描く事ができます。

例として以下のような三角関数のタブ区切りのデータを考えます。

```bash
$ seq 100 | awk 'BEGIN{OFS="\t"; print "x","sin(x)","cos(x)"}{x=$1/10; print x,sin(x),cos(x)}' | head
x	sin(x)	cos(x)
0.1	0.0998334	0.995004
0.2	0.198669	0.980067
0.3	0.29552	0.955336
0.4	0.389418	0.921061
0.5	0.479426	0.877583
0.6	0.564642	0.825336
0.7	0.644218	0.764842
0.8	0.717356	0.696707
0.9	0.783327	0.62161
```

これをtermeterコマンドにパイプで渡すとターミナル上でグラフを描く事ができます。
（グラフはキーボードのqを押すと閉じる事ができます。）

```bash
$  seq 100 | awk 'BEGIN{OFS="\t"; print "x","sin(x)","cos(x)"}{x=$1/10; print x,sin(x),cos(x)}' | termeter
```

![スクリーンショット 2015-03-24 0.33.34.png](https://qiita-image-store.s3.amazonaws.com/0/15114/d838dbcd-5629-3f7c-da0e-710a899dac20.png)

また、```tail -f``` コマンドのように出力が追加されていくコマンドをパイプすればリアルタイムに更新されるグラフを描く事ができます。（デモは一部文字化けしていますが、実際にはきれいに表示されると思います。）

```bash
$ seq 300 | awk 'BEGIN{OFS="\t"; print "x","sin(x)","cos(x)"}{x=$1/10; print x,sin(x),cos(x); system("sleep 0.1")}' | termeter
```

<a href="https://asciinema.org/a/18127"><img src="https://asciinema.org/a/18127.png" /></a>


## インストール

```go get``` でインストールできます。

```bash
$ go get github.com/atsaki/termeter/cmd/termeter
```

## 使い方

### データの入力

標準入力かファイルでデータを入力する事ができます。

```bash
$ seq 100 | termeter
$ se1 100 > 100.txt; termeter 100.txt
```

### データのフォーマット

データはタブ、スペース、カンマ等の特定の文字列で区切られている必要があります。
区切り文字は```-d``` オプションで指定する事が可能です。（デフォルトはタブ）

1行目の値はラベルとして使用されます。

```bash
# カンマを区切り文字として指定。-d の後にスペースを入れる必要があるので注意
$ seq 100 | awk 'BEGIN{print "x,y"}{print $1","$1}' | termeter -d ,
# スペースを区切り文字として指定。
$ seq 100 | awk 'BEGIN{print "x y"}{print $1,$1}' | termeter -d " "
```

データのそれぞれの列についてグラフが作成されます。
（オプションとして```-L first``` をつけると1列目のデータを線グラフの横軸のラベルとして使用する事ができます。）

```bash
$  seq 100 | awk 'BEGIN{OFS="\t"; print "x","sin(x)","cos(x)"}{x=$1/10; print x,sin(x),cos(x)}' | termeter -L first
```
![スクリーンショット 2015-03-29 8.05.15.png](https://qiita-image-store.s3.amazonaws.com/0/15114/98e6149b-6255-aa12-1ba9-0010b55d118b.png)


### グラフの種類

現在以下の3つの種類が使用可能です。

* LINE
  * 値を縦軸にプロットした線グラフ
* COUNTER
  * 値の出現回数の棒グラフ
* CDF
  * 値の分布関数。

デフォルトではデータの2行目の値によってグラフの種類が選択されます。値が数値である場合にはLINE、数値でない場合にはCOUNTERが選択されます。
明示的にグラフの種類を選択したい場合には```-t``` オプションを使用します。
```-t``` オプションは引数に文字列をとり、n文字めでn番目のグラフの種類を指定します。(LINEはl、COUNTERはc、CDFはdで指定します。それ以外の文字の場合には自動選択となります。）

例として以下のサイコロの目のデータを別々の種類のグラフとして描画してみます。

```bash
$ (echo "line counter cdf"; seq 1 1000 | awk '{x=int(6*rand())+1; print x,x,x}') | head
line counter cdf
6 6 6
3 3 3
5 5 5
5 5 5
6 6 6
2 2 2
3 3 3
5 5 5
2 2 2
```

このデータをLINE,COUNTER,CDFで表示すると以下のようなグラフとなります。
（```-S numerical``` は棒グラフをソートするためのオプションです。）

```bash
$ (echo "line counter cdf"; seq 1 1000 | awk '{x=int(6*rand())+1; print x,x,x}') | termeter -d " " -t lcd -S numerical
```

![スクリーンショット 2015-03-28 11.33.58.png](https://qiita-image-store.s3.amazonaws.com/0/15114/653ddf3a-bc0f-6f76-f39f-984bd33eaff4.png)


## ユースケース

#### statファミリ

[dstat](https://github.com/dagwieers/dstat), vmstatなどの出力を簡単にグラフにすることができます。

Mackerel等のモニタリングサービスの監視間隔よりも短い間隔の変化をとらえたい場合や監視に追加していないメトリクスをちょっと見たい場合に便利だと思います。

dstatの場合の例を示します。
```--output``` でCSVとして結果を出力させ、それを```tail -f``` を使って渡しています。```-n +7``` はデータ以外の部分を読み飛ばすために付けています。

```bash
$ dstat --cpu --output dstat.log > /dev/null &
$ tail -f -n +7 dstat.log | termeter -d ,
```

<a href="https://asciinema.org/a/18129"><img src="https://asciinema.org/a/18129.png" width="1189"/></a>

#### ダッシュボード

termeterはGo言語を使ってダッシュボードを作成できるライブラリ[termui](https://github.com/gizak/termui)を使って実装されています。

termuiを利用したダッシュボードの作成は難しくありません（[example](https://github.com/gizak/termui/tree/master/example) を参照）が、表示したいデータをファイルに集めtermeterで表示することでコードを書かずに簡易的なダッシュボードとして利用する事ができます。

## リンク

* https://github.com/atsaki/termeter