tl; dr;
- graphQLのリクエストは全て同一のURLとなる
- 通信エラーの場合、sentry上では同一URLとなってしまい、operationがわからなくなる
- 外部のOSS(apollo-link-sentry)を入れてgraphqlのリクエストの中身を見れるようにする
発生する問題
graphQLのリクエストは基本的には全て同一のURLのPOSTリクエストになる。(GETリクエストに意図的に変えることも場合によっては可能, たしか)。 sentryでネットワークエラーを検知した場合、同一のURLとなってしまい原因の判別に時間がかかってしまう。
画像引用下: apollo-link-sentry
対応
上記の問題に対して解決策を提供するライブラリとして、 apollo-link-sentryがある。
導入することによって、上記のリクエストエラーが下記のように表示され、 クエリのoperationやerrorの内容を表示させることができる。 詳しい導入はGitHubのREADMEを確認するのが良いと思う。
画像引用下: apollo-link-sentry
注意点
注意点としてどこまでの情報を出力するか、がある。 transactionでの出力を有効にしているような場合、エラー以外でもsentryにログが残る。 ここで、通常のレスポンス内容も出力してしまうと、個人情報がsentryに乗る可能性もでてきてしまい、 security上非常によろしくない。(場合によってはGDPRにも引っかかる)
apollo-link-sentryでは、初期化のタイミングでどの情報を出力させるかを設定できるので、そこで表示する情報を絞る。
new SentryLink(/* See options */)
https://github.com/DiederikvandenB/apollo-link-sentry/blob/master/src/options.ts
下記のような設定で良いのではないかと思う。 variableには場合によっては個人情報が載る可能性があるので、出力せず、queryの内容とerrorのみ出力するようにする。 そうすると個人情報が載る可能性は抑えられる。
const sentryLink = new SentryLink({ uri:URL, setTransaction: true, setFingerprint: true, attachBreadcrumbs: { includeQuery: true, includeVariables: false, includeFetchResult: false, includeError: true, includeCache: false, }, });
ただエラーに個人情報を出力させてしまっている場合にはその限りではない。 その場合はoptionの中にあるtransformでsentryに送る前に該当の出力を排除するようにする必要がありそう。
備考
今回はReactを例にとったが、swift、kotlinなどでも同様のはず。 graphqlとそのエラー検知の組み合わせの場合には、通信の内容が出力されるような工夫が何かしら必要になってくると思う。
※ライブラリがない場合はsentryのBreadcrumbsにgraphqlのリクエストの内容を付与して送るような処理を自分で作って、 clientのlinkに繋ぐ必要がありそう。