見出し画像

TWSNMPとGrafanaの連携(1)

TWSNMPのポーリング結果やAIの分析結果をInfluxdb経由でGrafanaのダッシュボードに表示する機能を作った話を書きます。長くなりそうなので何回かに分けます。

かっこいいダッシュボードを作りたい

TWSNMPにもグラフを表示する機能はあります。しかし、いくつかのポーリング結果をまとめて1つのグラフにしたり、いくつかのグラフを思い通りに並べて表示するダッシュボードを作る機能はありません。この機能を追加したい気持ちもありますが、でもGrafanaというソフト

を使えば、かっこいいダッシュボードを簡単に作ることができます。中途半端なものを作るよりは、Garafanaと連携することにしました。
こんな感じのダッシュボードが作れます。

画像2

連携のために必要なこと

Grafanaは、いくつかのデータソース

のデータをダッシュボードに表示できます。この中のどれかのデータソースにTWSNMPからデータを登録する方法がわりと簡単に連携を実現できそうです。利用するデータソースは、GO言語で開発されている Influxdb

を使うことにしました。
連携する仕組みは、

画像1

のような感じになります。

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組み込むための要点は押さえたので準備完了です。

つづく



開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。