MetabaseとMariaDBでたのしい可視化

# はじめに
チーム内で開発環境の様々なメトリクスを監視/可視化する取り組みをしています。

今回は隔離された環境に対する監視、可視化、通知の仕組みを作ろうとしていて、それ自体が結構大変で、別途記事を書こうと思いますが、今回はデータの格納と可視化部分にのみフォーカスして書きます。

どうでもいいですが最近チーム内に何か広めるときは先にqiitaに書いてから紹介するという手法を取っています。この記事もチーム内のMetabase使いたいけどよくわからんひとに向けて書いています。

# metabase
以下の記事で知って、さっそく使ってみたクチです。

[OSSのデータ可視化ツール「Metabase」が超使いやすい](https://qiita.com/acro5piano/items/0920550d297651b04387)

BIのための、データを可視化するツールです。

可視化に特化しているため、データベースは別途用意する必要がありますが、逆にデータベースにデータさえため込んでおけば、metabase側から好きな形で可視化することができます。

対応データソースは以下の通り。使い慣れたデータベースを使うことができるのでうれしいですね。

* BigQuery
* Crate
* Druid
* Google Analytics
* H2
* MongoDB
* MySQL
* PostgreSQL
* Presto
* Amazon Redshift
* SQlite
* SQL Server

([公式より](https://www.metabase.com))

で、今回は**使い慣れた**データベースということでMariaDBを用いました。

# 構築方法
docker-composeで立ち上げました。docker/docker-composeのインストール方法はどこか別の記事を参照してください。

```yaml:docker-compose.yml
version: '2'
services:
  web:
    image: metabase/metabase
    ports:
      - "3000:3000"
    links:
      - db:db
    depends_on:
      - db
    restart: always
  db:
    image: mariadb:10.2.12
    ports:
      - "3306:3306"
    volumes:
      - ./data/volumes:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root
    restart: always
```

MariaDBのデータは永続化しています。ファイルパスやポートはよしなに書き換えてください。

Metabaseのデータベース(H2)は永続化していないのでそのうちします。。。

MariaDBのrootパスワードは(よくないですが)environmentに持たせています。

```
# docker-compose up -d
```

# 接続方法
MetabaseからMariaDBへの接続です。

新規接続時、ユーザ登録後にデータベースの接続設定を入力することができます。すでにデータを格納しているデータベースがある場合接続しましょう。このようにBIツールとデータベースが完全に分離しているのでいいですね。後からでももちろん追加できます。

![metabase.png](https://qiita-image-store.s3.amazonaws.com/0/64903/0d763b91-d96b-eaf6-6c6b-8da2396df245.png)

データを匿名で送信するか？ってやつですね。断っておきました。

![metabase2.png](https://qiita-image-store.s3.amazonaws.com/0/64903/035d96ce-cadb-247f-e0b0-ac239cad3406.png)

さて、MetabaseではQuetionという単位でデータを扱います。上部のNew Questionをクリックし、Customを選択しましょう。

![metabase3.png](https://qiita-image-store.s3.amazonaws.com/0/64903/7ca2ff41-86bf-2148-d639-e90d14612b2a.png)

ここでは接続するテーブルを選択し、フィルタが必要ならフィルタすることで、データを見ることができます。まず通常通り、テーブルで表示しています。うんうん入ってるねーと見てください。

![metabase4.png](https://qiita-image-store.s3.amazonaws.com/0/64903/a10c1e54-63a1-1df1-6200-528d084df915.png)

Tableの部分を変えることで様々なデータの見方ができます。今回Lineを選択し、横軸をCreated_atにすることで、時系列の、あるストレージの使用状況がグラフにできました！楽ちんだ～！

![metabase5.png](https://qiita-image-store.s3.amazonaws.com/0/64903/09fd58b2-017c-59dc-a3de-f6779a1f21d1.png)

このQuestionはSaveしておくとあとからいつでも編集することができます。また、ここでDashboardに追加する？と聞かれるのでYesを選ぶとダッシュボードに追加されます。自分好みのダッシュボードが作れる点もアツいですね。

![metabase6.png](https://qiita-image-store.s3.amazonaws.com/0/64903/56a2d5f5-67c7-8833-58fd-50d698333da8.png)

# データ格納方法
データベースへのデータ格納方法はMetabaseと分離し、各データベースの方法に従うのですが、一応載せておきます。

まず、何らかの方法でストレージの空き容量をcsvファイルで取得します。

```csv:area1.csv
Name,Size[GiB],Available[GiB],Used[percent]
storage01,3516,3430,2
storage02,87013,20098,77
storage03,38152,6941,82
storage04,57228,17279,70
```

これは同時にチャット(mattermost)に通知もしています。

取得後、これをデータベースに格納します。
Python3.6で動作確認、pip install mysqlclientが必要。その依存でmysql_configコマンドが必要ですので、yumでmariadb-develをinstall。他、gccやpythonX.X-develも必要でした。コードのスタイルチェックにはpycodestyleを使いました。

```py3:insert.py
# coding:utf-8

import csv
import MySQLdb
import os

con = MySQLdb.connect(db="storage", user="root", passwd="root", host="127.0.0.1")
cur = con.cursor()
current_dir = os.path.dirname(os.path.abspath(__file__))

path2 = os.path.join(current_dir, "css", "style.css")

for area in ['area1', 'area2']:
    filename = area + ".csv"
    path = os.path.join(current_dir, filename)
    f = open(path, "r")

    reader = csv.reader(f)
    header = next(reader)

    for row in reader:
        sql = f"INSERT IGNORE INTO storage_{area}(name, size, available, used)" \
                                            + "values(%s,%s,%s,%s)"
        cur.execute(sql, (row[0], int(row[1]), int(row[2]), int(row[3])))
    f.close()

    con.commit()

cur.close()
con.close()
```

storageというDATABASEの、storage_area1/2 TABLEに、csvをそのまま突っ込んでいます。

csvを読み込んでinsertする部分を参考にしてください。[フォーマット文字列リテラル](http://codom.hatenablog.com/entry/2016/12/27/000000)を使いたかったのでPython3.6にしました。

MariaDB側では、時系列データがほしいので、テーブル作成時にcreated_atを作成しています。

```
MariaDB [storage]> show create table storage_area1;
+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table       | Create Table                                                                                                                                                                                                                                                 |
+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| storage_area1 | CREATE TABLE `storage_area1` (
  `name` varchar(20) DEFAULT NULL,
  `size` int(11) DEFAULT NULL,
  `available` int(11) DEFAULT NULL,
  `used` int(11) DEFAULT NULL,
  `created_at` datetime DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
```

1日1回、データ取得、チャット通知、DB格納をバッチ的に実行しています。

# おわりに
あんまり変化がなくておもしろくないですね。

![metabase7.png](https://qiita-image-store.s3.amazonaws.com/0/64903/552ae9f0-b67d-ff75-2688-457e6f61eb2e.png)

変化をたのしめるメトリクスをつっこんでくれるメンバーを募集中です。

installするだけでagent経由で勝手に取得してくれる便利な統合監視ソフトウェアはたくさんありますが、このように個別で手作りするのもいい勉強になりました。もっと楽にデータ格納できる方法もあるかもしれませんが、使い慣れた方法の組み合わせでできたので、特に苦労なく実現できました。

まだまだMetabase使いこなせてないので、データを増やして使いまくります。

以上です。