GrafanaでMySQLのデータを可視化する in Docker (in WSL2)

# About
- [Grafana](https://grafana.com) は、様々なデータを可視化してくれるダッシュボードツールです
- 本記事では、ローカル環境上ででサクッと試してみます
  - GrafanaとMySQLのコンテナをDocker上で用意する
  - MySQLで適当なデータベースを作る
  - Grafanaでそのデータを表示する
  - (Grafanaへのユーザ登録やログインは不要です)

# 環境
- Windows 11 Home
- WSL2 (Ubuntu-20.04)
- Docker 

# MySQLでデータベースを作る
## MySQLコンテナを作る
下記コマンドによってMySQLコンテナを作ります。簡易的にデータ永続化をするために、ここではローカルに `db` というディレクトリを作ってそれをマウントしています。これによって、コンテナを作り直してもデータベースが保持されます。また、アクセス権限を設定しないとrootで書き込まれてしまうため、userを指定しています。

WSL2上で試す場合、`--net host` が必要でした。なお、Windows Firewallは特に無効にしなくても大丈夫でした。

```sh:MySQLコンテナの作成
mkdir ./db

docker run --name some-mysql \
  --user `id -u` \
  -v `pwd`/db:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=pw-for-root \
  --net host \
  -p 3306:3306 \
  -d --rm mysql:8.0.30
```

## MySQLの設定をする
下記コマンドで作成したコンテナに入ります。パスワードは `pw-for-root` です。

```sh:MySQLに入る
docker exec -it  some-mysql mysql -u root -p
```

その後、下記SQL文によって後で使うGrafana用のユーザを作っておきます。GrafanaにはSELECTのみ許可します。ワイルドカードを使わないでちゃんとデータベース名とテーブル名を指定した方が安全です。

```sql:Grafana用ユーザ追加
CREATE USER 'grafanaReader' IDENTIFIED BY 'pw-for-grafana';
GRANT SELECT ON *.* TO 'grafanaReader';
```

## サンプルデータベースを作る
引き続き、下記SQL文によって適当なデータベースを作ります。ここでは通常のtableと、時系列のtableを作ります。
終わったら、Ctrl+dで終了してOKです。

```sql:サンプルデータベースを作る
CREATE DATABASE IF NOT EXISTS test_db;
CONNECT test_db;

CREATE TABLE user_table (
    id int(10) AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(20)
);

INSERT INTO user_table(name) VALUES ('Alice');
INSERT INTO user_table(name) VALUES ('Bob');
INSERT INTO user_table(name) VALUES ('Charlie');


CREATE TABLE time_table (
    id int(10) AUTO_INCREMENT PRIMARY KEY,
    data_time DATETIME,
    value int
);

INSERT INTO time_table(data_time, value) VALUES ('2022-01-02 16:00:00', 10);
INSERT INTO time_table(data_time, value) VALUES ('2022-02-02 16:00:00', 20);
INSERT INTO time_table(data_time, value) VALUES ('2022-03-02 16:00:00', 30);
INSERT INTO time_table(data_time, value) VALUES ('2022-04-02 16:00:00', 40);
INSERT INTO time_table(data_time, value) VALUES ('2022-05-02 16:00:00', 30);
INSERT INTO time_table(data_time, value) VALUES ('2022-06-02 16:00:00', 20);

SELECT * FROM user_table;
SELECT * FROM time_table;
```

# Grafana
## Grafanaコンテナを作る
下記コマンドによってGrafanaコンテナを作ります。簡易的にデータ永続化をするために、ここではローカルに `grafana` というディレクトリを作ってそれをマウントしています。ここには各種設定が保存されます。

```sh:Grafanaコンテナの作成
mkdir ./grafana

docker run --name grafana \
  --user `id -u` \
  -v `pwd`/grafana:/var/lib/grafana \
  --net host \
  -p 3000:3000 \
  -d --rm grafana/grafana
```

## Grafanaへアクセスする
コンテナを起動したのと同じPC上で以下にアクセスします。

- URL: http://localhost:3000/
- Username: admin
- Password: admin

![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/2047fba1-9c6b-c34d-06e1-3e6d4dc98163.jpeg)


## Data sourcesの設定
- Configuration -> Data sources -> Add data sourceをクリック

![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/5a624a3b-3982-1c3c-f6f3-8781683ef5d0.jpeg)


- MySQLを選択

![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/c5825d34-36f2-8c44-5891-ab0567a48d10.jpeg)


- 下記設定を行う
  - Host: localhost:3306
  - Database: test_db
  - User: grafanaReader
  - Password: pw-for-grafana
- ページ下部の `Save & Test` をクリックして、 `Database Connection OK` が表示されることを確認する

![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/d05fa455-53f6-e2cb-d89d-f09f0bb151fe.jpeg)
![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/e32e3415-28e8-320b-3ab3-9859a757beef.jpeg)


## Dashboardの設定
- Dashboards -> Browse -> New -> New Dashboard をクリック
- Add a new pane をクリック

![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/f786b978-a392-53a6-e338-d274326708e9.jpeg)


### 通常のテーブルを追加する
- Format Asを `Table` に設定
- Edit SQLをクリックして、以下を入力

  ```sql
  SELECT * FROM user_table;
  ```

- 右上からTableを選ぶ。または、他の描画方法を選ぶ
- 設定が完了したら `Apply` をクリック

![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/40717303-5a7c-13ea-4391-de70f45e2962.jpeg)


### 時系列データを追加する
- Dashboard上に、先ほどのテーブルが追加されているので、引き続き、Add Panel -> Add a new panelをクリック
- Format Asを `Time series` に設定 (default)
- Edit SQLをクリックして、以下を入力

  ```sql
  SELECT
    data_time AS "time",
    value
  FROM time_table
  ```

- 時間レンジを過去1年間にする (これは今回作成したデータがそういうもののため)
- 設定が完了したら `Apply` をクリック

![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/f3ce66df-cda0-3c50-da3e-fc8d30b9aef8.jpeg)


### Dashboardを保存する
- Dashboard上でパネルをさらに追加したり、位置を調整する
- 最後にSaveしたら完成

![09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/43e5fe6a-5c49-4133-e75b-4d3050d120ce.jpeg)

# その他
- コンテナを再起動しても設定は保持されている
- MySQL側でデータを追加したら、Dashboardも更新される
- 時系列データを扱う場合にはMySQLよりもInfluxDB の方がいいらしい