Control Tower バージョン 2.8 で追加されたアクセスログの追加設定によって増えるログの量を調べてみた

Control Tower バージョン 2.8 で追加されるアクセスログの設定により増加するアクセスログについて、具体的な増加量などを調べてみました
2022.03.23

こんにちは、大前です。

先日のアップデートで Control Tower のバージョン 2.8 がリリースされました。

バージョン 2.8 のアップデートで Control Tower が作成するログアーカイブバケット上のアクセスログバケットに対してアクセスログの設定が追加 されていますが、AWS の公式ドキュメントにはこの様な記載も確認できます。

(中略)ソースバケットとターゲットバケットが同じである場合、バケットに書き込まれるログに関する追加のログが作成されます。これは、ストレージの請求額がいくらか増える可能性があるため、望ましくない場合があります。

参考 : ログ配信を有効にするにはどうすればよいですか?


ソースバケットとターゲットバケットが同じだと、アクセスログの生成に対するアクセスログが生成されるため、ストレージコストに影響があるとのことですが、この文章だけだと実際にどの程度のストレージが増加するのかは机上で計算するのは難しそうです。

そのため、今回は Control Tower のバージョンを 2.8 にあげる前後で生成されているアクセスログの数などを調べてみたいと思います。

本エントリで検証を行った環境はあくまで個人の検証環境となります。本番ワークロードが動いている環境では異なる結果になる可能性もありますので、あくまで参考程度に留めていただけますと幸いです。

やってみた

今回は以下 2つのアプローチで調査を行ってみることにします。作業は基本的にログアーカイブアカウント上のものと考えてください。また、Control Tower のバージョン 2.8 へのアップデート方法について割愛します。

  • Amazon S3 Storage Lens で確認
  • Athena を利用した調査

Storage Lens で確認

Amazon S3 Storage Lens は 2020/11 ごろにリリースされた機能で、S3 の使用状況などを可視化してくれるサービスです。高度なメトリクスを利用しないのであれば無料で利用できるため、まずはこれを利用して Control Tower 2.8 前後のオブジェクト数やストレージ量の推移をざっくり確認してみます。

Control Tower 2.8 以前

Storage Lens のダッシュボードでフィルターを設定し、Control Tower が作成している S3 アクセスログ保存バケット(aws-controltower-s3-access-logs-<アカウントID>-<リージョン>)に対する結果のみ表示される様にします。

参考 : Amazon S3 Storage Lens ダッシュボードの表示 - Amazon Simple Storage Service


「日付の範囲」を "過去7日"、「%(変更比較)」を "日/日" にする事で、各種メトリクスに対して、日ごとの変化をざっくり知る事ができます。今回は、ストレージの合計オブジェクト数 について表示してみました。

ストレージの合計は 1日あたり 7.51%、オブジェクト数は 1日あたり 7.47% の増加である事が確認できます。


Control Tower 2.8 以降

Control Tower のバージョンを 2.8 にあげ、一週間ほど放置したのちに再度 Storage Lens を確認してみました。

ストレージの合計は 1日あたり 8.45%、オブジェクト数は 1日あたり 9.35% の増加となっている事が確認できます。具体的な数値は見えませんが、ログの量やストレージの増え幅が以前よりも大きくなっている事は確認できます。


下記は、Control Tower のバージョンを 2.8 にする前後のストレージ合計とオブジェクト数の変化を Storage Lens 上でグラフとして表示したものになります。Control Tower のバージョンを 2.8 にしたのは 3/8 であるため、3/8 を境目にしてグラフの傾きが変化していることも確認できます。

Athena を利用した調査

Storage Lens を利用することで、Control Tower バージョン 2.8 以降は想定どおり S3 アクセスログが増加している事が傾向レベルで確認する事ができました。

ここからは Athena を利用し、具体的にどのくらいのログが増えているのか等を確認してみたいと思います。


(前準備)分析対象のログを別の S3 に移動

Athena の課金 *1を抑えるため、スキャン対象としたいログだけ別の S3 バケットを用意し、そこにコピーしておきます。(Glue などを利用してパーティショニング可能な形にする方法もあるかと思いますが、一時的な調査であれば別バケットにコピーしてしまうのが楽だと思います)

今回は Athena でスキャンするためのバケットとして tmp-access-log-<アカウントID> を新規作成し、以下コマンドで 3月分のログだけコピーしました。Control Tower を 2.8 にあげたのは 3/8 なので、2.8 前後の S3 アクセスログが含まれる形になります。(コマンドを実行したのは 3/18 なので、3/1〜3/17 のログを対象とします)

 $ aws s3 sync s3://aws-controltower-s3-access-logs-<アカウントID>-<リージョン> s3://tmp-access-log-<アカウントID> --exclude "*" --include "2022-03-*"


(前準備) Athena のデータベース・テーブルスキーマを作成

以下公式ドキュメントを参考に、Athena のデータベースとテーブルスキーマを作成しました。データベース名やテーブル名、S3 のバケットは随時置き換えてください。

参考 : Athena を使用してAmazon S3 サーバーアクセスログを分析します。

## データベースの作成
create database s3_access_logs_db

## テーブルスキーマの作成
CREATE EXTERNAL TABLE `s3_access_logs_db.ct_access_logs`(
  `bucketowner` STRING,
  `bucket_name` STRING,
  `requestdatetime` STRING,
  `remoteip` STRING,
  `requester` STRING,
  `requestid` STRING,
  `operation` STRING,
  `key` STRING,
  `request_uri` STRING,
  `httpstatus` STRING,
  `errorcode` STRING,
  `bytessent` BIGINT,
  `objectsize` BIGINT,
  `totaltime` STRING,
  `turnaroundtime` STRING,
  `referrer` STRING,
  `useragent` STRING,
  `versionid` STRING,
  `hostid` STRING,
  `sigv` STRING,
  `ciphersuite` STRING,
  `authtype` STRING,
  `endpoint` STRING,
  `tlsversion` STRING)
ROW FORMAT SERDE
  'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  'input.regex'='([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$')
STORED AS INPUTFORMAT
  'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  's3://tmp-access-log-<アカウントID>'


ログの量を調査してみる

Athena でクエリが投げられる状態になったため、どのくらいログが増えているのか調べてみます。

まず、日別のレコード数をカウントしてみます。(1ファイルに複数レコードが含まれる場合もあるため、ファイル数とはイコールではありません)

with data_with_week_number AS(
    SELECT
        day(parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')) AS day_number,
        key
    FROM s3_access_logs_db.ct_access_logs
)
SELECT
    count(key) AS RecordNumber,
    day_number
FROM data_with_week_number
GROUP BY day_number
ORDER BY day_number


結果は以下の様になりました。day_number が 日付を表しており、10 であれば 3/10 を表します。

# RecordNumber day_number
1 6200 1
2 6147 2
3 5986 3
4 5942 4
5 5973 5
6 5987 6
7 6017 7
8 18561 8
9 23313 9
10 22966 10
11 23127 11
12 22415 12
13 22392 13
14 22794 14
15 22842 15
16 22808 16
17 22821 17

3/7 までの、Control Tower を 2.8 にあげる前は 1日あたり約 6000 のレコードが作成されていることに対し、Control Tower を 2.8 にあげた 3/8 以降は、1日あたり約 23000 レコードが生成されている事がわかります。環境によって差異がある部分とは思いますが、ログレコードの数だけでみると 4倍近くになっています。

一方で、Control Tower を 2.8 にあげた後は生成されるログの数は 23000 付近で安定しています。S3 アクセスログは複数のログがひとつのファイルに格納される仕様があるため、爆発的にログレコードが増え続ける事は防げているのではと推測しています。長い目で見ると緩やかに増えるのかもしれませんが、指数関数的にログが増えるわけではなさそうなので、少しは安心できるかもしれません。

参考 : サーバーアクセスログを使用したリクエストのログ記録 - Amazon Simple Storage Service


続いて、アクセスログの生成に対して生成されたアクセスログの数をカウントしてみます。アクセスログの生成に対して生成されたアクセスログレコードは、request_uri カラムに以下の文字列が含まれるため、これを部分一致で検索する事で抽出できます。

## レコードに含まれる request_uri カラムの例
"PUT /aws-controltower-s3-access-logs-<アカウントID>-<リージョン>/2022-03-10-00-15-03-<ランダムな文字列> HTTP/1.1"
with data_with_week_number AS(
    SELECT
        day(parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')) AS day_number,
        request_uri,
        key
    FROM s3_access_logs_db.ct_access_logs
)
SELECT
    day_number,
    count(key) AS RecordNumber
FROM data_with_week_number
WHERE request_uri LIKE '"PUT /aws-controltower-s3-access-logs-047821948938-ap-northeast-1/2022-03-% HTTP/1.1"'
GROUP BY day_number
ORDER BY day_number

結果は以下の様になりました。上に同じく、day_number が 日付を表しています。

# day_number RecordNumber
1 8 12349
2 9 17052
3 10 16880
4 11 17015
5 12 16399
6 13 16398
7 14 16707
8 15 16836
9 16 16752
10 17 16782

3/7 以前は Control Tower のバージョンが 2.8 ではなかった(=アクセスログに関する追加設定がなかった)ため、データが存在しない形になります。3/8 は Control Tower のバージョンが 2.8 ではない時間も含まれているためログ量が少ないですが、3/9 以降は 16000~17000 付近でログが生成されています。これに 6000 を足すとだいたい上の結果に近くなるため、この環境では 1日あたり 6000 ほどのログレコードが生成されていて、Control Tower バージョン 2.8 以降はアクセスログに関する追加設定の影響で 1日あたり 16000~17000 ほどのログが追加で生成されている事がわかりました。


ストレージコストへの影響を考える

Control Tower のバージョンを 2.8 にしてからどのくらいログが増えているのか確認する事ができたので、ストレージコストへの影響を考えてみます。

増えたログの大半を占めている アクセスログの生成に対するアクセスログ は、キーやランダムな文字列に変化はあれど、下記の様なレコードでほぼ固定の内容となっています。

f282d5339fc6b40e0aaaf8702fa9046ed9a20aeb3fca0b8758example	aws-controltower-s3-access-logs-<アカウントID>-<リージョン>	10/Mar/2022:00:41:18 +0000	-	svc:s3.amazonaws.com	PY6NVZKDB5E3XXXX	REST.PUT.OBJECT	2022-03-10-00-41-18-6A68BB6362451CD2	"PUT /aws-controltower-s3-access-logs-<アカウントID>-<リージョン>/2022-03-10-00-41-18-6A68BB6362451CD2 HTTP/1.1"	200	-		552	84	43	"-"	"-"	-	a2BxMBmtYq4ffLeLll85vfbiSblvL9gS8mBE+y+m++z6csYmJ0UQ31yQq3twmhxxXxXXxxpT8=	SigV4	ECDHE-RSA-AES128-GCM-SHA256	AuthHeader	s3.<リージョン>.amazonaws.com	TLSv1.2

このレコードをサイズ換算にすると、1レコードあたり約550B となります。

実際に、Control Tower を 2.8 にあげた後のログファイル一覧を眺めると、ファイルサイズが 550B や 1.1KB のファイルが多く確認できます。1.1KB のファイルは、上記レコードが 2つ含まれたログファイルです。

上記より、Control Tower を 2.8 にあげたことによる、アクセスログのストレージコストへの影響は、ざっくり以下の様に計算できるかと思います。

16000(1日あたりに生成される追加のアクセスログ)x 550B(ログ1つあたりのサイズ)= 8800000 = 8.8MB


私の環境では、1日あたり約8.8MB の追加ログが Control Tower の 2.8 アップグレードによって発生している事がわかりました。具体的な数値は環境によって差異があるかと思いますが、2.8 にあげることによって 1日あたりどのくらいログが増えたかは上述の方法で確認できるかと思いますので、Control Tower 2.8 を評価中の方などは参考にしていただけると幸いです。

おわりに

Control Tower バージョン 2.8 で追加されたアクセスログに関する設定による、ログの増加量について調べてみました。

冒頭にも記載した通り環境によって差異がある可能性もありますので、あくまで参考までに留めていただければと思いますが、爆発的にログ量がいきなり増えるわけではないという傾向は確認できたので、個人的には安心しました。

(とはいえアクセスログがフラットに出力されているので、アクセスログの出力先プリフィックスの指定ぐらいはしたいなぁ・・・)

以上、AWS 事業本部の大前でした。

参考

脚注