はじめに
Cloudflare Pages Functionsを利用すると、SSRを行うフレームワークを利用してWebアプリケーションを簡単に構築できる。例えば、SvelteKitではCloudflare Pagesに書かれているように、すぐにWebアプリケーションを開発・デプロイすることができる。
しかし、以下の記事等を見る限り、Pages Functionsのログは永続化して保存することがCloudflare側に備わっているデフォルトの機能ではできない。
- Products > Pages > Functions > Debugging and logging
- CloudFlare Pages(Functions)のログを永続保管したい
- Cloudflare PagesのPages Functionsでログを取る
また、Logpushというサービスがあるようだが、これはエンタープライズプランのみであり、個人開発やプロプラン等で利用している場合には選択肢に入らないだろう。
なんとかしてリアルタイムにログを残して、それを永続化できないか?と思い、今回、wrangler pages deployment tail
コマンドとGoogle Driveへの保存を組みわせて行うことで、ログの永続化をやってみた。
どのようにやるか?
そんなに複雑ではなく以下のようにして実現する。
- Google Driveをローカルのディレクトリにマウントする
- Wranglerのdeployment tailでリアルタイムにログを収集し、ファイルに書き出す
- ファイルを定期的にGoogle Driveをマウントしたディレクトリにコピーする
以下では、順を追ってやっていく。
1. Google Driveをローカルのディレクトリにマウントする
OSによるが、私は古いPCにxubuntuを入れ直したPCで今回のことをやるので、google-drive-ocamlfuse
を利用する(WindowsのPCならデスクトップアプリのインストーラーがあるのでそれでいい)。
インストール手順はGitHubのREADMEに書いてある通りで以下のようになる。
sudo add-apt-repository ppa:alessandro-strada/ppa
sudo apt-get update
sudo apt-get install google-drive-ocamlfuse
続いて、google-drive-ocamlfuse
はGoogle Drive APIを利用するので、おなじみのOAuth2.0のための設定をする。
この手順を終えたら、以下のようにしてgoogle-drive-ocamlfuse
にクライアントの情報を設定する。
google-drive-ocamlfuse -id xxxxxxxxxx.apps.googleusercontent.com -secret XXX-YYY-ZZZ
あとは、Google Driveをマウントさせたいローカルディレクトリを作成して、
$ google-drive-ocamlfuse ~/gdrive
というようにマウントを行えばいい。
2. Wranglerのdeployment tailでリアルタイムにログを収集し、ファイルに書き出す
これは特に何か特別なことは何もなく、以下のようにコマンドを実行するだけ。
$ npx wrangler pages deployment tail DEPLOYMENT_ID --project-name PROJECT_NAME | tee ~/logs/pages-functions.log
3. ファイルを定期的にGoogle Driveをマウントしたディレクトリにコピーする
これはシェルを書くことになるが、何も難しいことはなく以下のようなスクリプトを書いて実行すればいい。
#!/bin/bash
while true; do
rotate_log_files
cp $HOME/logs/pages-functions.log ~/gdrive/logs/pages-functions.log
sync
sleep 5
done
$ ~/sync-logs.sh
まとめると…
ここまで1つずつ順を追って見てきたが、2, 3の手順は1つのシェルにまとめてしまえるので、最終的には以下のシェルを実行すればいい(日付ごとにログファイルを分けるとか色々機能を追加しているが)。
#!/bin/bash
# デプロイメントIDを引数から取得し、存在しない場合はエラーを表示して終了
if [ -z "$1" ]; then
echo "Error: Deployment ID is required."
echo "Usage: Deployment ID is required."
exit 1
fi
DEPLOYMENT_ID=$1
echo "Deployment ID: $DEPLOYMENT_ID"
# Googleドライブのディレクトリを設定
GDRIVE_DIR="$HOME/gdrive/japan-meat-map"
# Googleドライブのディレクトリが存在することを確認し、存在しない場合は作成
echo "Checking if Google Drive directory exists..."
mkdir -p "$GDRIVE_DIR"
echo "Google Drive directory: $GDRIVE_DIR"
# ローカルファイルのパスを設定
LOCAL_LOG_FILE="/tmp/japan-meat-map.log"
echo "Local log file: $LOCAL_LOG_FILE"
# 初期のGoogleドライブのファイルパスを設定
GDRIVE_LOG_FILE="$GDRIVE_DIR/japan-meat-map.log"
echo "Google Drive log file: $GDRIVE_LOG_FILE"
# npxコマンドの出力をローカルファイルにリアルタイムで書き出す
echo "Starting npx wrangler..."
npx wrangler pages deployment tail "$DEPLOYMENT_ID" --project-name japan-meat-map | tee -a "$LOCAL_LOG_FILE" &
echo "npx wrangler started. Logging to $LOCAL_LOG_FILE"
# ログファイルの同期を5秒ごとに行うバックグラウンドプロセス
while true; do
if [ -f "$LOCAL_LOG_FILE" ]; then
cp "$LOCAL_LOG_FILE" "$GDRIVE_LOG_FILE"
sync
echo "Log file synced to Google Drive at $(date)"
else
echo "Local log file not found at $(date)"
fi
sleep 5
done
$ ~/tail_and_sync_logs.sh DEPLOY_ID
上記のシェルを実行し続ければリアルタイムにGoogle Driveログを残すことができる。
まとめとして
今回はCloudflare Pages Functionsのログを永続化し、かつリアルタイムにログを確認できる仕組みを構築してみた。
思ったよりも簡単にできたな感じた一方、以下のような課題もあるので、それを解消する方法がないかは今後も探っていきたいと思った(Cloudflareの制限事項はどうしようもないが)。
- https://developers.cloudflare.com/pages/functions/debugging-and-logging/#limits に書かれている制限があり、特にリクエスト/秒が過去5分間に100を超えた場合、ログは表示されません(Logs will not display if the Function’s requests per second are over 100 for the last five minutes.) とあるので、アクセスが多いとログが取れない
- シェルを動かすPCなど(AWSのEC2とかでも可)が必要で、そのPCが落ちるとログは取れない
- (正確に仕様がわかっていないが)
deployment id
がデプロイごとに変わる場合、その更新が必要になる
Google Drive APIは無料で利用可能(2024年7月時点で)。変更される場合もあるので最新の情報をチェックしてください。
https://developers.google.com/drive/api/guides/limits#pricing