Cloud Pub/SubのBigQuery Subscriptionでエラー内容を取得できるようになった話
ZOZO Advent Calendar 2023 23日目の記事になります。
これまでCloud Pub/SubのBigQuery SubscriptionにDead-letter topicを設定した際、Dead-letter topicに書き込まれた場合のエラー詳細を取得できませんでした。 例としてDead-letter topicに書き込まれた際、下記attributeが書き込まれます。何回書き込みに失敗したかはわかりますが、エラー内容についてはattributeへ書き込まれていません。
{ "CloudPubSubDeadLetterSourceDeliveryCount": "5", "CloudPubSubDeadLetterSourceSubscription": "hoge", "CloudPubSubDeadLetterSourceSubscriptionProject": "project", "CloudPubSubDeadLetterSourceTopicPublishTime": "2023-07-19T04:09:56.723+00:00", "googclient_schemaencoding": "JSON", "googclient_schemaname": "projects/project/schemas/sample", "googclient_schemarevisionid": "11111" }
12月時点でDead-letter topicに書き込まれたメッセージを確認すると、CloudPubSubDeadLetterSourceDeliveryErrorMessage
が新しく追加され、BigQueryのテーブル書き込み時のエラーを確認できるようになりました。
{ "CloudPubSubDeadLetterSourceDeliveryCount": "5", "CloudPubSubDeadLetterSourceDeliveryErrorMessage": "Error Detail", "CloudPubSubDeadLetterSourceSubscription": "hoge", "CloudPubSubDeadLetterSourceSubscriptionProject": "project", "CloudPubSubDeadLetterSourceTopicPublishTime": "2023-12-21T17:05:38.712+00:00", "googclient_schemaencoding": "JSON", "googclient_schemaname": "projects/project/schemas/sample", "googclient_schemarevisionid": "1111" }
jsonデータだけの説明だとどのような挙動かわからないため、試しに検証環境を準備して書き込まれるか確認します。
検証環境の準備
Topicの作成
メッセージをPublishするTopicとDead-letter topic用のTopicを作成します。
メッセージをPublishするTopicをsample-topic
、Dead-letter topic用のTopicをdeadletter-topic
と名付けて作成します。
Tableの作成
下記テーブルスキーマでhogehoge
というテーブルを作成します。
{ "fields":[ { "name":"sample_timestamp", "type":"TIMESTAMP", "mode":"NULLABLE" } ] }
BigQuery Subscriptionの作成
下記設定でBigQuery Subsciptionを作成します。正常時はBigQueryに作成したテーブル(hogehoge)へ書き込まれるようにし、エラー時はDead-letter topic(deadletter-topic)へ書き込まれます。
動作確認
正常系のメッセージと異常系のメッセージをそれぞれPublishし、Dead-letter topicへ書き込まれた際の挙動を確認します。
正常系のメッセージ
下記jsonデータをtopicへPublishします。
{ "sample_timestamp":"2023-12-23 10:00:00" }
BigQuery Subscriptionに紐づいているテーブルを確認すると、きちんと書き込まれていることが確認できます。
異常系のメッセージ
次に下記jsonデータをtopicへPublishします。BigQueryのテーブルスキーマはtimestamp型なのでこのjsonデータはBigQueryへ書き込まれずDead-letter topicへ書き込まれるはずです。
{ "sample_timestamp":"aaaaaaaa" }
下記コマンドを実行し、Dead-letter topicに紐づいているSubscriptionを確認します。
gcloud pubsub subscriptions pull deadletter-subscription --format=json
上記コマンドを実行し、取得できたjsonデータは下記になります。CloudPubSubDeadLetterSourceDeliveryErrorMessage
にBigQueryへinsertできなかった原因が書き込まれていることがわかります。
{ "ackId": "", "message": { "attributes": { "CloudPubSubDeadLetterSourceDeliveryCount": "5", "CloudPubSubDeadLetterSourceDeliveryErrorMessage": "Could not parse 'aaaaaaaa' as a timestamp. Required format is YYYY-MM-DD HH:MM[:SS[.SSSSSS]]", "CloudPubSubDeadLetterSourceSubscription": "bigquery-subscription", "CloudPubSubDeadLetterSourceSubscriptionProject": "", "CloudPubSubDeadLetterSourceTopicPublishTime": "2023-12-23T09:25:44.378+00:00", "googclient_schemaencoding": "JSON", "googclient_schemaname": "sample-schema", "googclient_schemarevisionid": "" }, "data": "", "messageId": "", "publishTime": "2023-12-23T09:25:48.511Z" } }
まとめ
BigQuery Subscriptionを利用し、Dead-letter topicへ送られたデータのエラー原因を取得できるようになっていました。BigQuery Subscriptionを利用しはじめた当初はエラー原因が取得できず都度データを再度Publishして検証する手間があったので非常にありがたいです…!