TWSNMPとGrafanaの連携(1)
TWSNMPのポーリング結果やAIの分析結果をInfluxdb経由でGrafanaのダッシュボードに表示する機能を作った話を書きます。長くなりそうなので何回かに分けます。
かっこいいダッシュボードを作りたい
TWSNMPにもグラフを表示する機能はあります。しかし、いくつかのポーリング結果をまとめて1つのグラフにしたり、いくつかのグラフを思い通りに並べて表示するダッシュボードを作る機能はありません。この機能を追加したい気持ちもありますが、でもGrafanaというソフト
を使えば、かっこいいダッシュボードを簡単に作ることができます。中途半端なものを作るよりは、Garafanaと連携することにしました。
こんな感じのダッシュボードが作れます。
連携のために必要なこと
Grafanaは、いくつかのデータソース
のデータをダッシュボードに表示できます。この中のどれかのデータソースにTWSNMPからデータを登録する方法がわりと簡単に連携を実現できそうです。利用するデータソースは、GO言語で開発されている Influxdb
を使うことにしました。
連携する仕組みは、
のような感じになります。
Influxdbを試してみる
仕組みが決まったらまずはInfluxdbを試してみます。簡単に環境を作るのはGrafanaもまとめてDockerを利用することです。
適当なディレクトリにdocker-compose.ymlファイルを
version: "3"
services:
influxdb:
image: influxdb:latest
ports:
- "8086:8086"
volumes:
- ./influxdb/data:/var/lib/influxdb
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards
- ./grafana/datasources:/etc/grafana/provisioning/datasources
depends_on:
- influxdb
のような内容で作成して
docker-compose up -d
のコマンドを実行すれば、Influxdb(8086番ポート)とGrafana(3000番ポート)が起動でします。
docker-compose exec influxdb /bin/bash
というコマンドを実行すれば、Influxdbのコマンドが利用できる状態になります。この状態で
に書いてある最初の一歩を試してみることができます。うまく行けば準備完了。
GO言語からInfluxdbを利用する
TWSNMPはGO言語で作っているので、GO言語からInfluxdbを利用するパッケージを探す必要があります。単に検索すると
が見つかります。しかし、これは、Influxdbの新しいバージョン向けなの先程、Dockerで起動したGrafanaと連携するための現行のInfluxdbでは使えません。最初に試してみましたがうまく通信できなくて少し悩みました。このページをよく読むとInfluxdb 1.x向けのパッケージのリンクがありました。
このパッケージを使ってテストプログラムを動かしてみました。
func main() {
// クライアントを作成
c, err := client.NewHTTPClient(client.HTTPConfig{
Addr: "http://192.168.1.5:8086",
Timeout: time.Second * 5,
// Username: username,
// Password: password,
})
if err != nil {
log.Fatal(err)
}
defer c.Close()
//データベースの一覧取得
q := client.NewQuery("SHOW DATABASES", "", "")
if response, err := c.Query(q); err == nil && response.Error() == nil {
fmt.Printf("%#v\n", response.Results)
for _, r := range response.Results {
for _, s := range r.Series {
for _, ns := range s.Values {
for _, n := range ns {
if name, ok := n.(string); ok {
fmt.Println(name)
}
}
}
}
}
} else {
log.Fatal(err)
}
// データベースを作る
q = client.NewQuery("CREATE DATABASE "+MyDB, "", "")
if response, err := c.Query(q); err == nil && response.Error() == nil {
fmt.Printf("%#v", response.Results)
} else {
log.Fatal(err)
}
// 登録するデータの入れ物を作る
bp, err := client.NewBatchPoints(client.BatchPointsConfig{
Database: MyDB,
Precision: "s",
})
if err != nil {
log.Fatal(err)
}
// 登録するデータを入れ物にいれる
tags := map[string]string{"cpu": "cpu-total"}
fields := map[string]interface{}{
"idle": 10.1,
"system": 53.3,
"user": 46.6,
}
pt, err := client.NewPoint("cpu_usage", tags, fields, time.Now())
if err != nil {
log.Fatal(err)
}
bp.AddPoint(pt)
// データを登録する
if err := c.Write(bp); err != nil {
log.Fatal(err)
}
// クライアントを開放する
if err := c.Close(); err != nil {
log.Fatal(err)
}
}
割とスムーズに動作しました。このテストプログラムでTWSNMP組み込むための要点は押さえたので準備完了です。
つづく