fluentdとGoogleのBigQueryを連携させるのに1日以上時間を溶かした話

# fluentdとGoogleのBigqueryを連携させたい！

この記事は、前回の記事

[Docker&Ubuntu初心者がfluentdを使ってみた](https://qiita.com/YutaroYamanaka/items/3a78d958754ca41f506f)
の続きとなります。
目標は、PythonのWebフレームワークのflaskからFluentd経由でBigQueryにアクセスログ等を格納することです。
今回は1日以上時間を溶かす結果となりましたが多くの知見が得られましたので、皆さんのお役に立てば幸いです。


# BigQueryとは
Google Cloud Platform(以下GCP)が提供するビッグデータ解析サービスです。普通数TB(テラバイト)もあるような大きなデータセットは、SQLのクエリを実行してもあまりにもデータが大きすぎて結果が返ってこないということもあります。でもBigQueryを使えば数秒で結果が返ってきます。流石すぎますGoogle様。
                 

![alt](https://codenote.net/wp-content/uploads/BigQuery.png)

# Dockerfile
今回もDockerのUbuntuイメージでやっていきます。私が調べた限り、GCPはPython 2.7系に依存しているため、インストールしておきます。
またfluentdのBigQuery用プラグインもインストールします。バージョンが最新のものをgithubから引っぱってきます。

```Dockerfile
FROM ubuntu:xenial

RUN apt-get update && apt-get -y upgrade
RUN apt-get install sudo
RUN apt-get install -y curl
RUN apt-get install -y  vim
RUN apt-get install -y git
#デフォルトで24224を使うのでポートを空けておく
EXPOSE 24224

# fluentd(td-agent)のインストール
RUN curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent3.sh | sh

# python2.7
RUN apt-get -y install python2.7
RUN apt install -y python-pip python-dev

# GCPのダウンロード
RUN curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz

# パッケージのダウンロード
RUN mkdir -p /usr/local/gcloud \
  && tar -C /usr/local/gcloud -xvf /tmp/google-cloud-sdk.tar.gz \
  && /usr/local/gcloud/google-cloud-sdk/install.sh

# パスを通す
ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin

# fluentd-plugin-bigqueryのインストール
RUN /opt/td-agent/embedded/bin/fluent-gem install --no-document specific_install
RUN /opt/td-agent/embedded/bin/fluent-gem specific_install https://github.com/kaizenplatform/fluent-plugin-bigquery.git
```
dockerをbuildしたのちに、コンテナを起動する時に

```
$ docker run --name test1 -it -p 24224:24224 ubuntu:td-bq /bin/bash
```
などで、ポートを空けてあげることに注意してください。
コンテナに入った時に、

```
$ bq
```

と打ってみてください。

not foundにならなければOKです。
Dockerfileを書く段階で、パスを通す必要がありそうです。

# GCPの設定
GCPでプロジェクトを作る過程は、他に詳しい記事がたくさんあるので割愛します。
コンテナ上で、ログインするには

```
# gcloud auth login
```
と打つと、Enter verification codeと出るので指定のURLに飛んでポチポチしたのちに表示される認証コードをコピペします。
これで、GCPへのログインが完了しました。

続いて、BigQueryでデータセットとテーブルを作っていきましょう

```terminal
# bq mk -t your-project-id:your_dataset
```
これでデータセットが作られました。
続いてテーブルスキーマを決定しておきます。スキーマの指定には、リスト形式で指定する方法とJSON形式で指定する方法がありますが今回はJSON形式で保存します。

```json

[
 { "name":"usr",
   "type": "STRING"
  },
  {
    "name": "country",
    "type": "STRING"
  }

]
```
この単純なjsonファイルをschema.jsonという名前にして
/etc/td-agent　の下に置きましょう。

```
# bq mk -t your-project-id:your_dataset.your_table /etc/td-agent/schema.json
```

GCPのBigQueryのページに飛んでもらうと、テーブルができたことを確認できたと思います。
また、後々使用するので
Google Developer Consoleからサービスアカウントを作成します。
発行が完了すると、画面上にクライアントID、メールアドレス、フィンガープリントが表示され、鍵ファイルがダウンロードされるはずなので保存して置きます


　　

# td-agent.confの設定

ここで一日溶かしました。かなり複雑ですね。/etc/td-agent　にあるtd-agent.confに、諸々の設定を書いていきます。

```td-agent.conf

<match testing.logs>
  @type bigquery_insert

  auth_method json_key
  json_key {
      "private_key":"-----BEGIN PRIVATE KEY-----\n　... -----END PRIVATE KEY-----\n",
      "client_email":"XXX@XXXXXXXX.gserviceaccount.com"
  }

  project yourt-project-id
  dataset your-dataset
  table your-table
  schema_path /etc/td-agent/schema.json
</match>
```

上のようなものを、td-agent.confに付け加えてあげてください。
一応中身の説明をすると、auth_methodにjson_keyを指定してあげて
private_keyとclient_emailは先ほどGCPのサービスアカウントの取得時に得られた鍵ファイルから、書いてあげます。
typeのところでは　bigqueryのpluginの設定をしているみたいです。またschema_pathは先ほど使ったjsonファイルのパスを指定してあげます。

また各種権限を付与するために、rootユーザにUSERをしてします。
/etc/init.d の下にある td-agentの中身を

```td-agent
TD_AGENT_USER=root
```
にしてあげてください。

これで設定は終了です。
td-agentの起動をします

```
root# /etc/init.d/td-agent start
```


td-agentが起動しました。

```
root# echo '{"usr": "yutaro", "country":"japan"}' | /opt/td-agent/embedded/bin/fluent-cat testing.logs
```

私の場合、これでBigQueryに値が無事格納されました！
エラーが出る場合は、/var/log/td-agent の下に　td-agent.logというファイルに
エラーログが出力されるのでこちらを適宜見ながら、修正できるといいと思います。

またpythonファイルから実行するには

```
$ pip install fluent-logger
```
としてあげて、/usr/local/bin/python/ に

```test.py
from fluent import sender
from fluent import event

# params -> *(tag, host, port)
sender.setup('testing', host='localhost', port=24224)
event.Event('logs', {
    'usr': 'yutaro',
    'country': 'japan'
    })

```

という test.pyを作っておいて

```
$ python test.py
```
で、BigQueryに値が格納されます。
Webアプリでのアクセスログ等も、このようにしてあげれFluentd経由でBigQueryに格納できると思います。
間違いや訂正等ありましたら気軽にご連絡ください。