Pocket

[AWS][Terraform]CloudWatch LogsをAmazon KinesisでS3にエクスポートする

結構前にCloudWatch Logsの各ログをAmazon Kinesisを利用してS3に保管するように作ってみましたが、保管されたログの中身を見てみると、以下のようにCloudWatch Logsの独自ログに書き変わっていることがわかりますね。

結局情報として欲しいのは message の部分で、かつLTSV形式で生ログの形で出力されていることがふさわしく、分析でBigQueryやAthenaにDigdagで取り込めるようするには1行に一つのログがある形式にしないといけないので、ログをバラす必要があります。

またCloudWatch Logのサブスクリプションとして出力されるログはgzip圧縮されており、Base64エンコードされて送られてきます。今回は手軽にログ基盤を実装する方法をブログしたいと思います。


構成

  • EC2/Amazon Linux 2(awslogs)
  • CloudWatch Logs(subscription filter)
  • Amazon Kinesis
  • Lambda(change LTSV)
  • S3

https://dev.classmethod.jp/articles/cloudwatch-logs-kinesis-origin-fireshose-s3-format/

  • Kinesis Data Firehose Cloudwatch Logs Processor

  • change_cloudwatchlogs_to_ltsv(Node.js 14.x)

前回と変わったところはLambdaを利用してLTSV形式に戻すように作り込む必要があるのですが、「いちいちLambda書かないといけないの?」という……心配は必要ございません。実はKinesisのTransform機能でLambdaのテンプレートを用意しております。(めちゃくちゃ助かる..)一応コード貼っておきますが、EC2での設定から説明していきましょう。


EC2

  • install

  • awscli.conf

  • awslogs.conf

  • Nginx(LTSV)

Nginx ログフォーマットをLTSV形式に

  • IAMロール割り当て

CloudWatchLogsFullAccess

今回はEC2で行いましたが、まずはawslogsの設定をしてCloudWatch Logsに出力しましょう。ECSの場合はawslogsをインストールしなくても標準出力していればCloudWatch Logsに出力されるので特に設定することはありません。ただ、Nginxとアプリが同居している場合はawslogsをインストールする必要があるので注意が必要です。続いてはTerraform化です。


Terraform

  • assume_role_policy/firehose.json

  • assume_role_policy/change_cloudwatchlogs_to_ltsv_policy.json 

  • assume_role_policy/kinesis_access_s3_logs_bucket.json 

  • assume_role_policy/kinesis_allow_deliverystreams.json 

  • assume_role_policy/kinesis_basic_role_policy.json

  • assume_role_policy/lambda.json

  • iam.tf

18行目でKinesis側にLambdaの権限を渡さないといつになっても、以下のようにLambdaが動作しないので、一旦Fullで権限を加えました。うまくいかないときはKinesis側のAmazon S3 destination > S3 bucket error output prefixで確認しましょう。

“errorCode”:”Lambda.InvokeAccessDenied”,”errorMessage”:”Access was denied. Ensure that the access policy allows access to the Lambda function.”

  • kinesis.tf 

S3までのBufferとintervalは5MBと300秒にしました。またログの損失をしないように短ければ短いほどいいのですが、ここは調整が必要となります。

また、Kinesis Data Firehoseのスループット上限を超過する場合(PutRecordBatchの上限である、コールごとに最大500レコード、または4 MiB )があり、ServiceUnavailableExceptionが出る可能性があるので、Transform側のBuffer sizeとBuffer intervalは1MBと60秒にしてバッファ間隔を短くしています。S3先のディレクトリprefixは必ず年/月/日のように管理しましょう。

  • lambda.tf 

LambdaはS3から取ってくるようにしましょう。timeoutは5分にしていますが、手動のデフォルトで設定してしまうとKinesis側でtimeout伸ばしてくれと言われてしまうのであえて設定しています。

  • variables.tf

環境変数でCloudWatch Logs名、S3のディレクトリ先、Kinesis名を指定することで今後ログが増えた場合追加するだけなので便利です。あとはログがS3に保存されるか気楽に待つだけです!


ログ確認

ちゃんとLTSV形式になっていることを確認できました!オートスケールしても問題なくログは取れていたので、BigQueryやAthenaで取り込める準備が整いました。

※S3からgzファイルをダウンロードする時に既に解凍されているので、わざわざmvしなくても圧縮ファイルをクリックすれば中身を閲覧することができます。(AWSの私用らしい)

※余談

Digdag/Embulkの場合はembulk-input-s3プラグインを利用して以下のように設定すればBigQueryにシンクできるようになります。

  • Gemfile

  • access_log.yml.liquid


まとめ

簡単にAmazon Kinesisでログ基盤を作ることができました。Fluentd/td-agentの場合は様々なログ加工等しやすいというメリットがあるのですが、バージョンアップがツライことや運用工数を考えると、awslogsのメンテのしやすさとKinesisに任せてしまうというのがいいかもしれません。また課題が出てきたらブログします!!

Pocket

カテゴリー: AWSTerraform

adachin

1989年生まれのSRE。ホスティングから大規模なアドテクなどのインフラエンジニアとして携わる。現在はサービスの信頼性向上、DevOps、可用性、レイテンシ、パフォーマンス、モニタリング、オブザーバビリティ、緊急対応、AWS/Azureでのインフラ構築、Docker開発環境の提供、Kubernetes保守、インフラコード化、新技術の検証、リファクタリング、セキュリティ強化などを担当している。個人事業主では数社サーバー保守とベンチャー企業のSREインフラコンサルティングやMENTAで未経験者にインフラのコーチング/コミュニティの運用を実施している。また、「脆弱性スキャナVuls」のOSS活動もしており、自称エバンジェリスト/技術広報/テクニカルサポート/コントリビュータでもある。

0件のコメント

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください