fluentd で Cloud logging(旧:Stackdriver) にログを送る

#はじめに
皆様、GCPは業務で使っていますか？
最近、GCPのインフラ管理を担当することになり、ログの転送・管理をfluentd+Stackdriverで行うために調査・検証をしたので、そのメモを残しておきます。

#fluentd, Stackdriverとは？
細かくは別の記事を見ればいくらでも書いてあるので、ここではざっくりと。

* Stackdriver
    * GCPの色んな操作のログを自動で貯めてくれるすごいツール。AWSで言えばCloud watch logs.
    * GCE内のインスタンスで吐かれるログ`/var/log/messages`などはデフォルトでは収集出来ない。
* fluentd
    * **色々な**形式のログを、**色々**加工出来て、**色々な**ところに送ることが出来るすごいソフト。
    * 上で書いた**色々**と書いてある箇所は、Pluginという形で提供されている。必要ならそれを組み込める。超柔軟。
    * OSS

要するに、**GCE内で取りたいログをfluentdで収集しStackdriverに送る**という趣旨の記事です。

#各種準備作業
##GCPのIAMにServiceAccountを作る
以下のroleを持つサービスアカウントを作成する。

1. Logging → ログ書き込み
- モニタリング → モニタリング指標の書き込み

###作成手順
`IAMと管理` → `サービスアカウント` → `サービスアカウントの作成`

![NCxit3sTnOAnZPS1583592234_1583592265.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598801/81e6120a-6050-ca19-e31e-f9585719ad1c.png)
![HxBXaUt16dBJdpz1583592617_1583592640.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598801/43c81efd-e62b-6048-067c-ea6e3de238ef.png)

###GCEのサービスアカウントに紐づける
作成されている(or 新たに作成した)GCEのサービスアカウントに紐づける

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598801/301987b5-5ffa-5185-5520-b91d3a55e92a.png)

※取得対象がGCEではない場合は、[こちら](https://cloud.google.com/logging/docs/agent/authorization?hl=ja)を参照。

###GCEにgoogle-fluentdをinstallする
```bash:GCE_instance
curl -sSO https://dl.google.com/cloudagents/install-logging-agent.sh
sudo bash install-logging-agent.sh
```

これで準備完了。

#マシン内のログを送る設定をする
##default状態
上記のgoogle-fluentdをinstallすると、デフォルトでいくつかのログ送信の定義ファイルが入っている。

```bash
/etc/google-fluentd/config.d
├── apache.conf
├── cassandra.conf
├── chef.conf
～～～[中略]～～～
├── syslog.conf
├── syslog_endpoint.conf
├── tomcat.conf
└── zookeeper.conf
```
syslogも入っているので、installした時点で（自動的にサービスが起動し）Stackdriverに`/var/log/messages`のログが送られている。

##カスタムログを送る
例えば自身で作ったアプリケーションのログなど、カスタムのログを送りたいケースが多々あると思います。
なので、対象のログを指定する方法を書いていきます。
まずは、最も基本的な動作を見るために、シングルラインから設定していきましょう。

###シングルラインのログ
syslogもそうですが、ログ形式が1行の場合の定義です。
まず、試験用にも必要なので、1行のログを出力するshell scriptを書きましょう。

```bash:my_logger.sh
#!/bin/sh

datatime=`date +"%Y-%m-%d %H:%M:%S.%3N"` # ← ミリ秒まで取る。個人的なログに対する拘り。
hostname=`hostname`
appname="my_custome_app"

echo "${datatime} ${hostname} ${appname} [$1] : $2" >> /var/log/my_custom_app.log
```

これを使って、こんな感じのログを書いていきます。

```bash
sudo sh ./my_logger.sh info "The transaction completed successfully."
sudo sh ./my_logger.sh warn "The transaction completed, but some columns were invalid."
sudo sh ./my_logger.sh error "The transaction stopped because of error."
```

```bash:/var/log/my_custom_app.log
2020-03-08 23:05:52.153 dev-machine-cent my_custome_app [info] : The transaction completed successfully.
2020-03-08 23:05:52.157 dev-machine-cent my_custome_app [warn] : The transaction completed, but some columns were invalid.
2020-03-08 23:05:52.161 dev-machine-cent my_custome_app [error] : The transaction stopped because of error.
```

###confファイルを作成する
`/etc/google-fluentd/config.d`にファイルを作成する。

```bash:/etc/google-fluentd/config.d/my_custom_app.conf
<source>
  @type tail
  format none
  path /var/log/my_custom_app.log
  pos_file /var/lib/google-fluentd/pos/my_custom_app.pos # ← どこまでログを送ったのかの記録ファイル
  read_from_head true
  tag my_custom_app_log
</source>
```

```bash:/var/lib/google-fluentd/pos/my_custom_app.pos
/var/log/my_custom_app.log      0000000000000000        0000000000000000
```

```bash:
sudo systemctl restart google-fluentd
sudo systemctl status google-fluentd
● google-fluentd.service - LSB: data collector for Treasure Data
   Loaded: loaded (/etc/rc.d/init.d/google-fluentd; bad; vendor preset: disabled)
   Active: active (running) since Sun 2020-03-08 14:43:23 UTC; 17s ago
     Docs: man:systemd-sysv-generator(8)
～～～[中略]～～～
Mar 08 14:43:23 fluentd-test runuser[2209]: pam_unix(runuser:session): session opened for user root by (uid=0)
Mar 08 14:43:23 fluentd-test google-fluentd[2189]: [63B blob data]
Mar 08 14:43:23 fluentd-test systemd[1]: Started LSB: data collector for Treasure Data.
```
下の方にエラーが出てなければ問題なく起動しています。
さて、このタイミングでStackdriverにログが送信されています。先ほど出力させた3行です。
ここでもう一度ログに書き込みましょう。

```bash
sudo sh ./my_logger.sh info "The transaction completed successfully."
sudo sh ./my_logger.sh warn "The transaction completed, but some columns were invalid."
sudo sh ./my_logger.sh error "The transaction stopped because of error."
```
![gENFptPc9wIwTOH1583679977_1583680025.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598801/e4f0c8c9-1070-993f-f6a3-67989f25ad60.png)

textPayloadの箇所にログ1行全文が入っています。実は内部的にはmessageというタグに入っています。
他の`timestamp`などはfluentdが自動的に付けた上でJSON形式にして送ってくれます。
時刻はほとんど差分がないですね。**ログの時刻 ≒ 自動でfluentdがつけてくれるtimestamp**

#次回
fluentdでログの取捨選択/加工をする
https://qiita.com/ys_nishida/items/bf04fa54ab53e0369806