[CloudWatch Logs]ロググループにアクセス（エラー）ログが反映されないときの対処方法

# はじめに

`/etc/awslogs/awslogs.conf`に追加したログがロググループに反映されない、ということが起きたので実際に行った対処方法を乗せておきます。
その手の記事が乏しいような気がしたので。


「旧エージェントじゃなくて統合エージェントを入れろよ」という意見は受け付けません。何故ならその通りだからです。~~統合はソースが少ないような気がして日和っちゃったんですよ！！！~~

# 先に結論

```
# アクセスログ（エラーログ）の出力先を確認。
$ ls -la /var/log/nginx
```
`access.log（error.log）`ではなく`access.log(error.log)-作成年月.gz`の方に出力されているようであれば、`/etc/awslogs/awslogs.conf`の指定を書き換える。


# なにが起きたのか

CloudWatch logsのエージェントをインストールし、`/var/log/nginx/access.log`と`/var/log/nginx/error.log`をロググループに出力したかった。
`$ sudo vi /etc/awslogs/awslogs.conf`で以下を追加。

```/etc/awslogs/awslogs.conf
[/var/log/nginx/access.log]
datetime_format = %d/%b/%Y:%H:%M:%S %z
file = /var/log/nginx/access.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/nginx/access.log

[/var/log/nginx/error.log]
datetime_format = %Y/%m/%d %H:%M:%S
file = /var/log/nginx/error.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/nginx/error.log
```

`$ sudo systemctl restart awslogsd`で再起動。
CloudWatch Logsのマネジメントコンソールからロググループを確認。

そこで問題が発生。
・デフォルトの`/var/log/messages`はロググループに反映されている。
・追加したnginxのエラーログとアクセスログは反映されていない。

えっ、なにその気持ちの悪い状況は……。

`$ cat /var/log/awslogs.log`でエラー状況を確認すると、以下のことが書いてある。

```
unable to open database file
 時刻とかズラーッと：Missing or invalid value for use_gzip_http_content_encoding config. Defaulting to use gzip encoding.
```

考えたこと
「メッセージログは反映されているということはnginx側の問題で、要はnginxのデータベースを開けるようにすればいいのか？」

違いました。

# 上手くいった対処方法

そもそもログ自体がきちんと出力されているのか？

`$ cat /var/log/nginx/access.log(error.log)`で確認。
結果、なにも書かれていない。

そこで冒頭にも書いてありますが、以下のコマンド。

```
# アクセスログ（エラーログ）の出力先を確認。
$ ls -la /var/log/nginx

# 結果
権限など：access.log
権限など：access.log-作成年月.gz
権限など：error.log
権限など：error.log-作成年月.gz
```
これはもしかして、出力先が違う？

`/etc/awslogs/awslogs.conf`のfileなどのパスを`access.log(error.log)`から`.gz`の方に書き直す。
↓
`$ sudo systemctl restart awslogsd`で再起動。
↓
上手くいきました！

`unable to open database file`というメッセージは関係なかったようです。大事なのはこっちの方でした。

```
Missing or invalid value for use_gzip_http_content_encoding config. Defaulting to use gzip encoding.
```

要は、CloudWatch Logsではgzipファイルで圧縮されたものを使用しているようです。勉強になりました。

>直接のgzipに関する記述ではありませんが、参考までに。
>[CloudWatch Logs エージェントのリファレンス](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AgentReference.html)

そしてこちらの記事、

https://qiita.com/toyoday/items/f3434f8075217fb602ff

どうにも、ログの吐き出し先が`access.log(error.log)-作成年月.gz`となっているようです。
`access.log(error.log)`の脳死指定ではダメだと。
うーん、勉強になる。

# 失敗した対処方法

対処もトントン拍子ではなかったので、色々と試してはみました。
エラー状況によっては、以下の方法のいずれかで上手くいくかもしれません。

## パラメータストアの記入

「データベースと言えば、RDSでパラメータストアを使ったけどあれのせいか？」と考えて以下のことをやってみました。

`$ sudo vi /etc/awslogs/awscli.conf`　
末尾に以下を追加。

```/etc/awslogs/awscli.conf
aws_access_key_id = アクセスキー
aws_secret_access_key = シークレットキー
```

RDSの話なので案の定関係ありませんでした。

## /var/lib/awslogs/agent-stateの作成

>以下の記事を参考
>[Awslogs awslogsd - unable to open database file]
(https://stackoverflow.com/questions/53782247/awslogs-awslogsd-unable-to-open-database-file)

どうにも、`/var/lib/awslogs/agent-state`が必要で、それがないから`unable to open database file`とか言われてしまうようです。

実際どうなのかと、`$ sudo vi /etc/awslogs/awslogs.conf`で`state_file`を確認。
`state_file = /var/lib/awslogs/agent-state`
とデフォルトで指定されている。

しかし私の場合は`/var/lib/awslogs/agent-state`が既に存在していたので、これが問題ではなかったようです（正常ではある）。

## パーミッションの変更

このやり方を試すことはおすすめしません。念のため。

「権限がないのが原因か？」と思い、

```
# 読み取り、書き込み、実行の権限を全てのユーザーに許可。
$ sudo chmod -R 777 /var/log/nginx
```

ただ、あまり乗り気ではありませんでした。
下手に上位階層の権限を与え過ぎると、SSH接続ができなくなる危険があります。
俗に言う`Permission denied (publickey)`エラー。
そうなった場合、最悪EC2を削除しなくてはいけません（クラウドだから削除だけで済むとも言えますが）。

そもそもこれは望み薄でした。デフォルトで出力されているメッセージログの権限を確認してみると、

```
$ ls -l /var/log/messages
-rw------- 1 root root
```

上記のように、権限は関係なさそうです。
パーミッションの変更をするにしても、スナップショットやAMIの取得など、万が一の対策をおすすめします。
そして上手くいかなかったら即座に、`$ sudo chmod 555`などで権限を引き下げておいた方が良いかと。

# おわりに

CloudWatchエージェントで上手くいかなかったときに確認しておくこと。

```
# 書き間違いなど、初歩的なミスをチェック。
$ sudo vi /etc/awslogs/awslogs.conf

# エラー状況の確認。
$ cat /var/log/awslogs.log

# アクセスログ（エラーログ）の出力先を確認。
$ ls -la /var/log/nginx

# ログ自体は吐き出されているのか。
$ cat ログのパス
```