Samplerとは
最近のWebアプリの多くには、「ダッシュボード」と呼ばれるUIが用意されています。ダッシュボードとは本来、車の計器盤を指す言葉です。車のダッシュボードにはスピードメーターやタコメーター、燃料計、水温計などが配置されており、ドライバーが車の状態を瞬時に把握できるようになっています。
Webアプリにおけるダッシュボードも車のそれと同じで、現状のデータを可視化するためのツールです。ダッシュボードには様々なウィジェットやメトリクスが配置されており、サービスの状態を俯瞰できるように構成されています。また本当に必要とする情報だけを集約できるよう、ダッシュボードはユーザーが自由にカスタマイズできるのが一般的です。
図1 サーバーモニタリングサービス「Datadog」のKubernetes Dashboardの例。クラスターを構成するノードや稼働中のコンテナ、CPUやメモリの負荷などを一目で把握できるようになっている。
Webアプリ上に用意されているダッシュボードは、当然ですがそのアプリの状態しか見ることができません。そうしたアプリ固有のダッシュボードではなく、自分のPC上に、自分が必要とする情報だけを集約できるダッシュボードがあったら便利だと思いませんか。さらに「サーバーと黒い画面だけが友達さ」という諸兄にとっては、ターミナル上にダッシュボードを構築したいと思うことでしょう。思わないですか? まあここは話の都合上、そう思っておいてください。
今回紹介するSamplerは、任意のシェルコマンドを実行し、その結果をターミナル上でメトリクス化できるツールです。Samplerを使うことで、ターミナル上に独自のダッシュボードを作ることができるのです。
ただしSamplerは本格的な監視ツールではなく「セットアップが容易な開発ツール」という位置づけのため、PrometheusやZabbixを置き換えることを期待しないでください。筆者の個人的な感想ですが、そうしたモニタリングツールよりもConkyに近いツールではないかと思います。
Samplerのインストール
SamplerはGo言語製のツールです。Ubuntu向けのパッケージがないため、GitHubのリリースページからバイナリをダウンロードして、実行権限を付与するのが簡単でしょう。本記事執筆時点の最新バージョンは1.1.0です。
ホームディレクトリ内にsamplerをインストールする例
$ curl -Lo ~/bin/sampler https://github.com/sqshq/sampler/releases/download/v1.1.0/sampler-1.1.0-linux-amd64
$ chmod +x ~/bin/sampler
コンフィグの用意
Samplerを実行する前に、コンフィグファイルを用意しましょう。コンフィグファイルがない状態でsamplerコマンドを実行すると、以下のようなエラーを表示してSamplerは終了します。
コンフィグファイルを指定せずsamplerコマンドを実行した場合
$ sampler
Please specify config file using --config flag. Example: sampler --config example.yml
SamplerのコンフィグファイルはYAMLで記述します。ここでは例として、PCのロードアベレージをグラフ化してみましょう。以下の内容を~/.sampler.configとして保存してください。
/proc/loadavgから過去1分、5分、15分のロードアベレージを取得して折れ線グラフにするコンフィグ
runcharts: # Runchartを定義する
- title: Load Average # グラフのタイトル
rate-ms: 1000 # 値を取得するサンプリングレート(ms、デフォルトは1000)
scale: 2 # 小数点以下のスケール(デフォルトは1)
legend:
enabled: true # グラフ内の各アイテムのラベルを表示する(デフォルトはtrue)
details: true # 各アイテムの現在値、最大値、最小値、差分を表示する(デフォルトはtrue)
items: # グラフに表示するアイテムの定義
- label: 1min # アイテムのラベル
sample: cut -d ' ' -f 1 /proc/loadavg # 実行するコマンド
- label: 5min
sample: cut -d ' ' -f 2 /proc/loadavg
- label: 15min
sample: cut -d ' ' -f 3 /proc/loadavg
作成したコンフィグファイルは、–configオプションでsamplerコマンドに渡します。
コンフィグを指定してsamplerを実行する
$ sampler --config ~/.sampler.config
図2 ロードアベレージをグラフ化した状態
表示できるコンポーネント
Samplerでは前述の例にあるRunchartの他にも、以下のようなコンポーネントを表示できます。
Sparkline
Sparklineは値の変化を可視化することに特化した、小さな棒グラフです。ここではpsコマンドで全プロセスのCPU使用率を表示し、awkで加算した値を利用しています。
全プロセスのCPU使用率の合計を表示する例
sparklines:
- title: CPU usage
rate-ms: 200
scale: 1
sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'
図3 0.2秒ごとにCPU使用率の変化をプロットする
Barchart
Barchartはいわゆる棒グラフです。Runchartと同様に、複数のアイテムを並べて比較するような用途に便利です。
Chromium、Firefox、Emacsそれぞれの使用メモリを表示する例。指定したプロセスが存在しない場合に値が返せずエラーとなってしまうため、本来であればプロセスが存在しなかった場合は0を返すようなラッパースクリプトを用意するのが望ましい
barcharts:
- title: Memory usage by process
rate-ms: 1000
scale: 1
items:
- label: Chromium
sample: ps ux | grep '[c]hromium-browser' | awk '{s+=$6} END {print s}'
- label: Firefox
sample: ps ux | grep '[f]irefox' | awk '{s+=$6} END {print s}'
- label: Emacs
sample: ps ux | grep '[e]macs' | awk '{s+=$6} END {print s}'
図4 Chromium、Firefox、Emacsそれぞれの使用メモリを表示した例
Guage
Guageは最大値、最小値、現在値を指定することで、現在値が全体の何%にあたるのかを表示できます。たとえばディスクの空き容量や、プログレスバーなどでの利用が考えられます。
/と/homeのディスク使用量をグラフ化する例。最小値は0に決まっており、かつdfコマンドからは取得できない値のため、echoコマンドで0を出力している。sampleに設定するのは値ではなく実行するシェルコマンドのため、0とだけ書くことはできない
gauges:
- title: Used Disk Space [/]
rate-ms: 1000
scale: 1
percent-only: 5
cur:
sample: df / | tail -n 1 | awk '{print $3}'
max:
sample: df / | tail -n 1 | awk '{print $2}'
min:
sample: echo 0
- title: Used Disk Space [/home]
rate-ms: 1000
scale: 1
percent-only: true
cur:
sample: df /home | tail -n 1 | awk '{print $3}'
max:
sample: df /home | tail -n 1 | awk '{print $2}'
min:
sample: echo 0
図5 /と/homeのディスク使用量をグラフ化した例
Textbox
Textboxはその名の通り、文字を表示するためのコンポーネントです。特定のコマンドの実行結果をそのまま表示したいような場合に有効です。
テキストで天気予報を表示できるwttr.inをcurlで叩いた結果と、おじさんがLINEやメールで送ってきそうな文を生成するojichatコマンドを埋め込んでみた例
textboxes:
- title: Sapporo
position: [[0, 0], [28, 10]]
rate-ms: 10000
sample: curl 'wttr.in/sapporo?0ATQF&lang=ja'
- title: Tokyo
position: [[29, 0], [28, 10]]
rate-ms: 10000
sample: curl 'wttr.in/tokyo?0ATQF&lang=ja'
- title: Ojichat
position: [[0, 11], [80, 13]]
rate-ms: 5000
sample: docker run --rm ojichat
図6 日本語や絵文字も表示できる
Asciibox
AsciiboxもTextboxと同様に、コマンド実行結果の文字列を表示するコンポーネントです。Textboxとの違いは、文字をアスキーアートで表示する点です。ダッシュボード上で目立たせたい文字を表示する場合に便利ですが、アスキーアート化する都合上、日本語は表示できません。
現在時刻を表示する例。日本語を含んだ文字列は表示できないため、LANG=Cで実行している
asciiboxes:
- title: Local time
rate-ms: 1000
font: 3d
border: false
sample: LANG=C date +%r
図7 現在時刻を3Dアスキーアートで表示した例
レイアウトの調整
Samplerはターミナルのサイズや複数のコンポーネントの兼ね合いを考え、自動的にコンポーネントの位置とサイズを調整して表示します。しかし、せっかくですから自分好みにコンポーネントの位置やサイズを調整したいですよね。そのためにはコンフィグファイルにpositionを記載します。positionは以下の書式で指定します。
コンポーネントの位置とサイズを指定する書式
position: [[X座標, Y座標], [幅, 高さ]]
ターミナルの左上隅から、80x15の大きさでRunchartを表示する例
runcharts:
- title: Load Average
position: [[0, 0], [80, 15]]
rate-ms: 200
scale: 2
(...略...)
ですが、実際にターミナル上にコンポーネントを表示させながら、現物あわせで調整したい場合もあるでしょう。Samplerは実行中のコンポーネントの移動とリサイズに対応しています。
Samplerを実行している状態で、位置やサイズを変更したいコンポーネントをマウスでクリックして選択してください。その状態でEnterキーを押すと、「MOVE」「RESIZE」「RESUME」というメニューが表示されます。ここで「MOVE」もしくは「RESIZE」を選択すると、カーソルキーでコンポーネントを移動/リサイズできるようになります。好みの位置やサイズに調整ができたら、Enterキーで調整を終了します。この際、コンフィグファイルには自動的にpositionが追記されるため、次回起動時には同じレイアウトが再現されます。
ここで一点気をつけなければならないことがあります。コンポーネントの位置を調整してコンフィグファイルの上書きが発生した場合、コンフィグファイル内のコメント行がすべて消えてしまうという問題があります。一時的に設定をコメントアウトしているような場合にこれが発生すると、それらの設定は失われてしまうため気をつけてください。
このように、Samplerはターミナル上で任意の情報をメトリクス化することができます。様々なシェルコマンドと組み合わせて、君の考えた最強のダッシュボードを作ってみよう!
図8 紹介したコンポーネントを組み合わせてダッシュボードを作成してみた