Cloudflare R2 に HTTP アクセスログをプッシュして API で取得するまで
Cloudflare ではリクエストやイベントログを記録&保存する Logpush 機能をサポートしています。
ログ保存先として、以前は S3 をはじめとする サードパーティサービス のみサポートしていたのですが、今年 Cloudflare が GA した S3 互換のオブジェクトストレージ R2 に対しても、Cloudflare ダッシュボードまたは API 経由でログをプッシュできるようになっていたので試してみました。
今回はサンプルのウェブサイトの前段に Cloudflare CDN を設置し、訪問者の HTTP アクセスログを R2 にプッシュしてみます。また、保存されたログをダッシュボードと API で取得してみるところまでやってみます。
前提
- Cloudflare CDN を有効化した静的サイトを準備済みです。
R2 バケットの準備
まずはログを保存する R2 バケットを作成し、バケットにアクセスするため API トークンも生成します。
R2 バケットの作成
Cloudflare ダッシュボードの左サイドバーから [R2] に移動し、[Create a bucket] を行います。
デフォルトの設定(パブリックアクセスなどは不可)でそのまま作成して大丈夫です。
APIトークンの生成
バケット一覧ページに戻り、右上 [Manage R2 API Tokens] をクリックします。
バケットにログを書き込むため、Edit 権限を付与します。
API トークンの生成に成功すると、キー ID と Secret が生成されますので、それらをコピーしておきます。
以上で R2 の準備は完了です。
上記では R2 ページから API トークンを生成しましたが、その代わりに、Cloudflare の Genelral な API トークンを生成して利用することも可能です。
その場合、下記の設定が必要になります。
- Zone scope, logs edit permissions.
- Account scope, R2 write permissions.
Logpush設定
次に Logpush の設定に移ります。
左サイドバー [Analytics] → [Logs] に移動し、 Logpush の [Manage] をクリックします。
次の画面で対象ドメインを選択します。現在 Logpush はエンタープライズカスタマー限定機能のため、対応したドメインを選択してください(今後全プランに開放予定)。
[Add Logpush job] をクリック。
[HTTP requests] を選択。
ログに出力されるフィールドを設定します。今回は Cache と CacheResponse も有効化してみます。
ログの出力先として [R2 Object Storage] を選択。
先程作成した R2 バケット名と APIトークン を入力します。
[Daily subfolders] のオプションはそのままデフォルトにしておくと、自動でログを日毎のフォルダを分けてくれます。
バケット情報とトークンが正しければ Ready 状態になり、これで Logpush の準備も完了です。
ログを Cloudflare コンソールから確認する
サンプルサイトにアクセスしてから R2 のバケットに移動すると、ログファイルが生成されています。
ダウンロードして、 $gzip -d
して中身を見てみます(少し成形してます)。
{ "ClientIP": "2a02:908:13b2:2dc0:6828:af62:a81a:e955", "ClientRequestHost": "konishi.classmethod.cf", "ClientRequestMethod": "GET", "ClientRequestURI": "/", "EdgeEndTimestamp": "2022-12-10T13:07:28Z", "EdgeResponseBytes": 1043, "EdgeResponseStatus": 200, "EdgeStartTimestamp": "2022-12-10T13:07:28Z", "RayID": "777634266d915AAA", "CacheCacheStatus": "dynamic", "CacheReserveUsed": false, "CacheTieredFill": false, "CacheResponseBytes": 2594, "CacheResponseStatus": 200 }
CLoudflare CDN でのキャッシュを ON にしているため CacheCacheStatus
が dynamic
になっています。初回アクセスであれば miss
になるはずです。
API でログを取得してみる
API リクエスト ( GET )のフォーマットは下記です。
start
, end
, bucket
は必須パラメーターです。
curl -s -g -X GET 'https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/logs/retrieve?start=2022-06-01T16:00:00Z&end=2022-06-01T16:05:00Z&bucket=cloudflare-logs&prefix=http_requests/example.com/{DATE}' \ -H "X-Auth-Email: <EMAIL>" \ -H "X-Auth-Key: <API_KEY>" \ -H "R2-Access-Key-Id: R2_ACCESS_KEY_ID" \ -H "R2-Secret-Access-Key: R2_SECRET_ACCESS_KEY" | jq .
返り値は先ほどと一緒です。
{ "ClientIP": "209.141.49.169", "ClientRequestHost": "konishi.classmethod.cf", "ClientRequestMethod": "GET", "ClientRequestURI": "/", "EdgeEndTimestamp": "2022-12-11T03:08:00Z", "EdgeResponseBytes": 1024, "EdgeResponseStatus": 200, "EdgeStartTimestamp": "2022-12-11T03:08:00Z", "RayID": "777b0367d979aAAA", "CacheCacheStatus": "dynamic", "CacheReserveUsed": false, "CacheTieredFill": false, "CacheResponseBytes": 2564, "CacheResponseStatus": 200 }
また、ログが生成されるまでには現状若干のタイムラグがあります。
だいたいは1分未満でログが生成されるとのことです。
最後に
元々 Logpush はエンタープライズ限定機能でしたが、先日のアナウンスでは今後全プランに開放予定とのことです。
https://blog.cloudflare.com/announcing-logs-engine/
we will start offering these services to customers at any scale