ローカルの Mac に td-agent ( Fluentd ) を入れて、Amazon Athena から SQL ライクにログを抽出するまで。

# 今いま、あるところに

Rails のプロジェクトがありました。 :older_man_tone2: :older_woman_tone1:

そこでは、[lograge](https://github.com/roidrage/lograge) という gem をいれて、`/log/development.log` に欲しいログ情報を JSON 形式で送りつけていました。

```rb:/config/initializers/lograge.rb
Rails.application.configure do
  config.lograge.enabled = true
  config.lograge.formatter = Lograge::Formatters::Json.new
  config.lograge.custom_options = lambda do |event|
    {
      user_id: event.payload[:user_id],
      user_email: event.payload[:user_email],
    }
  end
end
```

```zsh:/log/development.log
# ...イメージ
{"method":"GET","path":"/dashboard/events","format":"json","controller":"DashboardController","action":"events","status":200,"duration":68.21,"view":0.44,"db":0.0,"user_id":"9999","user_email":"mochizuki@hoge.com"}
```

**ここに td-agent を入れて、ログを S3 に送り、Amazon Athena から SQL ライクにログを抽出するということをやりたいと思います。**

# 最終的なイメージ

:military_medal:

![td.png](https://qiita-image-store.s3.amazonaws.com/0/45822/769055a2-4692-1ca1-1b0a-9e702f86ab54.png)


# まず td-agent (Fluentd) を入れるところから


[Installing Fluentd using .dmg Installer (MacOS X)](http://docs.fluentd.org/v0.12/articles/install-by-dmg) ここに書いてあるとおりに、Download して、td-agent を入れます。これはすぐにスルっと入ると思います。 :no_mouth:

つぎに、`fluent-plugin-s3` というものを入れたいのですが、これが難しかったです。

```zsh:インストール
/opt/td-agent/usr/sbin/td-agent-gem install fluent-plugin-s3
```

結論、上のコマンドでいけるのですが、...とにかく行けます。

ref. http://docs.fluentd.org/v0.12/articles/faq#i-installed-td-agent-and-want-to-add-custom-plugins-how-do-i-do-it

（自分用のメモ。以下のファイルから `/opt/td-agent/usr/sbin/td-agent` の場所を確認。）

```zsh:/Library/LaunchDaemons/td-agent.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>KeepAlive</key>
  <true/>
  <key>Label</key>
  <string>td-agent</string>
  <key>ProgramArguments</key>
  <array>
    <string>/opt/td-agent/usr/sbin/td-agent</string>
    <string>--log</string>
    <string>/var/log/td-agent/td-agent.log</string>
    <string>--use-v1-config</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>WorkingDirectory</key>
  <string>/opt/td-agent</string>
</dict>
</plist>
```

# つづいて設定ファイルを書きます。

いろいろ学びながら（ハマりながら）、完成したのが下です。（一応これで、やりたいことはできました。）

```zsh:/etc/td-agent/td-agent.conf
<source>
  type forward
</source>

<source>
  type     tail
  tag      lograge
  format   json
  path     {project-path}/log/development.log
  pos_file {project-path}/log/development.log.pos
  time_key time
</source>

<match lograge>
  @type copy
  <store>
    @type stdout
  </store>
  <store>
    @type s3
    format json
    aws_key_id {aws_access_key_id}
    aws_sec_key {aws_secret_access_key}
    s3_bucket {my_bucket_name}
    s3_region ap-northeast-1
    path lograge_logs/ # 任意に指定できます
    buffer_path /var/log/fluent/lograge_s3 # 任意に指定できます
    buffer_chunk_limit 100k
    time_slice_format year=%Y/month=%m/day=%d/%Y%m%d-%H
    utc
  </store>
</match>
```

### ポイント説明

- `@type stdout` で、`/var/log/td-agent/td-agent.log` にログが流れてくるので、これを `tail -f` しながら作業を進めました。
- `format json` で JSON形式で（余計な日時データなどを含まない形で）吐き出してくれます。
- `@type copy` で複数のアウトプットをしてくれます。（ stdout と s3 への吐き出し）

`@type copy` の存在に出会うまで、ぼくは**一向に現れないログを永遠と** 待ち続けていました。 :angel_tone3:


```zsh:(こんな風に書いていたわけです。）
<match lograge>
  @type stdout
</match lograge>
<match lograge>
  @type s3
  省略
</match>
```

# td-agent を動かしておく

```zsh:動かす
sudo launchctl load /Library/LaunchDaemons/td-agent.plist
```

```zsh:止める
sudo launchctl unload /Library/LaunchDaemons/td-agent.plist
```

設定ファイル `td-agent.conf` をいじったら、上のコマンドで "止めて" ・ "動かして" 反映させます。reload みたいなコマンドないのかなぁとおもいつつ、`&&` でつなげてお手製リロードコマンドを何度も叩きました。

以上で、`/log/development.log` の JSON 形式のログが、`S3://lograge` にアップされるようになりました。 :smiley: 

```zsh:awscliでの確認
$ aws s3 ls --recursive  s3://my-bucket-name
2017-02-02 17:10:27        270 lograge_logs/year=2017/month=02/day=02/20170202-07_0.gz
2017-02-02 18:10:58       2580 lograge_logs/year=2017/month=02/day=02/20170202-08_0.gz
2017-02-02 19:10:31        757 lograge_logs/year=2017/month=02/day=02/20170202-09_0.gz
```

# Amazon Athena の設定をする


![スクリーンショット 2017-02-02 19.36.11.png](https://qiita-image-store.s3.amazonaws.com/0/45822/7a719c47-8410-ca7e-621b-04a2ce6dc112.png)

クエリがかけるので、`create database hoge` などでデータベースをつくります。

そして、テーブルもクエリでつくれるのですが、それは大変そうなので、`Catalog Manager` メニューからつくります。

道なりにすすめば、ゴールにつきます。ポイントはフォーマを JSON にしておくことです。これで、正規表現をゴリゴリ書かなくてすみます。隣の席の CTO が、正規表現にすごく時間がかかったとおっしゃっていましたので、これを避けることができてよかったです。 :rolling_eyes: （どうも単純な正規表現ではなく、癖があり、`\\d` などと書かなくてはいけないようです。）

![スクリーンショット 2017-02-02 19.38.08.png](https://qiita-image-store.s3.amazonaws.com/0/45822/74c0e74c-6ae6-d42e-d6d7-79ec40266d20.png)


年・月・日でパーティションを切っていますので、以下のコマンドで反映させます。（ちょっとここ勉強不足で詳細わかっていません。）

```mysql
MSCK REPAIR TABLE database_name.table_name;

# 確認
show partitions database_name.table_name;
```

# あとはクエリを叩くだけです

一番最初のキャプチャの通りです。`select * from table_name;` これで、みたいデータがとれます。


:dango:


以上です。

途中で、いろいろハマりましたが、無事にやりたいところまでできてよかったです。今日はもうサウナに入って体を整えて :beer: でも飲みたいと思います。

明日以降は、これらを itamae とかで、リモート構築できるようにしなければなりません。 :walking_tone1: 


ありがとうございました。 :pray: