Database JUNKY

MySQL,MariaDBを中心としたブログです

nginxのログをtd-agentを利用して、MySQLに突っ込んでみた 〜アクセスログのデータベース化

nginxのログを収集したいので、td-agentを入れることにした。そのあとどうするかは考えます ここでは、nginxのログの設定から、Fluentdの設定を行い、最終的にMySQLのテーブルにログを吐くところまでを記載したいと思います

かなりの長編ですが、皆様の環境でもこの通りやれば、かならず、、動くはずです。。動くといいな。。

f:id:hit10231023:20160521011718p:plainf:id:hit10231023:20180309104332j:plain

サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)

nginx実践入門 (WEB+DB PRESS plus)

nginx実践入門 (WEB+DB PRESS plus)

td-agentのインストール

インストールはこれだけです

curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh

インストールが完了しましたらバージョンを確認してみます

td-agent のバージョンを確認

/opt/td-agent/usr/sbin/td-agent --version
----
td-agent 0.12.40

プラグインをインストールするためのgem

/usr/sbin/td-agent-gem -v
------------------------------
2.6.13

MySQL Plugin をインストール

さて、いよいよMySQLプラグインをインストールするわけですが、まずプラグインが標準でが入っているかもしれません。確認してみましょう

/usr/sbin/td-agent-gem で確認しました。どうやら入っていないようです

# /usr/sbin/td-agent-gem list --local | grep -i plugin
fluent-plugin-kafka (0.6.1)
fluent-plugin-mongo (0.8.1)
fluent-plugin-rewrite-tag-filter (1.5.6)
fluent-plugin-s3 (0.8.5)
fluent-plugin-scribe (0.10.14)
fluent-plugin-td (0.10.29)
fluent-plugin-td-monitoring (0.2.3)
fluent-plugin-webhdfs (0.7.1)

インストール可能なプラグインを検索

こんな感じでやります

/usr/sbin/td-agent-gem search -r fluent-plugin

fluent-plugin-mysql をインストールします

/usr/sbin/td-agent-gem install fluent-plugin-mysql-bulk
-------
Fetching: mysql2-0.5.2.gem (100%)
Building native extensions.  This could take a while...
Successfully installed mysql2-0.5.2
Fetching: mysql2-cs-bind-0.0.7.gem (100%)
Successfully installed mysql2-cs-bind-0.0.7
Fetching: fluent-plugin-mysql-bulk-0.0.8.gem (100%)
Successfully installed fluent-plugin-mysql-bulk-0.0.8
Parsing documentation for mysql2-0.5.2
Installing ri documentation for mysql2-0.5.2
Parsing documentation for mysql2-cs-bind-0.0.7
Installing ri documentation for mysql2-cs-bind-0.0.7
Parsing documentation for fluent-plugin-mysql-bulk-0.0.8
Installing ri documentation for fluent-plugin-mysql-bulk-0.0.8
Done installing documentation for mysql2, mysql2-cs-bind, fluent-plugin-mysql-bulk after 0 seconds
3 gems installed

Nginx での作業

次は、nginxの設定を確認してみます。apcheでもnginxでもそうなのですが、標準のログフォーマットがわかりづらいので、個人的に、ltsv形式を採用しております また、データベースに格納することから、全ての情報というよりは、必要なもののみ絞って出力しております

ログフォーマットをLTSV形式に

一部抜粋ですがこんな感じのフォーマットにしています。必要最低限のものしか設定していおりませんので、もっと他の情報も欲しい人は、この部分を適宜変更する必要があります ltsvなんてかっこいいこといいましたが、単なるラベル付きログファイルってだけですw

/etc/nginx/conf/nginx.conf から一部抜粋しております

cat /etc/nginx/nginx.conf
-----
log_format ltsv_req_video 'time:$time_local\t'
                           'server:$server_name\t'
                              'time_local:$msec\t'
                              'request_uri:$request_uri\t'
                              'status:$status\t'
                              'user_agent:$http_user_agent';
access_log  /var/log/nginx/ltsv_request.log  ltsv_log;

logディレクトリのパーミッションを変更

あとの、td-agentで読み込めるようにしないとエラーになってしまうので、ここだけ設定を変更しましょう

chmod -Rf o+rx /var/log/nginx

nginxの再起動

/etc/init.d/nginx restart

MySQLでの作業

ログ格納用のMySQLテーブルを作成する

MySQLのこまかい設定については抜粋します。nginxのログファイル形式を参考に以下のテーブルnginxという名前のデータベースに作成しました。

ddl

USE nginx ;

CREATE TABLE `request_log` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `server` varchar(128) DEFAULT NULL,
  `time_local` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `request_uri` varchar(500) DEFAULT NULL,
  `status` varchar(5) DEFAULT NULL,
  `user_agent` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

td-agent.confの編集

上記のnginx.conf をログフォーマットをベースした編集結果が以下の通りとなります。 よくわかわからなかったのが、日時周りですね。おそらくなのですが、日付の書式がMySQLの定義と合わなくて、どうしようもなかったので、 勢いで、from_unixtime(?) で変換してからINSERTするようにしました

/etc/td-agent/td-agent.conf

vi /etc/td-agent/td-agent.conf
<source>
  type tail
  format ltsv 
  time_key time
  time_format %d/%b/%Y:%H:%M:%S %z
  tag  nginx.request.video
  path /var/log/nginx/request.log
  pos_file /var/log/td-agent/request.pos
</source>

## Output descriptions:
<match nginx.request.video>
  type copy
  <store>
  type mysql
  host localhost
  database nginx 
  username sysadm 
  password mypasswd
  key_names server,time_local,request_uri,status,user_agent
  table customer_action_logs
  sql INSERT INTO request_log (server,time_local,request_uri,status,user_agent) VALUES (?,from_unixtime(?),?,?,?)
  flush_interval 10s
  </store>

  <store>
    type file
    path /var/log/td-agent/request.json
  </store>
</match>

td-agentでの作業

td-agent の起動

ここまで作業が終わりましたらtd-agentを起動してみます。

/etc/init.d/td-agent start

MySQLでデータが入っているか確認

ちょっと見てみましょう

mysql>
MariaDB [(none)]> SELECT * FROM nginx.request_log ORDER BY id DESC LIMIT 1\G
*************************** 1. row ***************************
         id: 49
     server: mynginxserver.test.com
 time_local: 2016-01-11 01:57:41
request_uri: /server-status/index.html
     status: 200
 user_agent: check_http/v1.4.16 (nagios-plugins 1.4.16)
1 row in set (0.00 sec)

おぉぉお、バッチリ!!

Nginx ポケットリファレンス

Nginx ポケットリファレンス