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インポートで利用

構成図

構築するサーバの簡単な構成と、データ処理のフローは以下のとおりです。

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 ファイルは 公式サイトOther platforms から取得してきました。
作業ディレクトリは /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 ページが開くので、「開始しましょう」から進みます。

ログインするためのアカウント情報を入力します。特に記載はありませんが全て必須項目です。

追加するデータベースを選択できます。後で追加・削除も可能です。ここでは指定せずに進めています。(追加方法については後述します。)

データ収集についての同意確認がされますが、同意しなくとも問題ありません。

設定が完了するとダッシュボード画面が表示されます。

引き続き、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

その他のプラグインについては公式サイトで確認することが出来ます。

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 のダッシュボード画面を開いて、管理者画面を開きます。

画面上部の「データベース」を押下します。

右上の「データベースを追加」を押下します。

「Database type」で MySQL を選択して、接続のための必要情報を入力後、保存ボタンを押下します。

データベースの情報を自動探査してくれるので「このデータを詳しく見る」を押下します。

ダッシュボード画面に戻ると、自動探査の結果が確認できます。

各グラフを選択すれば詳細な情報なども確認することが可能です。

最後に

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

参考情報

Metabase公式ドキュメント
Embulk公式ドキュメント