03 Sep 2017, 15:48

NginxのログをFluentdでDynamoDBへ送る

NginxのログをFluentdを使ってAWSのdynamoDBへ送る実験を行ったので、そのメモを残します。
Fluetnd自体あまり触ったことがなかったので、その入門から、AWS DynamoDBへ送信するまでを紹介します。

はじめに

環境

本ブログの実験環境は下記のとおりです。

  • サーバ: AWS EC2, Ubuntu16.04
  • Fluentd: 0.12.35

どんな場面で使えるの?

WebサーバのログをわざわざFluetndを使ってDynamoDBへ送信する必要があるのか?どんなときに使えるのか? そのあたりを少し説明したいと思います。

まず、サーバが複数ある環境では、とくにクラウドのようにサーバの台数が増減する環境では、ログの集約は重要になってきます。AWSをはじめクラウドサービスではオブジェクトストレージのサービス(AWSならS3)があることが多く、オブジェクトストレージにログを集めることもよく紹介されます。 しかし、オブジェクトストレージの特性上、リアルタイムでの処理は向いていません。

DynamoDBのようなスケーラビリティに特徴のもつデータストアを利用することで、大量のログデータもリアルタイムに書き込みができ、冗長化もユーザ視点では気にする必要がありません。大量のログデータの集約に役立つソリューションになるでしょう。

また、FluentdはRaspberry PiのようなIoTデバイスでも利用することができます。 IoTデバイスから直接DynamoDBへログを送信することができればスケーラビリティの面でも安心ですよね。

fluentd-usage-overview

Fluetndインストールと入門

インストール

Fluetndのインストールはとても簡単です。
以下のページの各OSの”Installation Guide”を見るといいでしょう。
https://www.fluentd.org/download

今回はUbuntu16.04環境で行いました。レポジトリからのインストールをします。 インストールしたら起動と、起動できたかの確認を行ってみます。

$ curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh | sh
$ sudo systemctl start td-agent
$ sudo systemctl status td-agent
● td-agent.service - LSB: data collector for Treasure Data
   Loaded: loaded (/etc/init.d/td-agent; bad; vendor preset: enabled)
   Active: active (running) since Sun 2017-09-03 06:41:59 UTC; 27min ago
     Docs: man:systemd-sysv-generator(8)
  Process: 2083 ExecStop=/etc/init.d/td-agent stop (code=exited, status=0/SUCCESS)
  Process: 2127 ExecStart=/etc/init.d/td-agent start (code=exited, status=0/SUCCESS)
    Tasks: 27
   Memory: 236.1M
      CPU: 1.951s
   CGroup: /system.slice/td-agent.service
           ├─2153 /opt/td-agent/embedded/bin/ruby /usr/sbin/td-agent --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid
           ├─2156 /opt/td-agent/embedded/bin/ruby /usr/sbin/td-agent --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid
           ├─2162 /opt/td-agent/embedded/bin/ruby /usr/sbin/td-agent --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-age.pid
           └─2171 /opt/td-agent/embedded/bin/ruby /usr/sbin/td-agent --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid

Hello Fluentd

まずはFluetndがどういうものか理解するために、一番単純な例を試してみます。
NignxのログをFluetndを使って別のファイルに書き出してみます。

まずはNginxのインストールをします。
fluetndからNginxのログファイルが閲覧できるように権限の変更は忘れずに行ってください。

$ sudo apt-get install nginx
$ sudo systemctl start nginx
$ curl localhost
  // ちゃんとHTMLが返ってくればOK
$ sudo chmod 644 /var/log/nginx/access.log
  // Fluentdからログファイルが読み取れるようにします。

次に、Fluetndの設定をいます。
そもそもFluentdの基本的な考え方は、インプットとアウトプットです。 どのようにFluentdにデータをインプットするか、またそれをどのようにアウトプットするかを指定して利用します。 (アウトプットするにあたってフィルターなどかけられる)

Nginxのログを入力には、tailを今回利用します。 tailという名前からもう想像もできるかもしれませんが、ファイルを監視しIOイベントを読み取って、追記された情報に対して処理を行っていきます。

以下の設定ファイルで、format部分が少し難しそうに見えますが、アクセスログの内容をFluetnd側でJsonに変換できるように形式を指定しているだけです。以下参考にしています。
http://qiita.com/liubin/items/92a4e7e3917143ae4aaf

アウトプットはfileタイプを選択し、/tmp以下にファイルとして出力するようにします。

$ sudo vim /etc/td-agent/td-agent.conf
<source>
  type tail
  path /var/log/nginx/access.log
  format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forwarder>[^\"]*)")?/
  time_format %d/%b/%Y:%H:%M:%S %z
  tag nginx.access
  pos_file /var/log/td-agent/nginx.pos
</source>

<match nginx.access>
  type file
  path /tmp/output_nignx_access_log
</match>

設定が完了したらfluetndを再起動して、curlでNginxにアクセスします。
何回かアクセスするといいと思います。

$ sudo systemctl restart td-agent
$ curl localhost

さて、/tmp以下に出力できているか確認します。
ついでに中身をのぞいてみると、Nginxのログの内容がJsonになって出力されていることが確認できます。

$ ls -l /tmp/
-rw-r--r--  1 td-agent td-agent  552 Sep  3 06:14 output_nignx_access_log.20170903.b55842e6a17fff571

$ cat /tmp/output_nignx_access_log.20170903.b55842e6a17fff571
2017-09-03T06:13:11+00:00       nginx.access    {"remote":"127.0.0.1","host":"-","user":"-","method":"GET","path":"/","code":"200","size":"11321"}
2017-09-03T06:13:17+00:00       nginx.access    {"remote":"127.0.0.1","host":"-","user":"-","method":"GET","path":"/","code":"200","size":"11321"}

dynamoDBへのログ送信

では、続いてDynamoDBへのログ送信をおこなっていきます。

dynamoDBのテーブル作成

DynamoDBのテーブルを作成しますが、今回は難しいことは何もしません。 下記の通りでテーブルを作ります。

  • テーブル名: mosuke5-test
  • プライマリーキー: id, 文字列

プラグインの設定

fluetndからDynamoDBへ書き込むには、プラグインを別途インストールする必要があります。こちらのプラグインを使用していきます。
https://github.com/gonsuke/fluent-plugin-dynamodb

インプットは先程と変えずに、アウトプットをDynamoDBに変更し使っていきます。
設定は以下のとおりです。

$ sudo td-agent-gem install fluent-dynamodb-plugin
$ sudo vim /etc/td-agent/td-agent.conf
<match nginx.access>
  @type dynamodb
  aws_key_id xxxxxxxxxxxxxxx
  aws_sec_key xxxxxxxxxxxxxxxxxxxxxxxxxx
  dynamo_db_region ap-northeast-1
  dynamo_db_endpoint https://dynamodb.ap-northeast-1.amazonaws.com
  dynamo_db_table mosuke5-test
</match>

# 変更したら再起動しましょう
$ sudo systemctl restart td-agent

ではcurlでWebサーバへアクセスした後に、AWSコンソールからDynamoDBをみてみましょう。
きちんとDynamoDBへログが保存されていることが確認できるかとおもいます。 ちなみにIDはプラグインの方で自動で付与しているものです。

fluentd-dynamodb-console

設定Tips

fluent-dynamodb-pluginを設定する上で、ハマったポイントがあったので書いておきます。

さいごに

とても簡単な例でしたが、Fluentdの初歩的な使い方から、DynamoDBへのログの書き込みまで理解できましたでしょうか。
設定方法も重要ですが、大事なのは冒頭にも書いた、これがどのような場面で役立つソリューションであるか、ほかのログ収集ソリューションとはどこが特徴的であるかです。
そのあたりの振り返りにご活用いただければと思います。

このエントリーをはてなブックマークに追加