本番環境で運用する AppSync と仲良くなるために知っておきたいこと 【ログ編】
こんにちは。@hayata-yamamotoです。
今回は、AppSync と CloudWatch Logs をテーマに、AppSync で提供しているサービスのデバッグやログ調査の運用ノウハウを紹介します。
なお、本記事はとある LT 会で発表した AppSync の登壇資料がベースとなっております。
背景
弊社は現在、AppSync で提供していたバックエンド機能を APIGateway に移行中です。
背景はさまざまありますが、最も大きな理由には AppSync の開発及び品質保証、デバッグの難しさが挙げられます(背景などを説明したブログはこちら)
とはいえ、AppSync の運用を年単位で行うとそれなりにうまく使えるようになり、AppSync をリプレイスにしても、蓄積したノウハウをこのままにしておくのはもったいないと思いこの記事を執筆しています。現在、AppSync を運用している方、そして AppSync わからないなぁと思っている人に、少し参考になる内容になっていれば嬉しいです。
AppSync について
AppSync とは、最新のウェブおよびモバイルアプリケーションの構築を簡素化するサーバーレス GraphQL および Pub/Sub API のサービスです。[1]
弊社では、GraphQL API をメインに用いてバックエンドシステムを開発運用してきました。現在も API 自体は残っていますが、徐々に利用は減少傾向にあり、徐々に APIGateway ベースのバックエンドに移行して行っています。
AppSync を構成する要素
AppSync の GraphQL API を利用する際には、以下のようなリソースを作成し運用します。[2]
- GraphQL スキーマ
- データソース
- リゾルバー
さらに、用途によってはリゾルバー内で用いる 関数 を定義したりもします。要するに以下のような構成になります。関数を定義する際は、リゾルバーに関数が複数紐づいてきます。
AppSync のログ
AppSync のログは、コンソールの「ログ設定」のページで有効化することができます。[3] 設定では、ログだけでなく, WAF や X-Ray などセキュリティ設定を行うこともできます。
ログ機能の設定
AppSync にはログの種類が大きく分けて 2 種類あります。[4]
- リクエストレベルログ(「詳細コンテンツを含める」設定が有効の時のみ)
- フィールドレベルのログ
またフィールドレベルのログに関しては、3種類のログ記録方法があります。
- なし(フィールドリゾルバーはログを出さない)
- エラー(フィールドリゾルバーがエラーを出した時のみ)
- すべて(全てのログを記録)
弊社は当初、「エラー」でシステムを運用しておりましたが、現在は「すべて」のログが残るように設定を変更して運用しています。顧客問い合わせなどが発生した際に、エラーログのみしか残っていないと、調査が難航してしまうケースが何度かあったためです。
まとめると、おすすめの設定は以下です。
一度設定してみてログが多ければ、少なくしていくスタンスで運用すると良いでしょう。
ログの種類の整理
AppSync のログ記録を有効化したら、CloudWatch にログが流れ込むようになります。/aws/appsync/apis/xxxxxxxx
のようなロググループに全スキーマの実行ログが溜まっていくため、調査の際は CloudWatch Logs Insights を用いることが欠かせません。
AppSync の場合は、自分達でロガーを設定してるわけでもなく、勝手にログがまとまってくるため、ログ調査においては以下の3点に注意が必要です。
- 「どんなログが」
- 「いつ発行されて」
- 「どんな内容を有しているか」
こちら を参考に、表にまとめてみました。AppSync のリゾルバー内で複数の関数を呼び出す「パイプラインリゾルバー」を使っていると、公式ドキュメントに掲載されているよりも、もっと多様なログが吐き出されるため注意が必要です。
ログタイプ | いつ | どんな内容か |
---|---|---|
RequestSummary | リクエストの処理が終了した時 | requestId, statusCode など |
ExecutionSummary | リゾルバーに対する処理が終了した時 | 開始時間や経過時間、処理にかかった時間の情報が複数残る |
Tracing | フィールドリゾルバーのログ設定による | フィールドのデータやマッピングの情報など |
BeforeMapping | パイプラインリゾルバーのリクエストマッピングテンプレートが実行される時 | マッピングテンプレートが実行された時のデータ(context や 引数など) |
RequestMapping | パイプラインに指定された関数のリクエストマッピングテンプレートが実行された時 | マッピングテンプレートが実行された時のデータ(context, 引数, 前の実行結果など) |
ResponseMapping | パイプラインに指定された関数のレスポンスマッピングテンプレートが実行された時 | マッピングテンプレートが実行された時のデータ(context, 引数, 前の実行結果など) |
AfterMapping | パイプラインリゾルバーのレスポンスマッピングテンプレートが実行された時 | マッピングテンプレートが実行された時のデータ(context や 引数など) |
ログ調査
AppSync のログ調査も、他の AWS リソースでのログ調査と同様に、どうやって対象ログの requestId を見つけ出すか に注力するのが重要です。requestId が引き出せれば、一覧のログを一発で確認できるため、リクエストの最初から最後までを網羅的に確認することができるからです。
調査フローを簡単にまとめると以下のようになります。
上記のフローに基づいて、CloudWatch Logs Insights から対象のログを以下のクエリを用いて検索し、調査を進めるイメージです。
requestId を調査する際に使用するクエリ
fields @timestamp, @message
| filter @message like "<ResolverName>"
対象のリゾルバーに関連するログが出力されてきたら、以下のような手順で問題が発生しているログを調査します。
- AfterMapping を確認する(パイプラインの最後の手順のため)
- 問題が発生しているログを見つけたら、 requestId を控える
requestId が判明した時に使うクエリ
fields @timestamp, @message
| filter requestId = '<requestId>'
問題が発生しているリクエストが見つけ出せる状態になっているため、以下のような手順で問題が発生した箇所を特定します。
- AfterMapping を確認する
- AfterMapping から ResponseMapping を遡る
- 問題が発生している ResponseMapping を特定する
- RequestMapping の TransformedTemplate を確認し、処理に問題がないかを確認する
- 問題がある場合は修正する
終わりに
今回は、AppSync をテーマに、リソースの構成とログの機能、そして調査方法についてまとめてみました。現在は、AppSync のリソースは徐々に利用縮小をして行っていますが、代わりに APIGateway をはじめとする別のサーバーレスリソースを活用しています。
弊社のプロダクトや開発に少しでもご興味持っていただけたら、是非カジュアル面談などにお越しください!
Discussion