hero_picture
Cover Image for S3サーバーアクセスログの整理(2026年7月版)

S3サーバーアクセスログの整理(2026年7月版)

こんにちは。クラウドソリューション事業部の石垣です。

最近、古いS3バケットのサーバーアクセスログ(いわゆるS3アクセスログ)を調査する機会があって、ちょっと大変でした。

今(2026年7月現在)、設定するならばどういう設定にしておくのがいいか改めて、調査・確認しましたので共有します。

S3サーバーアクセスログ

まず従来型のS3サーバーアクセスログについて。

2023年11月の時点でログオブジェクトキーの形式として、日付ベースのパーティショニングに対応しました。

  • 従来まで
    • [DestinationPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]
  • 選択できるようになった形式
    • [DestinationPrefix][SourceAccountId]/[SourceRegion]/[SourceBucket]/[YYYY]/[MM]/[DD]/[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]

Athena等で分析用にクエリを流す際に、パーティション設定をすることで全件スキャンではなく特定の日付([YYYY]/[MM]/[DD])のログに対してクエリを実行できるようになりました。

スキャンデータ量を制限できることで、スキャンデータ量依存のコストを低減し、また実行時間も短縮させることができました。

このアップデートの何が嬉しかったかの検証blogは以下となります。

https://www.seeds-std.co.jp/blog/creators/s3accesslog-objectkey/

CloudWatch へのログ配信

2026年6月のアップデートとして、CloudWatchへのログ配信の機能が追加されました。

Amazon S3 サーバーアクセスログが Amazon CloudWatch Logs と Amazon S3 Tables への配信に対応 - AWS

AWS の新機能についてさらに詳しく知るには、 Amazon S3 サーバーアクセスログが Amazon CloudWatch Logs と Amazon S3 Tables への配信に対応

Amazon Web Services, Inc.aws.amazon.com/jp/about-aws/whats-new/2026/06/amazon-s3-cloudwatch-logs-tables

CloudWatch Logsだけでなく、S3(汎用バケット)やData Firehoseも配信先として選択できます。これはCloudWatch Logsそのものではなく、CloudWatchのログ配信基盤(CloudWatch Log Delivery)を利用しているためです。CloudFrontのv2ログと同じ形ですね。

1S3
23CloudWatch Log Delivery
4 ├─ CloudWatch Logs
5 ├─ S3
6 └─ Firehose

S3への配信

S3への配信も出力形式としてjsonとparquetが選択できるようなっています。

CloudWatch Logsへの配信

CloudWatch Logsへの配信では、そのままS3 Tablesへのミラーリングを配信設定と一括でできるようでした。

その上で、S3 Tablesのバケットがない場合は新規で作成されて、その中にテーブルが作成されるようです。

CloudWatch上はどこに設定があるかわかりにくいですが、「設定>Global>S3テーブル統合」です。

CloudWatchとS3 Tablesとの統合は以下参照。

S3 Tables 統合によるログへのアクセス - Amazon CloudWatch Logs

CloudWatch Logs Amazon S3 Tables Integration は、ログデータの高度な分析を可能にします。この統合により、CloudWatch Logs が S3 Tables に接続されます。複雑なインフラストラクチャを管理することなく、強力なクエリエンジンにアクセスできます。

docs.aws.amazon.comdocs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/s3-tables-integration.html

試しに手元のDuckDBでクエリしてみます。

参考:

Amazon S3 Tables

Support for S3 Tables is currently experimental. The iceberg extension supports reading Iceberg tables stored in Amazon S3 Tables. Requirements Install the following extensions: INSTALL aws; INSTALL httpfs; INSTALL iceberg; Connecting to Amazon S3 Tables You can let DuckDB detect your AWS credentials and configuration based on the default profile in your ~/.aws directory by creating the following secret using the Secrets Manager: CREATE SECRET ( TYPE s3, PROVIDER credential_chain ); Alternatively, you can set the values manually: CREATE SECRET ( TYPE s3, KEY_ID 'key_id', SECRET 'secret', REGION 'region' ); For the full range of credential options (assumed roles, SSO,…

DuckDBduckdb.org/docs/current/core_extensions/iceberg/amazon_s3_tables
Amazon S3 Tables

接続

1INSTALL aws;
2INSTALL httpfs;
3INSTALL iceberg;
4CREATE SECRET (
5	TYPE S3,
6	PROVIDER credential_chain
7);
8
9ATTACH 'arn:aws:s3tables:ap-northeast-1:xxxxxxx:bucket/aws-cloudwatch(S3テーブルバケットのARN)' AS s3_tables_db (
10	TYPE iceberg,
11	ENDPOINT_TYPE s3_tables
12);
13
14SHOW ALL TABLES;
1┌─────────┐
2│ Success │
3boolean4├─────────┤
5true6└─────────┘
7┌──────────────┬─────────┬──────────────────────────┬──────────────┬──────────────┬───────────┐
8databaseschema  │           name           │ column_names │ column_types │ temporary9varcharvarcharvarcharvarchar[]varchar[]boolean10├──────────────┼─────────┼──────────────────────────┼──────────────┼──────────────┼───────────┤
11│ s3_tables_db │ logs    │ amazon_s3__server_access │ [__][INTEGER]false12└──────────────┴─────────┴──────────────────────────┴──────────────┴──────────────┴───────────┘

テーブル見えてそうですね。テーブルが見えたので、実際にクエリを実行してみます。

基本的なデータ確認

1SELECT 
2    request_time,
3    operation,
4    http_status,
5    bucket_name,
6    key_name,
7    remote_ip,
8    bytes_sent_size,
9    user_agent
10FROM s3_tables_db.logs.amazon_s3__server_access 
11LIMIT 3;
1┌──────────────────────────┬─────────────────────────────┬─────────────┬──────────────────┬──────────┬─────────────┬─────────────────┬────────────────────────────────────────────────────────────────┐
2│       request_time       │          operation          │ http_status │   bucket_name    │ key_name │  remote_ip  │ bytes_sent_size │                         user_agent                             │
3timestamp with time zone │           varchar           │    int64    │     varcharvarcharvarchar   │      int64      │                          varchar4├──────────────────────────┼─────────────────────────────┼─────────────┼──────────────────┼──────────┼─────────────┼─────────────────┼────────────────────────────────────────────────────────────────┤
52026-07-09 13:44:58+09   │ REST.GET.ENCRYPTION         │         200 │ my-bucket        │ NULLNULL407NULL62026-07-09 13:44:58+09   │ REST.GET.LOGGING_STATUS     │         200 │ my-bucket        │ NULLNULL316NULL72026-07-08 18:29:28+09   │ REST.GET.OWNERSHIP_CONTROLS │         200 │ my-bucket        │ NULL192.0.2.100193 │ Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...8└──────────────────────────┴─────────────────────────────┴─────────────┴──────────────────┴──────────┴─────────────┴─────────────────┴────────────────────────────────────────────────────────────────┘

従来の形式と異なり、構造化されたデータとして各フィールドが分離されているため、扱いやすくなっています。

オペレーション別のエラー率

どのオペレーションでエラーが発生しているかを確認します。

1SELECT 
2    operation,
3    COUNT(*) as count,
4    COUNT(CASE WHEN http_status >= 400 THEN 1 END) as errors,
5    ROUND(COUNT(CASE WHEN http_status >= 400 THEN 1 END) * 100.0 / COUNT(*), 2) as error_rate
6FROM s3_tables_db.logs.amazon_s3__server_access 
7GROUP BY operation
8HAVING errors > 0
9ORDER BY error_rate DESC;
1┌────────────────────────────────────┬───────┬────────┬────────────┐
2│             operation              │ count │ errors │ error_rate │
3varchar               │ int64 │ int64  │   double4├────────────────────────────────────┼───────┼────────┼────────────┤
5│ REST.GET.CORS                      │     11100.06│ REST.GET.WEBSITE                   │     11100.07│ REST.GET.OBJECT_LOCK_CONFIGURATION │     44100.08│ REST.GET.BUCKETPOLICY              │     11100.09└────────────────────────────────────┴───────┴────────┴────────────┘
10
11

この例では、設定されていない機能(CORS、Website、Object Lock、Bucket Policy)へのアクセスが404エラーとなっています。

普通に使用できそうですね。

まとめ

S3のサーバーアクセスログを改めて整理してみました。

2026年7月現在の今設定するならば、CloudWatch Log Deliveryを利用してログを配信するのがいいかと思います。

個人的には、Athenaなどで後から分析するだけであれば、S3(Parquet + Hive互換)への配信が最もシンプルだと感じました。

一方、リアルタイム分析やLogs Insightsを利用したい場合はCloudWatch Logs、既存のIceberg基盤へ直接取り込みたい場合はData Firehoseと、用途に応じて選択するとよさそうです。