EmbulkとMetabaseでログを可視化してみよう

# はじめに
今日は OSS の Embulk と Metabase を使ってログを可視化していきたいと思います。
昨今よく見られる、Fluentd などで日々のログを蓄積して解析を行うのではなく、ある一日の Apache アクセスログをデータベースに投入して、アクセス状況などをグラフで確認できるように進めて行きたいと思います。

# Embulkとは
Fluentd 開発者の古橋氏が開発した Fluentd のバッチ版のようなツールで、ファイルやデータベースからデータを吸い出し（Input）、別のストレージやデータベースにロード（Ouput）するためのツールです。
今回は Apache アクセスログの吸い出しと MySQL へのインポートのために利用しています。

# Metabaseとは
Kibana や Re:Dash などと同じ、OSSのデータ可視化 / BIツールのひとつです。
グラフの種類が多く、MongoDB などの豊富なデータベースをサポートしていることが特徴として挙げられます。
また、クエリが使えなくても直感的にグラフ作成が出来るなど、非エンジニアでも利用しやすいツールです。

# 環境
|プロダクト名称|説明|
|---|---|
|Red Hat Enterprise Linux 7.6（AWS EC2)|OS|
|Java 1.8.0_192|Metabaseを動作させるために必要|
|MySQL Server 5.7.24|ログデータ格納用|
|Metabase 0.31.1|記事投稿時点での最新版|
|Embulk 0.9.11|アクセスログの吸出しとDBインポートで利用|

## 構成図
構築するサーバの簡単な構成と、データ処理のフローは以下のとおりです。
![SnapCrab_NoName_2018-12-7_21-18-5_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/316808/a967c81a-55cb-3676-d626-190420f9cbed.png)

# Metabase の導入手順
導入作業については root ユーザでの実施を前提としています。

## Java のインストール
rpm で Java をインストールします。

```
# rpm -ivh jdk-8u192-linux-x64.rpm
```
インストールした Java のバージョンを確認します。

```
# java -version
java version "1.8.0_192"
Java(TM) SE Runtime Environment (build 1.8.0_192-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.192-b12, mixed mode)
```

## MySQL のインストール
依存関係が多いので MySQL は yum でインストールします。

```
# yum -y install mysql-community-server
```
インストールしたMySQLのバージョンを確認します。

```
# mysqld --version
mysqld  Ver 5.7.24 for Linux on x86_64 (MySQL Community Server (GPL))
```

## Metabase の実行
Metabase の jar ファイルは <a href="https://www.metabase.com/">公式サイト</a> の <a href="https://www.metabase.com/start/other.html">Other platforms</a> から取得してきました。
作業ディレクトリは /opt/metabase としてダウンロードした metabase.jar を以下のように実行するだけで動作します。

```
# java -jar metabase.jar

※ Metabase 接続のデフォルトポートは3000ですが、変更したい場合は以下のようなコマンドで起動
# MB_JETTY_PORT=xxxx java -jar metabase.jar
```
いちいち実行するのも面倒なので、サービス化してしまいます。

```/etc/systemd/system/metabase.service
[Unit]
Description=Metabase server
After=syslog.target network.target

[Service]
User=root
Type=simple
WorkingDirectory=/opt/metabase
ExecStart=/usr/bin/java -jar /opt/metabase/metabase.jar
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=metabase
SuccessExitStatus=143
TimeoutStopSec=120
Restart=always

[Install]
WantedBy=multi-user.target
```
上記のように記載しましたら、自動起動を設定して起動させます。

```
# systemctl daemon-reload
# systemctl enable metabase
# systemctl start metabase.service
```

## 初期設定

起動が完了しましたら、http://localhost:3000/setup/ にアクセスすることで初期設定が可能です。作業は FireFox にて実施しています。
※ 導入時の最新版（0.31.1）では日本語化対応がされていますが、バグのためか IE では英語表記のみとなってしまうようです。

上記URLにアクセスすると、この Welcome ページが開くので、「開始しましょう」から進みます。
![Screen Shot 2018-11-29 at 15.47.41-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/67168008-1fae-f770-0f2b-eff88d4d442f.png)

ログインするためのアカウント情報を入力します。特に記載はありませんが全て必須項目です。
![Screen Shot 2018-11-29 at 16.06.54-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/dbd0e09c-1c7a-b856-e4ff-9436b7592eeb.png)

追加するデータベースを選択できます。後で追加・削除も可能です。ここでは指定せずに進めています。（追加方法については後述します。）
![Screen Shot 2018-11-29 at 16.10.05-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/9f9ddf0e-5915-399d-d9c3-1aea32dbe866.png)

データ収集についての同意確認がされますが、同意しなくとも問題ありません。
![Screen Shot 2018-11-29 at 16.10.17-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/28a46355-afc4-ea89-4182-1de67c290514.png)

設定が完了するとダッシュボード画面が表示されます。
![Screen Shot 2018-11-29 at 16.10.57-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/f86f161c-7ce5-421e-e46f-a94efd32503d.png)


引き続き、Embulk で Apache アクセスログを MySQL にインポートしていきます。

# Embulk の導入手順
こちらも Metabase と同様に root ユーザでの実施を前提としています。

## Embulk のインストール
Java で動作するツールとなります。

```
curl --create-dirs -o ~/.embulk/bin/embulk -L "https://dl.embulk.org/embulk-latest.jar"
chmod +x ~/.embulk/bin/embulk
echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```
インストールした Embulk のバージョンを確認します。

```
# embulk -v
Embulk v0.9.11
```

## プラグインのインストール
Embulk には様々な Input、Output に対応したプラグインがありますが、今回は Input が Apache アクセスログで、Output が MySQL なので、以下のプラグインを利用します。

* embulk-parser-apache-custom-log
* embulk-output-mysql

プラグインは gem でインストールします。

```
# embulk gem install embulk-parser-apache-custom-log
# embulk gem install embulk-output-mysql
```
その他のプラグインについては<a href="http://www.embulk.org/plugins/">公式サイト</a>で確認することが出来ます。

## example の実行
Embulk とプラグインを利用するために必要な基本的なファイルとディレクトリを自動生成するために「example」と次項の「guess」を実行します。

まずは Embulk の example を実行することで、サンプルファイルやディレクトリが作成されます。

```
# embulk example ./try1
2018-12-06 18:26:18.267 +0900: Embulk v0.9.11
Creating ./try1 directory...
  Creating ./try1/
  Creating ./try1/csv/
  Creating ./try1/csv/sample_01.csv.gz
  Creating ./try1/seed.yml

Run following subcommands to try embulk:

   1. embulk guess ./try1/seed.yml -o config.yml
   2. embulk preview config.yml
   3. embulk run config.yml
```
## guess の実行
前述の example 実行時に出力されている「embulk guess」を実行することで、example で作成されたサンプルデータを元に、自動でスキーマを推定して、設定ファイルが生成されます。

```
# embulk guess   ./try1/seed.yml -o config.yml
```
これで Embulk とプラグインを利用するために必要な基本的なファイルとディレクトリが生成されました。

# Embulk の設定と実行

## config.yml （Input側）の編集
生成された「config.yml」をアクセスログのフォーマットに合わせて編集します。

```config.yml
in:
  type: file
  path_prefix: /opt/embulk/try1/access_log/sample.access_
  parser:
    type: apache-custom-log
    format: "%{%d/%b/%Y:%T %z}t %u %T %D %r %>s %b \"%{User-Agent}i\" %{X-Forwarded-For}i"
out:
  type: stdout
```
* path_prefix：投入したいログまでのパスとファイルの prefix を記載
* format：Apache のカスタムログ書式を投入したいログに合わせて記載

## preview の実行
アクセスログを path_prefix に合わせて配置して、config.yml の記載に問題がないかを確認します。

```
# embulk preview config.yml
  :
2018-12-07 13:07:16.256 +0900 [INFO] (0001:preview): Loaded plugin embulk-parser-apache-custom-log (0.4.1)
2018-12-07 13:07:16.310 +0900 [INFO] (0001:preview): LogFormat : %{%d/%b/%Y:%T %z}t %u %T %D %r %>s %b "%{User-Agent}i" %{X-Forwarded-For}i
2018-12-07 13:07:16.310 +0900 [INFO] (0001:preview): RegExp    : (\d{2}/[A-z]+/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4}) (.*) (-?\d+|-) (-?\d+|-) (.*) ([1-9]\d{2}) (-?\d+|-) "(.*)" (.*)
2018-12-07 13:07:16.310 +0900 [INFO] (0001:preview): replacement : 9

+-------------------------+---------------------+-----------------------------+------------------------------+-------------------------+----------------------+---------------------+-----------------------------------------------------------------------+---------------------------------------+
|  request-time:timestamp | request-user:string | request-process-time-s:long | request-process-time-us:long |     request-line:string | response-status:long | response-bytes:long |                                      request-header-User-Agent:string | request-header-X-Forwarded-For:string |
+-------------------------+---------------------+-----------------------------+------------------------------+-------------------------+----------------------+---------------------+-----------------------------------------------------------------------+---------------------------------------+
| 2018-10-25 15:12:12 UTC |                     |                           0 |                          913 | "GET /example HTTP/1.1" |                  302 |                 493 | Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko  |                           xxx.xxx.xxx |
+-------------------------+---------------------+-----------------------------+------------------------------+-------------------------+----------------------+---------------------+-----------------------------------------------------------------------+---------------------------------------+

```
何かしら問題がある場合は、Java のエラーログが出力されます。
問題が無い場合は上記のような形式で出力されます。

## データベースの追加
アクセスログ投入先の MySQL にデータベースを追加します。テーブルはプラグインが自動で作成してくれるため、手動で作成する必要はありません。

```
mysql> CREATE DATABASE embulk DEFAULT CHARACTER SET utf8;
mysql> GRANT ALL ON embulk TO root@localhost;
```

## config.yml （Output側）の編集
config.yml の「out:」以下をMySQLに接続するための情報に編集します。

```config.yml
in:
  type: file
  path_prefix: /opt/embulk/try1/access_log/sample.access_
  parser:
    type: apache-custom-log
    format: "%{%d/%b/%Y:%T %z}t %u %T %D %r %>s %b \"%{User-Agent}i\" %{X-Forwarded-For}i"
out:
  type: mysql
  host: localhost
  user: root
  password: password
  database: embulk
  table: apache_access_log
  mode: insert_direct
```

## run の実行
最終的に config.yml に記述した内容を実行する場合は「embulk run」となります。

```
# embulk run config.yml
```

## 実行結果の確認
MySQL にテーブルが作成され、データが作成されたことを確認します。

```
mysql> USE embulk;
Database changed

mysql> SHOW TABLES;
+-------------------+
| Tables_in_embulk  |
+-------------------+
| apache_access_log |
+-------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM apache_access_log LIMIT 1;
+---------------------+--------------+------------------------+-------------------------+--------------------------------------------+-----------------+----------------+---------------------------+--------------------------------+
| request-time        | request-user | request-process-time-s | request-process-time-us | request-line                               | response-status | response-bytes | request-header-User-Agent | request-header-X-Forwarded-For |
+---------------------+--------------+------------------------+-------------------------+--------------------------------------------+-----------------+----------------+---------------------------+--------------------------------+
| 2018-10-26 00:12:12 | NULL         |                      0 |                     913 | "GET /example HTTP/1.1"                    |             302 |            493 |  Java/1.6.0_24            | xxx.xxx.xxx                    |
+---------------------+--------------+------------------------+-------------------------+--------------------------------------------+-----------------+----------------+---------------------------+--------------------------------+
1 row in set (0.00 sec)

```
これでデータの投入は完了しました。
ちなみに、データは25万件ほど一気に入れましたが2～3分程度で完了しました。

# Apache アクセスログの可視化

## Metabase にデータベースを追加
Metabase のダッシュボード画面を開いて、管理者画面を開きます。
![Screen Shot 2018-12-06 at 20.17.19-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/127d6e20-e975-9d7e-4dc4-37c1f07f1a79.png)

画面上部の「データベース」を押下します。
![Screen Shot 2018-12-06 at 20.22.39-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/4c1deb4c-2a3d-e070-22b5-8d94008ec6e7.png)

右上の「データベースを追加」を押下します。
![Screen Shot 2018-12-06 at 20.22.49-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/135fd719-9787-9275-684e-7f1a0f9f1522.png)

「Database type」で MySQL を選択して、接続のための必要情報を入力後、保存ボタンを押下します。
![Screen Shot 2018-12-06 at 20.24.07-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/4fd45cd6-5381-c427-0147-ca10c6375a22.png)

データベースの情報を自動探査してくれるので「このデータを詳しく見る」を押下します。
![Screen Shot 2018-12-06 at 20.24.23-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/9794e086-c5b1-f996-a1a2-e92d8149a288.png)

ダッシュボード画面に戻ると、自動探査の結果が確認できます。
![Screen Shot 2018-12-06 at 20.25.06-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/6bcd794c-cac7-58a6-e205-2936432b48d5.png)

![Screen Shot 2018-12-06 at 20.25.19-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/71d6b9ed-5da1-3aee-36d7-ced7545dd5fc.png)

各グラフを選択すれば詳細な情報なども確認することが可能です。
![Screen Shot 2018-12-07 at 15.34.45-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/316808/fe4e72a3-4b07-b8da-f79d-454ccbb949f5.png)

# 最後に
Metabase もRe:Dash などと同様に用途に合わせたグラフ作成は可能です。
選択できるデータベースにも自由度が高く、SQL を書かなくともクエリビルダーで簡単にデータのグルーピング等が出来るので学習コストが低く済むと思います。
Embulk は日々データを蓄積していなくても、アクセス負荷が高くなった時間帯の前後のログがあればいいので、原因調査を行う場合などにとても有用であると感じました。
今回は Apache アクセスログと MySQL のプラグインのみを紹介しましたが、他にも様々な Input/Output プラグインがあります。
データ移行の際にも利用可能なようなので、Metabase との組み合わせ以外でも色々試してみると面白いかもしれません。

# 参考情報
<a href="https://www.metabase.com/docs/latest/">Metabase公式ドキュメント</a>
<a href="http://www.embulk.org/docs/">Embulk公式ドキュメント</a>