5
0

[簡単]LambdaのログをKinesis Data Firehose経由でS3に保存してみた

Last updated at Posted at 2023-12-13

この記事について

アイレット株式会社Advent Calendar2023 14日目の記事です!
携わっている案件にてAWS Kinesis Data Firehoseに触れる機会があり、興味を持ったので検証してみました。

実現したいこと

実現したいことは、タイトルの同じでLambdaのログをKinesis Data Firehose経由でS3に保存することです。
Lambdaで実行したログはCloud Watch Logsに保存されます。短期間だけ利用する場合は費用についてあまり気にしなくてもいいですが、長期間利用したり関数の実行回数が多くなることでログデータが膨大になり高い費用が発生してしまいます。料金の比較でS3はUSD 0.025/GBに対して、CloudWatch Logsでは収集でUSD0.76/GB,保存でUSD0.033/GBと高く設定されています。
そのため、ログの保存費用を削減するために一般的に1次保存先としてCloudWatch Logsを選択して2次保存先としてS3を選択するケースが多いです。(費用を削減する方法として、ロググループの保存期間の設定、S3のライフルサイクル設定・・が挙げられます)

CloudWatch LogsからS3に転送する方法でもエクスポート機能やAWS Lamdaを利用することやKinesis Data Firehoseを利用する方法があります。今回は楽に設定できるFirehoseを選択して実現していきたいと思います。構成図は以下の通りです。

image.png

今回は簡易的な検証を行うので、Terraformは使用せずマネジメントコンソール上で操作します。

各サービスの設定

S3の設定

まずは、ログを格納するためS3を作成します。

image.png

設定値は以下の通りです。

設定項目 設定値
バケット名 advent2023-lambda-log
AWS リージョン 東京
オブジェクト所有者 ACL無効
このバケットのブロックパブリックアクセス設定 「パブリックアクセスをすべて ブロック」
バケットのバージョニング 無効にする
タグ 追加しない
デフォルトの暗号化 無効にする
オブジェクトロック(詳細設定) 無効にする

バケット名は全てのAWSアカウントの中で一意に決まるので、検証したい場合は違う名前を付与してください。

IAMの設定

次にKinesis Data FirehoseからS3にデータを保存するために必要な権限を付与します。

advent2023-firehose-role

信頼関係
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "firehose.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

advent2023-firehose-policy

ポリシー
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Effect": "Allow",
			"Action": [
				"s3:AbortMultipartUpload",
				"s3:GetBucketLocation",
				"s3:GetObject",
				"s3:ListBucket",
				"s3:ListBucketMultipartUploads",
				"s3:PutObject"
			],
			"Resource": [
				"arn:aws:s3:::advent2023-lambda-log",
				"arn:aws:s3:::advent2023-lambda-log/*"
			]
		},
		{
			"Sid": "Statement2",
			"Effect": "Allow",
			"Action": [
				"lambda:InvokeFunction",
				"lambda:GetFunctionConfiguration"
			],
			"Resource": "arn:aws:lambda:ap-northeast-1:xxxxxxxx:function:advent2023-logs-processor-func"
		}
	]
}

advent2023-cloudwatch-logs-role

CloudwatchlogsがFirehoseへとデータを送信するために必要な権限を付与します。

信頼関係
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.ap-northeast-1.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

advent2023-cloudwatch-logs-policy

xxxxxxxの部分はご自身のアカウントIDを入力してください。

ポリシー
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Effect": "Allow",
			"Action": [
				"s3:AbortMultipartUpload",
				"s3:GetBucketLocation",
				"s3:GetObject",
				"s3:ListBucket",
				"s3:ListBucketMultipartUploads",
				"s3:PutObject"
			],
			"Resource": [
				"arn:aws:s3:::advent2023-lambda-log",
				"arn:aws:s3:::advent2023-lambda-log/*"
			]
		},
		{
			"Sid": "Statement2",
			"Effect": "Allow",
			"Action": [
				"lambda:InvokeFunction",
				"lambda:GetFunctionConfiguration"
			],
			"Resource": [
				"arn:aws:lambda:ap-northeast-1:xxxxxxxxxxx:function:advent2023-lambda-func"
			]
		}
	]
}

Firehoseの設定

次にFirehoseの設定を行います。Amazon Kinesis→Data Firehose→配信ストリームを作成をクリック

image.png

設定値は以下の通りです。

設定項目 設定値
ソース Direct PUT
送信先 Amazon S3
配信ストリーム名 ACL無効
S3 バケット advent2023-lambda-log
サービスアクセス advent2023-firehose-role

後でデータ変換の機能を使って検証を行いますが、上記以外の設定は一旦デフォルトでOKです。

Lambdaの設定

lambdaの実行ログが欲しいだけなのでコードはシンプルです。

advent2023-lambda-func
import json

def lambda_handler(event, context):
    
    print("advent2023-test")
    
    return {
        'statusCode': 200,
        'body': json.dumps('advent2023-test')
    }

Cloudwatch Logsの設定

Cloudwatchlogsにサブスクリプションフィルターの設定を行います。対象のロググループ→サブスクリプションフィルター→作成→Kinesis Firehose サブスクリプションフィルターを作成のボタンをクリック。

image.png

設定値は以下の通りです。

設定項目 設定値
送信先アカウント 現在のアカウント
Kinesis Firehose 配信ストリーム advent2023-firehose-log
既存のロールを選択 advent2023-cloudwatch-logs-role
ログの形式 その他
サブスクリプションフィルターのパターン
サブスクリプションフィルター名 advent2023-lambda-subfilter

検証

lambdaのテストを実行すると、S3のadvent2023-lambda-logにログデータが格納されていました。

image.png

ログデータをダウンロードして開いてみると

image.png

文字化けが起きてしまいました・・
調べてみると、CloudWatchLogsからAmazonkinesisDataFirehoseに送信されたデータはgzipに圧縮されていて、そのデータを無理やり開こうとしたのが原因らしいです。7zipで圧縮されたデータを解凍してみると・・

無事にログデータの内容を確認できました。(念のため、一部データログを隠してます)

image.png

ログのデータが改行されていなくて見にくいので、firehoseの機能である、データ変換の機能を使用してログデータを見やすいように整形しようと思います。

advent2023-firehose-logの設定でレコードを変換および転換の編集をクリックします。

image.png

次に、AWS Lambdaでソースレコードを変換でデータ変換をオンにチャックを入れ、関数の作成をクリックします。

image.png

今回は1からLambdaのコードを作成するのではなく、Blueprintを使用します。
Blueprintとは、AWS Lambda関数を作成する際に使用できるテンプレートのことを指します。
特定のイベントトリガーや使用ケースに対応したサンプルコードと設定が提供されているので、さまざまなシナリオに合わせた関数を素早く作成できます。

Kinesis Data Firehose Cloudwatch Logs Processorのプルーフプリントを選択します。

image.png

関数の作成の画面では設計図の使用のボタンをクリックします。設計図名でProcess Cloudwatch logs sent to Kinesis Firehoseを選択、関数名をadvent2023-logs-processor-func、実行ロールは基本的なLambdaアクセス権限で新しいロールを作成を選択し関数の作成を行います。

image.png

処理時間がかかることを想定してタイムアウトを10分に修正しました。ちなみに、AWSの公式ドキュメントでは最大5分のLambdaの呼び出し時間がサポートされています。

image.png

再度、Lambdaのadvent2023-lambda-funcでテストを実行してみると、S3のadvent2023-lambda-logにログデータが格納されます。ログデータの中身は整形されいてて前回に比べて見やすくなりました。

Photokako-mosaic-pKLlKI5BAM8AXmJj.png

まとめ

今回はLambdaのログをKinesis Data Firehose経由でS3に保存してみました。検証してみてより一層理解が深まりました。
初めて記事を執筆したので拙い文章になってしまいましたが、最後まで読んでいただきありがとうございました。

参考資料

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0