
Cloud Schedulerのジョブからgcloudコマンドでジョブ内のデータを取得してみた
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
データアナリティクス事業本部の根本です。gcloudコマンドで、Cloud Schedulerに設定してあるPub/SubターゲットのジョブでPub/Subメッセージ本文を抽出する機会があり、折角なのでスクリプトなどをまとめて記事にしてみました。
この記事の対象者
- gcloudコマンドでCloud Schedulerに設定してあるPub/Subターゲットのジョブに設定してあるPub/Subメッセージ本文をシェルスクリプトで抽出したいひと
前提条件
- gcloudコマンドが使用できること
やりたいこと
- シェルスクリプトで指定ジョブのPub/Subメッセージ本文を抽出したい
Cloud Schedulerには以下の設定値でジョブが登録されています。
設定項目名 | 設定値 |
---|---|
ジョブ名 | test-scheduler |
ターゲットタイプ | Pub/Sub |
リージョン | asia-northeast1 |
メッセージ本文 | {"params": {"bucket": "test-bucket", "content": "hello-scheduler"}} |
やってみる
まずはリファレンスを参照しました。
リファレンスを見てみると
gcloud scheduler jobs describe
上記コマンドで取得できそうだったので早速叩いてみました。
gcloud scheduler jobs describe "test-scheduler" --location="asia-northeast1" --format="json"
レスポンスは以下でした。
{
"lastAttemptTime": "2024-05-19T15:00:00.314187Z",
"name": "projects/プロジェクト名/locations/asia-northeast1/jobs/test-scheduler",
"pubsubTarget": {
"data": "eyJwYXJhbXMiOiB7ImJ1Y2tldCI6ICJ0ZXN0LWJ1Y2tldCIsICJjb250ZW50IjogImhlbGxvLXNjaGVkdWxlciJ9fQ==",
"topicName": "projects/プロジェクト名/topics/トピック名"
},
"retryConfig": {
"maxBackoffDuration": "3600s",
"maxDoublings": 1,
"maxRetryDuration": "0s",
"minBackoffDuration": "5s"
},
"schedule": "00 00 * * *",
"state": "PAUSED",
"timeZone": "Asia/Tokyo",
"userUpdateTime": "2024-05-20T07:28:15Z"
}
上記のレスポンスをみると、pubsubTarget
のデータがBase64
でエンコードされていました。取得項目を見る限り、このpubsubTarget
がPub/Sub関連データが入っているのではないかと推測します。Cloud Scheduler上のPub/SubターゲットのデータもBase64にエンコードされているとは思いませんでした。
Cloud Functions関数でPub/Subメッセージからデータ取得するときはBase64をデコードするのはよくやるやつですが、同じことをやってあげる必要がありそうです。
以下のコマンドでデコードしてみました。
gcloud scheduler jobs describe "test-scheduler" --location="asia-northeast1" --format="json" \
| jq -r '.pubsubTarget.data' \
| base64 --decode
以下の結果となり、Cloud Schedulerに登録してあるジョブのPub/Subメッセージ本文と一致していました。
{"params": {"bucket": "test-bucket", "content": "hello-scheduler"}}
コマンドの動作としてはデコードするためにpubsubTarget
のデータだけをjqコマンドで取得して、そのデータをbase64コマンドでデコードしています。
上記より、Cloud Schedulerに登録してあるジョブのPub/Subターゲットの本文はBase64でデコードする必要があるとわかりました。
シェルスクリプト化してみた
折角なのでシェルスクリプトにしてみました。
単一のジョブのPub/Subメッセージ本文を取得するシェルスクリプト
#!/bin/bash
# ジョブの名前とリージョンを設定。ジョブ名はコマンドライン引数で取得
JOB_NAME=$1
LOCATION="asia-northeast1"
JOB_DETAILS=$(gcloud scheduler jobs describe "$JOB_NAME" --location="$LOCATION" --format="json")
MESSAGE_BASE64=$(echo "$JOB_DETAILS" | jq -r '.pubsubTarget.data')
echo "$MESSAGE_BASE64" | base64 --decode
上記スクリプトを実行します。処理の流れはコマンドラインでやっていることそのままですが、シェルスクリプトの引数にジョブ名を設定して実行するようにしています。
実行してみます。
sh scheduler_job.sh test-scheduler
実行すると以下が出力されました。
{"params": {"bucket": "test-bucket", "content": "hello-scheduler"}}
問題なく動作しています。
複数のジョブのPub/Subメッセージ本文を取得するシェルスクリプト
折角なので、たくさんジョブがある場合でも使えるようにしてみました。
#!/bin/bash
LOCATION="asia-northeast1"
# ジョブ一覧を取得
JOB_LIST=$(gcloud scheduler jobs list --location="$LOCATION" --format="json")
# すべてのジョブについてループ
for row in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do
_get_job_name() {
echo "${row}" | base64 --decode | jq -r "${1}"
}
JOB_NAME=$(_get_job_name '.name')
JOB_DETAILS=$(gcloud scheduler jobs describe "$JOB_NAME" --location="$LOCATION" --format="json")
if echo "$JOB_DETAILS" | jq -e '.pubsubTarget' > /dev/null; then
MESSAGE_BASE64=$(echo "$JOB_DETAILS" | jq -r '.pubsubTarget.data')
echo "Job Name: $JOB_NAME"
echo "Message: $MESSAGE"
echo "$MESSAGE_BASE64" | base64 --decode
echo ""
else
echo "not Pub/Sub target."
fi
done
簡単に説明しますと、ジョブ一覧を取得してその一覧を元にループ処理しています。Pub/Subターゲット以外のジョブもあると思うので、
Pub/Subターゲット以外だったら処理をスキップするようにしています。
実行結果はCloud Schedulerに設定してあるジョブによります。以下は2件ジョブを登録していた場合の結果です。
Job Name: projects/プロジェクト名/locations/asia-northeast1/jobs/test-scheduler
Message:
{"params": {"bucket": "test-bucket", "content": "hello-scheduler"}}
Job Name: projects/プロジェクト名/locations/asia-northeast1/jobs/test-scheduler-2
Message:
{"params": {"bucket": "test-bucket-2", "content": "this-is-scheduler-2"}}
おわりに
Base64でエンコードされていると思っていなかったので少し驚きましたが、それ以外は特に詰まるところもなくコマンド実行できました。
この記事がどなたかのお役に立てば幸いです。それではまた。