Chatwork Creator's Note

ビジネスチャット「Chatwork」のエンジニアとデザイナーのブログです。

ビジネスチャット「Chatwork」のエンジニアとデザイナーのブログです。

読者になる

Datadog RUMを使ってクライアントからの過剰リクエストを監視する

こんにちは!フロントエンド開発部の澁谷(@shibe23)です。
この記事は Chatwork Advent Calendar 2022 22日目の記事です

ChatworkはDAUが101.7万人 (2022年3Q中の中央値)、かつユーザーの滞在時間も非常に長いサービスとなっています。
そのため、クライアントサイドの不具合によって過剰にAPIリクエストが行われた場合、通信負荷(とインフラ費用)が膨大になってしまいます。

APIのリクエストが過剰に行われていることを検知したいのですが、以下のような要件から、クライアント側でエラーを検知できるようにしたいと考えました。

  • どのリリースで問題が起きたかを判断するため、フロントエンド側のリリース情報を含めて検知したい
  • 社内検証の時点で検知できることが望ましいため、社内環境をフィルタリングしてアラートの閾値をコントロールしたい
  • 通常のユースケースでも特定のAPIが大量に叩かれるため、サーバーサイドからは一時的にリクエストが増えた程度では問題かどうかを検知しづらい

調査の結果、DatadogRUM(Datadog Realtime User Monitoring)を導入することにしました。 その他の候補としてはNewRelicが挙がりましたが、検知対象となるイベントの仕組みがChatworkの特性とマッチしなかったため、今回はDatadogRUMを利用することになりました。

導入にあたってハマった点がいくつかありましたので、以降でご紹介したいと思います。

DatadogRUMを導入する

基本的な概念

DatadogRUMは、ブラウザのパフォーマンス、エラー、ユーザー体験にまつわるメトリクスを収集・可視化できるツールです。 今回はAPIリクエストにまつわる情報を利用します。

DatadogRUMはユーザーのアクションを「セッション」という単位でまとめて管理しており、課金もセッション単位で集計しています。
15分ユーザーのアクションがない、または4時間ユーザーアクションが続いた場合は1セッションとして区切られます。
セッション内のデータは、Webページにアクセスするごとに「ビュー」という単位で保存され、その中に、どのようなリソースにアクセスしたか、どのようなエラーが出たか、といった詳細情報がまとめられます。

公式の概念図を引用すると、下記のようになります。

Datadog RUMの概念図 (引用元: 収集された RUM ブラウザデータ)

詳細は下記が参考になります。
セッションの期限について: RUM とセッションリプレイの課金

セッション単位で取得できるデータの詳細: 収集された RUM ブラウザデータ

プランと課金データ

料金プランには2種類あります。 今回はResourceに含まれる情報が必要だったため、Browser Premiumを利用しました。

プラン名 説明
Browser Sessionなど、最低限の情報が収集できる
Browser Premium 下記が追加で収集できる
- Session Replay (ユーザーの行動をビジュアルで確認できる)
- Resource (APIや画像などのリクエスト情報).
- Long Task (50ms以上かかっている処理)

SDKの利用方法

SDKのオプションは下記を設定しています。 オプションの設定については、内容によってBrowser Premiumとしてとれるかどうか変わってくるため注意が必要です。

標準でservice, env, versionというkeyを設定できるため、ビルド時のリリースバージョンなど、監視に利用する値はこれらに入れてしまいます。

import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
  applicationId: 'xxxxx',
  clientToken: 'xxxxx',
  site: 'datadoghq.com',
  service:'chatwork-frontend',
  sampleRate: 100,
  premiumSampleRate: 100,
  trackInteractions: false,
  defaultPrivacyLevel: "mask",
  // 以下にアプリケーションやビルド固有の情報を追加する
  service: 'chatwork-frontend',
  env: releaseChannel, 
  version: commitID,
});

オプションの設定は少しクセがあるので、特に注意するポイントを抜粋します。

共通して必要な項目

  • sampleRate … 全体のセッションのうち何%をDatadogに送信するか

Browser Premiumを使いたい時に必要な項目

  • premiumSampleRate … sampleRate で絞った数のうち、何%をBrowser Premiumのデータとして集計するか

    • sampleRate が50でpremiumSampleRate が50の場合、全体の半分のセッションがDatadogに送信され、そのうち半分がBrowser Premiumのデータとして記録されます
    • ResourceやLong Taskなど、Session Replay以外の情報が必要な場合、0より上にする必要があります
    • SessionReplayはstartSessionReplayRecording()を実行しない限り記録されません
  • trackInteractions …. ユーザーのクリックイベントなどの詳細を記録するかどうか

    • Session Replayとは無関係ですが、クリックしたDOM要素のテキストなどが含まれる可能性があるので、必要がなければfalseにしておくことをオススメします

Session Replayを使いたい時に必要な項目

  • defaultPrivacyLevel … SessionReplayで送信されるデータの機密情報をマスクするかどうか
    • maskにするとDOMに含まれるテキストが全てxxxに置き換わります。ユーザー情報が見えてしまう恐れがあるので、Session Replayを使う場合は必ずmask にすることをおススメします
  • datadogRum.startSessionReplayRecording() … SessionReplayを有効にします

また、Session Replayは無効にしていますが、ユーザーのデータを意図せず取得することがないよう、自動テストなどで設定の誤変更を検知するなど含めて、厳重に管理することをお勧めします。

// datadogRUM.js
export const initConfiguration = {
  applicationId: "xxxx-xxx-xx",
  clientToken: "abcd12345678",
  site: "datadoghq.com",
  service: "test-service",
  premiumSampleRate: 0,
  trackInteractions: false,
  trackFrustrations: false,
  defaultPrivacyLevel: "mask"
};
// datadogRUM.test.js
import { initConfiguration } from "./index";

test("DatadogRUM configs are keep privacy safety.", () => {
  expect(initConfiguration).toEqual(
    expect.objectContaining({
      trackInteractions: false,
      trackFrustrations: false,
      defaultPrivacyLevel: "mask"
    })
  );
});

ダッシュボードでの確認

DatadogRUM利用開始時に、デフォルトでいくつかダッシュボードが追加されます。

「Dashboard」または「UX Monitering」という項目にダッシュボードが表示されます。

表示されているグラフの任意の点をクリックし、View RUM events を選ぶことで、Sessions & Replays画面に遷移し、RUMで取得したセッションの中身を見ることができます。

Dev toolのNetworkを見てもDatadogにデータが送信されていないときは

  • sampleRate を100未満にしていると、セッションが送られないためNetworkタブを見ても何も起こらない場合があります
  • セッションの管理はCookieで行っており、_dd_s というkeyのCookieを削除してリロードをすると計測対象になり、通信が確認できるようになります

チャットに通知する

イベントが取得できれば、次は監視の設定になります。

Monitorに監視設定を追加する

Datadogの「Monitor」を使ってChatworkへの通知を行うことができます。
MonitorはChatworkへ直接通知することもできるのですが、今回は任意のメッセージを挟みたいため、Webhook経由でZapierから投稿するようにしました。

「Monitor」 -> 「Real User Monitoring」を選択し、監視対象としたい値を設定します。

Monitorの設定画面

実際の運用では、社内環境かどうか、かつエンドポイントやリリースバージョンごとにAPIリクエストをグループ分けし、一定の閾値を超えたタイミングでアラートを出すようにしています。

ZapierでChatworkに通知する

WebhookをトリガーにしてChatworkに投稿します。ここは受け取ったメッセージにメンションを加えて流しているだけです。

Zapierの設定画面

これでリクエストが閾値に達した時にChatworkに通知されるようになりました!

Chatworkで通知が届いたところ

最後に

DatadogRUMは概念に慣れていないとどのように設定するのがいいか分からない点が多いのですが、今回の記事がみなさんの導入に役立てば幸いです。

Chatworkではフロントエンドの実装だけではなく、アプリケーションの運用についても改善したいという方を募集しています。

興味を持たれた方はぜひご応募ください!

hrmos.co