NginxアクセスログファイルをFluentdでMySQLに格納する

こんにちは、サイオステクノロジーの森谷です。
今回はAzure上でログ収集基盤ツールのFluentdを動かしてみたいと思います。

Fluentdとは

Fluentdはオープンソースで公開されているログ収集基盤ツールです。プラグイン型のアーキテクチャを採用しており様々なログフォーマットや出力先に対応可能な点、リアルタイムにログ転送を行う点が特徴です。入出力時にはログデータの加工やフィルタ、再送などが可能です。また、バッファリング機能を持っているため、リアルタイム処理で懸念されるログ欠損を防止してくれます。前回紹介したEmbulkのリアルタイム処理版になります。

今回は、このFluentdを用い、Webサーバのアクセスログをパースし、RDBに格納します。以下はその大まかな構成です。
Fluentdを用いてNginxのアクセスログをMySQLのテーブルへ格納する

この記事では、以下の項目について解説します。

  • Nginxのインストール・実行
  • Fluentdインストール前の準備
  • Fluentdのインストール・実行
  • Fluentdの設定・実行
  • 動作確認

GitHub: https://github.com/fluent/fluentd
Document: https://docs.fluentd.org/

前提環境

今回、Azure上にはあらかじめ下記環境を用意します。
(MySQLについては、前回簡易に利用する方法を紹介したため、必要であればそちらを参照してください。)

  • CentOS 7.2 64bitが搭載されたVM
  • 80番ポートにアクセス可能な設定を行ったセキュリティグループ
  • MySQLデータベース

Nginxのインストール・実行

まずはFluentdのログ収集対象であるWebサーバとして、Nginxをインストールします。公式サイトの記述を参考に、パッケージをインストールしましょう。

$ cat << 'EOS' | sudo tee /etc/yum.repos.d/nginx.repo
> [nginx]
> name=nginx repo
> baseurl=https://nginx.org/packages/centos/7/$basearch/
> gpgcheck=0
> enabled=1
> EOS
$ sudo yum -y install nginx

インストールが完了した後は、Nginxを起動します。
また自動起動にも登録し、次回起動時にデフォルトで起動するようにしておきましょう。
CentOS 7ではサービスの管理をSystemdで行いますので、次のようなコマンドになります。

$ sudo systemctl start nginx
$ sudo systemctl enable nginx

起動したら、Webブラウザからアクセスして動作を確認しましょう。以下のようにIPアドレスを用いてVMにアクセスし、「Welcome to nginx!」のページが表示されたら、インストールに成功しています。

https://<VMのIPアドレス>/

Fluentdインストール前の準備

公式ドキュメントのBefore Installingを参考に、インストール前に環境を整えます。

NTPの設定

Azure上で作成したCentOS 7にはChronydがプリインストールされており、NTPサーバと時刻を同期するようになっています。そのため、特に設定の必要はありません。なお以前のバージョンで利用されていたNtpdを利用したい場合、Chronydと同時に起動できないため、Chronydを停止し、自動起動の設定を解除する必要があることに注意してください。

ファイルディスクリプタの設定

ファイルディスクリプタの最大の数を増やします。まずは以下のコマンドで現在の最大のファイルディスクリプタの数を確認します。

$ ulimit -n

デフォルトでは1024などになっていると思われますが、これではFluentdが利用するには不足しているので、/etc/security/limits.confに以下のような行を追加します。

root soft nofile 65536
root hard nofile 65536
*    soft nofile 65536
*    hard nofile 65536

変更後はVMを再起動します。Nginxを自動起動へ登録していれば、再起動後も動作しているはずですので、ここでもう一度動作確認してもよいでしょう。

ネットワークカーネルの最適化

Fluentdの処理が多い高負荷環境ではネットワークカーネルのパラメータ調整が必要になります。今回は収集対象がNginxのみの簡易な環境ですので、省略します。

Fluentdのインストール・実行

NginxとMySQLをつなぐFluentdをインストールします。
Fluentdをインストールする方法はいくつかありますが、今回は簡単にインストールするため、td-agentを利用します。td-agentはTreasure Data社が公開している、fluentdに加え専用のRuby等がバンドルされている安定版のパッケージになります。Treasure Data社の各種サービスと連携することを想定したものになっていますが、連携させずにFluentdのみを利用することができます。

td-agentのインストールは以下コマンド1つの実行のみで可能です。またNginx同様、サービスの起動と自動起動への登録もしておきましょう。

$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh
$ sudo systemctl start td-agent
$ sudo systemctl enable td-agent

Fluentdの設定

Nginxのログを収集し、MySQLへ格納する仕組みを実現するため、各種の設定をしていきます。

ログアクセスの設定

CentOS 7のデフォルトでは、NginxのアクセスログはLogrotatedが管理しており、nginxユーザ・admグループ以外は読み込むことができません。そのため、td-agentの実行ユーザをadmグループに追加しましょう。

$ sudo usermod -aG adm td-agent

依存パッケージのインストール

この後の作業で必要なコマンドや、Fluentdのプラグインをインストールする際に必要なパッケージを事前にインストールします。以下のコマンドでVMに依存パッケージ(gcc, mysql-client, mysql-devel)を追加してください。

$ wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm
$ sudo rpm -Uvh mysql57-community-release-el7-9.noarch.rpm
$ sudo yum install -y gcc mysql-community-client mysql-community-devel

Fluentdプラグインの追加

プラグインをコマンド1つでインストールするだけで、様々な入出力に対応できる点がFluentdの魅力です。今回は出力先としてMySQLが利用できるように、MySQLプラグインを追加します。td-agentに内蔵されたRubyGemsを用いてプラグインをインストールしましょう。

$ sudo td-agent-gem install fluent-plugin-mysql -v 0.1.5

これで、FluentdからMySQLを入出力に利用できるようになりました。

td-agent.confの設定

/etc/td-agent/td-agent.confを以下のように編集し、入出力の設定を行います。

<source>
  @type tail
  path /var/log/nginx/access.log
  pos_file /var/log/td-agent/nginx.access.log.pos
  tag nginx.access

  format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>\S+) +(?<version>\S+))?" (?<code>[^ ]*) (?<size>[^ ]*) "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<xforwarded>[^\"]*)"$/
  time_format %d/%b/%Y:%H:%M:%S %z
</source>

<match nginx.access>
  @type mysql_bulk
  host <your-host>
  port <your-port>
  database <your-database>
  username <your-user-name>
  password <your-user-password>

  column_names id,host,user,time,method,path,version,code,size,referer,agent,xforwarded
  key_names id,host,user,${time},method,path,version,code,size,referer,agent,xforwarded
  table nginx_access_log

  flush_interval 10s
</match>

source部は、入力の設定になります。今回はtail入力プラグインを利用してNginxのアクセスログを監視し、新しい行が追加されるたびにそれを取得します。タグ名は任意ですが、Nginxアクセスログのデータであるこがわかるよう、nginx.accessとしておきます。また、formatパラメータにログのフォーマットを正規表現で記述します。(?<key> )によって囲んだ部分が対応するキーの値となりますので、忘れずに指定しましょう。

match部は、指定したタグ名にマッチするデータに対して設定した動作を行います。今回はmysql_bulk出力プラグインを指定し、データを指定したMySQLデータベースのテーブルに格納します。MySQLの接続情報は自身の環境に合わせて変更してください。mysql_bulkプラグインではcolumn_namesパラメータで格納する列名を指定し、key_namesパラメータで対応するログデータのキーを指定します。このとき${time}でそのデータを収集した時刻を指定することもできますので、併せて格納しておきます。

設定を変更したら、td-agentを再起動して、設定を読み込みましょう。起動後にステータスを確認して、runningでなければ設定ファイルに文法ミス等がありますので、設定を確認しましょう。

$ sudo systemctl restart td-agent

出力先テーブルの作成

Fluentdではテーブルが存在しない場合に作成する機能はないため、事前に出力したデータを格納するテーブルを作成しておきましょう。以下のコマンドでは、先ほど設定したtd-agent.confに対応したカラム名・テーブル名のテーブルを作成しています。

$ mysql -h <your-host> -P <your-port> -u <your-user-name> -p <your-database> <<EOS
> CREATE TABLE nginx_access_log (
>   id         INT AUTO_INCREMENT PRIMARY KEY,
>   host       VARCHAR(16),
>   user       VARCHAR(200),
>   time       DATETIME,
>   method     VARCHAR(200),
>   path       VARCHAR(200),
>   version    VARCHAR(200),
>   code       INT,
>   size       INT,
>   referer    VARCHAR(200),
>   agent      VARCHAR(200),
>   xforwarded VARCHAR(200)
> );
> EOS

動作確認

いよいよFluentdの動作を確認します。
再びWebブラウザからVMにアクセスし、Nginxのスタートページを表示します。キャッシュが残っているとサーバにアクセスしない場合があるため、更新をしてもいいかもしれません。

アクセス後に、テーブルの中身を確認しましょう。

ログのデータが情報ごとにカラムに分かれて格納されました!

まとめ

今回はAzure VMにNginxとFluentdをインストールし、NginxのアクセスログデータをMySQLデータベースにインポートしました。ログデータはパースされ情報ごとにカラム分けされているため、SQLを用いての解析が容易にできますね。
このようにFluentdを利用すればログをリアルタイムに取得・解析し、活用することができます。紹介しきれないほど多くの種類のログ・出力先に対応しているので、皆さんも一度試し、新しい活用方法を発見してみてはいかがでしょう。

ここまでご覧いただきありがとうございました。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です