広告枠を募集中 ご相談ください

Optimizelyがソフトウェアリリースチーム向けに機能フラグとプログレッシブロールアウトを管理する仕組み

365Finds Editorial
Wiki 記事 11,430 本収録

あなたの AI で 365 Wiki を使う

下のプロンプトをコピーして、普段使っている AI に貼り付け、そのまま質問してください。

完全版 Skill をダウンロード

まずはプロンプトでお試しください。よく使う場合は完全版 365Wiki Skill をインストールすると、毎回貼り付ける必要がありません。普段使う AI がなければ、Gemini や Microsoft Copilot のウェブ版でも使えます。

Optimizely Feature Experimentation は、最新のソフトウェアエンジニアリング、プラットフォーム、およびプロダクトデリバリーチーム向けに、クラウド、モバイル、エッジ環境全体で機能フラグ(Feature Flags)を管理し、プログレッシブロールアウト(段階的リリース)を実行するための集中管理プレーンを提供します。組織が継続的インテグレーションおよび継続的デリバリー(CI/CD)パイプラインを採用するにつれて、コードのデプロイと機能のリリースを直接結びつけることは重大な運用のボトルネックを生み出し、リグレッション発生時に障害影響範囲(ブラストレイディウス)を拡大させます。Optimizely は、ランタイムロジックを確定的かつリモートで管理されるフラグの背後にカプセル化することで、デプロイとリリースを分離(デカップリング)します。分散型 JSON 構成アーキテクチャ(Datafile)、高性能なクライアントおよびサーバー SDK、そしてローカルの MurmurHash3 バケット分割アルゴリズムを通じて、Optimizely はランタイムネットワーク遅延ゼロで、カナリアリリース、社内ドッグフーディング、きめ細かなオーディエンスターゲティング、自動化されたパーセンテージ拡大を実現します。さらに、即時キルスイッチ機能と統合された統計追跡機能により、ソフトウェアチームは数秒以内に障害を緩和し、本格的な全面展開の前に運用の主要業績評価指標(KPI)に照らしてシステム性能を検証できます。

デカップリングされた機能デリバリーのアーキテクチャ

従来のモノリシックなデプロイ方式では、エンジニアリングチームはソフトウェアリリースを「オール・オア・ナッシング」のハイリスクなイベントとして扱わざるを得ませんでした。新しくデプロイされたマイクロサービスにデータベース接続リークが発生したり、更新された決済フローが特定のモバイルブラウザでクラッシュした場合、チームは性急な緊急修正パッチをプッシュするか、高コストなロールバックを発動する必要がありました。Optimizely Feature Experimentation は、コードのコンパイルとランタイムでの機能実行の間にプログラマブルな決定レイヤーを挿入することで、このモデルを再構築します。

+-----------------------------------------------------------------------------------+
|               OPTIMIZELY 機能フラグ&プログレッシブロールアウトパイプライン        |
+-----------------------------------------------------------------------------------+
| 1. ダッシュボード&構成プレーン                                                   |
|    - Optimizely 管理インターフェース / REST API / CI/CD パイプライン自動化        |
|    - 機能フラグ、変数(string、number、JSON、bool)、環境の定義                   |
|    - オーディエンスターゲティングルールと段階的ロールアウト比率の設定             |
+-----------------------------------------+-----------------------------------------+
                                          |
                                          | 構成状態をコンパイル
                                          v
+-----------------------------------------------------------------------------------+
| 2. エッジ配信& DATAFILE                                                          |
|    - プロジェクトスキーマ、フラグ、ルール、ハッシュを含む読み取り専用 JSON        |
|    - Akamai/Fastly コンテンツ配信ネットワーク(CDN)経由でグローバル配信          |
|    - リアルタイム Webhook 通知によりアプリケーションサーバーに変更を即時伝達      |
+-----------------------------------------+-----------------------------------------+
                                          |
                                          | CDN または Webhook 経由で取得/ストリーミング
                                          v
+-----------------------------------------------------------------------------------+
| 3. SDK/AGENT によるインメモリ評価                                                |
|    - SDK(Node.js、Go、Python、Java、C#、Swift、Android、React)が Datafile をキャッシュ|
|    - Optimizely Agent(マイクロサービス)がローカル REST / gRPC 評価を提供        |
|    - createUserContext(userId, attributes) がビジターパラメータをメモリ内でバインド |
|    - 決定論的 MurmurHash3 評価によりサブミリ秒でバケット割り当てを計算            |
+-----------------------------------------+-----------------------------------------+
                                          |
                                          | 非同期・ノンブロッキングのメトリクス収集
                                          v
+-----------------------------------------------------------------------------------+
| 4. テレメトリ、統計&セーフティコントロール                                       |
|    - バックグラウンドバッチ処理によるインプレッションおよびコンバージョンイベント送信|
|    - リアルタイムエラー監視と APM スパンタグ付け(Datadog、New Relic、Sentry)     |
|    - グローバルキルスイッチ:再デプロイなしでミリ秒単位でトラフィックを 0% へ復帰 |
+-----------------------------------------------------------------------------------+

Datafile の役割と仕組み

Optimizely アーキテクチャの中心にあるのが Datafile です。これはプロジェクト全体の機能構成を表現する軽量な JSON データです。フラグの評価が発生するたびにアプリケーションコードから Optimizely のサーバーへ外部 HTTP リクエストを送信させるのではなく、Optimizely SDK が Datafile を直接ダウンロードし、ローカルアプリケーションのメモリ内にキャッシュします。

Datafile には以下の要素が含まれます。

Datafile は世界中に分散された CDN に配置されているため、アプリケーションの起動時間は極めて高速に保たれます。長時間稼働するサーバープロセスのために、SDK は設定可能なバックグラウンドポーリングによって定期的に Datafile を更新するか、エンジニアが Optimizely 管理画面でフラグ設定を変更した際にトリガーされるインバウンド Webhook を介してほぼ即座に同期します。

マイクロサービスアーキテクチャ向け Optimizely Agent

多言語で記述されたマイクロサービスが広範に展開する複雑な分散アーキテクチャでは、数十のサービスにそれぞれネイティブ言語の SDK を導入・管理することが運用のオーバーヘッドとなる場合があります。これを解決するために、Optimizely はオープンソースで Go 言語製のコンテナ化されたサイドカーマイクロサービス「Optimizely Agent」を提供しています。

Optimizely Agent は、Kubernetes の Pod やサイドカーコンテナのように、アプリケーションワークロードに隣接して稼働します。Datafile の同期、バックグラウンドでのイベントバッチ処理、Webhook のリスニングを一括管理し、ローカルアプリケーションに対して高スループットな REST および gRPC エンドポイントを公開します。これにより、特殊なランタイムやレガシー環境で作業するチームでも、言語固有の Datafile ライフサイクルを管理することなく、確定的機能フラグの利点を活用できます。

プログレッシブロールアウトのメカニズム

プログレッシブロールアウト(段階的リリース、段階的ランプ、フェーズドリリーストとも呼ばれる)とは、トラフィックの 100% を一度に公開するのではなく、段階的に拡大するユーザーサブセットに対して新機能を順次公開していくプラクティスです。Optimizely は、ターゲットデリバリー(Targeted Deliveries)と決定論的トラフィックバケット分割という 2 つのコアプリミティブを通じてプログレッシブロールアウトを構成します。

ターゲットデリバリーと機能実験の比較

Optimizely プラットフォーム内では、主に 2 つのルールタイプを使用してフラグを管理します。

項目ターゲットデリバリー(ロールアウトルール)機能実験(Feature Experiment)
主な目的運用の安全性、リスク軽減、段階的デプロイユーザー行動の測定、コンバージョン率向上、統計的影響の評価
バリエーションバイナリ(通常は on または off)または単一バリエーションマルチバリアント(対照群 vs. バリエーション A vs. バリエーション B)
トラフィック分割動的調整(例: 0% -> 5% -> 25% -> 100%)有効な実験ブランチ間での静的パーセンテージ分割
決定ロギング軽量なインプレッショントラッキングまたはサイレント評価Optimizely Stats Engine が取り込む厳密な統計テレメトリ
対象オーディエンス段階的ティア(社内スタッフ、ベータテスター、地域コホート)対象顧客セグメントから無作為抽出された代表サンプル

リリースチームは、これら両方のアプローチを頻繁に組み合わせて使用します。エンジニアリングチームはターゲットデリバリーを開始して、バックエンドデータベースの最適化を 10% のユーザーに安全にロールアウトします。システムの健全性が確認されたら、プロダクトチームはそのフラグの上に機能実験を重ね、有効化されたユーザーの間で 2 種類の異なる UI レイアウトを比較テストできます。

MurmurHash3 による決定論的トラフィックバケット分割

プログレッシブロールアウトの技術的信頼性は、決定論的なバケット分割に完全に依存しています。ユーザーが Web アプリケーションにログインし、新しい決済ページが表示された後、ブラウザをリロードした瞬間に突然旧バージョンの体験に戻ってしまうと、ユーザーの信頼は損なわれ、セッション状態が破損する恐れがあります。

これを防止するため、Optimizely はコストのかかる集中型状態データベースやスティッキーセッション Cookie の管理を行いません。代わりに、SDK が MurmurHash3 アルゴリズムを使用してローカルでバリエーション割り当てを算出します。

  1. ハッシュシード生成:SDK はユーザーの一意の識別子(userId)と実験またはロールアウトルール識別子を結合してシード文字列を作成します。
  2. ハッシュ計算:シード文字列を 32 ビットの MurmurHash3 ハッシュ関数で処理し、均一に分散された疑似乱数整数を生成します。
  3. 剰余による正規化:算出されたハッシュ値を 10,000 で除算した剰余(Modulo)を取り、すべてのユーザーを 0 から 9,999 までの整数バケットへ決定論的にマッピングします。
  4. 範囲比較判定:各ロールアウト段階で、割り当てられたトラフィックパーセンテージに応じた数値バケット範囲を定義します。
    • 1% ロールアウト:バケット 0 〜 99
    • 10% ロールアウト:バケット 0 〜 999
    • 50% ロールアウト:バケット 0 〜 4,999
    • 100% ロールアウト:バケット 0 〜 9,999

モノトニック・スティッキネス(単調維持性)の保証

この連続的なバケットマッピングによる極めて重要な数学的メリットが、**モノトニック・スティッキネス(単調維持性)**です。エンジニアリングチームがロールアウト比率を 10% から 25% に引き上げると、SDK はアクティブなバケット範囲を [0, 999] から [0, 2499] へと拡大します。特定のユーザー識別子とフラグキーに対する MurmurHash3 の出力は常に同一であるため、10% の段階で 0 〜 999 のバケットに該当したユーザーは、拡張された [0, 2499] の範囲内にも必ず含まれます。アクティブな拡大プロセス中に、既存ユーザーがレガシー状態に意図せず引き戻されることは決してありません。

きめ細かなオーディエンスセグメンテーション

プログレッシブロールアウトが不特定の一般トラフィックから開始されることはほとんどありません。エンジニアリングチームはオーディエンス定義を活用し、明確な運用コホートに段階分けしてリリースを進めます。Optimizely は、実行時に SDK へ渡されるカスタム属性に基づいて、オーディエンスルールを順次評価します。

+-----------------------------------------------------------------------------------+
|                           ルール評価優先順位のフロー                              |
+-----------------------------------------------------------------------------------+
| ルール 1: 社内スタッフ向けドッグフーディング                                      |
|           条件: email endsWith "@example.com"                                     |
|           割り当て: 100% 有効(On)                                               |
+-----------------------------------------+-----------------------------------------+
                                          | (ルール 1 に一致しない場合)
                                          v
+-----------------------------------------------------------------------------------+
| ルール 2: ベータパートナーコホート                                                |
|           条件: betaOptIn == true かつ subscriptionTier == "enterprise"           |
|           割り当て: 100% 有効(On)                                               |
+-----------------------------------------+-----------------------------------------+
                                          | (ルール 2 に一致しない場合)
                                          v
+-----------------------------------------------------------------------------------+
| ルール 3: パブリック向けプログレッシブロールアウト                                |
|           条件: その他すべてのユーザー                                            |
|           割り当て: トラフィックの 15%(MurmurHash3 バケット 0 〜 1,499)         |
+-----------------------------------------+-----------------------------------------+
                                          | (ユーザーのバケット番号 >= 1,500)
                                          v
+-----------------------------------------------------------------------------------+
| デフォルトフォールバック状態                                                      |
| 割り当て: フラグ無効 OFF(レガシー実装を維持)                                    |
+-----------------------------------------------------------------------------------+

SDK 実装ハンズオン:コンテキスト、決定、および変数

最新の Optimizely SDK は、OptimizelyUserContext を中心としたオブジェクト指向の実行パターンを採用しています。このパターンにより、ユーザー状態の初期化が個々のフラグ評価から分離され、より整理されたクリーンなコード設計が促進されます。

アプリケーションコードでのフラグ状態の決定

以下の TypeScript/Node.js の例は、ソフトウェアデリバリーチームが SDK を構成し、ユーザーコンテキストを構築し、機能フラグを評価して動的な構成変数を安全に取得する方法を示しています。

import { createInstance, OptimizelyUserContext } from '@optimizely/optimizely-sdk';

// 1. バックグラウンドでの Datafile 自動ポーリングを有効にして Optimizely クライアントを初期化
const optimizelyClient = createInstance({
  sdkKey: process.env.OPTIMIZELY_SDK_KEY,
  datafileOptions: {
    autoUpdate: true,
    updateInterval: 300000, // 5 分ごとに Datafile を同期
  },
});

await optimizelyClient.onReady();

// 2. 現在のリクエスト/セッションを表す OptimizelyUserContext を構築
function handleSearchRequest(userId: string, userAttributes: Record<string, any>, query: string) {
  const userContext: OptimizelyUserContext = optimizelyClient.createUserContext(
    userId,
    {
      country: userAttributes.country || 'US',
      subscriptionTier: userAttributes.tier || 'standard',
      isInternalTester: userAttributes.email?.endsWith('@company.com') || false,
      appVersion: '3.4.1',
    }
  );

  // 3. 機能フラグの評価を実行
  const decision = userContext.decide('vector_search_engine');

  // 特定のユーザーコンテキストに対して機能が有効化されているか確認
  if (decision.enabled) {
    // 4. Optimizely 上でリモート構成された動的機能変数を取得
    const timeoutMs = (decision.variables['request_timeout_ms'] as number) || 800;
    const similarityModel = (decision.variables['embedding_model'] as string) || 'text-embedding-3-small';
    const topK = (decision.variables['top_k_results'] as number) || 20;

    return executeVectorSearch(query, { timeoutMs, similarityModel, topK });
  }

  // レガシーなリレーショナル全文検索へのフォールバック
  return executeLegacyKeywordSearch(query);
}

機能変数によるランタイムパラメータの分離

Optimizely Feature Experimentation の大きな強みは、**機能変数(Feature Variables)**をサポートしている点です。機能フラグは単なるオン/オフの二値スイッチにとどまりません。リリースチームはロールアウトの進行中に、ソースコードを変更したり新規デプロイを行ったりすることなく、運用パラメータを微調整する必要があります。

Optimizely はフラグ内で型付けされた変数をサポートしています。

エンジニアリングチームが新しい検索エンジンを 25% のトラフィックにロールアウトした際にダウンストリームのメモリ負荷の上昇を観測した場合、ロールアウト全体を一時停止する必要はありません。エンジニアは Optimizely のダッシュボードにアクセスし、top_k_results 変数を 50 から 20 に引き下げて構成を保存するだけです。更新された Datafile は CDN 経由で配布され、数秒以内にアプリケーションメモリへ反映されます。

エンタープライズの運用安全性とキルスイッチ

プログレッシブロールアウトが計画的な機能提供を促進する一方で、機能フラグがもたらす最大の運用防衛メカニズムは**即時キルスイッチ(Instant Kill Switch)**です。

緊急ロールバックの比較構造

機能フラグを持たない従来の CI/CD ワークフローにおいて、本番環境で深刻な障害に対処するには以下のステップが必要です。

  1. 可観測性ダッシュボードで異常なエラー急増を検知する。
  2. インシデント対応チームを招集して根本原因を特定する。
  3. 原因となった Git コミットを特定する。
  4. Git revert を実行し、プルリクエストのレビューとテストスイートを実行する。
  5. CI パイプラインがコードをコンパイルし、コンテナイメージを構築してクラスターへデプロイするのを待つ。

この一連の修復サイクルには 30 分から 90 分を要することが多く、その間エンドユーザーはサービスの劣化や障害に晒され続けます。

一方、Optimizely 機能フラグを導入していれば、インシデントの緩和は単一のアクションで完了します。管理画面でフラグを Disabled に切り替えるか、ロールアウト比率を 0% に引き下げるだけです。SDK はローカルでフラグを評価し、リアルタイム Webhook またはストリーミング接続によって Datafile を即座に更新するため、キルスイッチはすべてのサーバー群へサブ秒単位で伝播します。コンテナの再起動やユーザーセッションの切断、本番インフラの変更を伴うことなく、コードの実行は瞬時に安全なレガシーフォールバックブランチへ復帰します。

可観測性と APM テレメトリの統合

安全なプログレッシブロールアウトを遂行するためには、トラフィックを拡大しながらシステムの挙動をリアルタイムで観測しなければなりません。Optimizely は、Datadog、Dynatrace、New Relic、Prometheus、Sentry などのアプリケーションパフォーマンス監視(APM)ツールと直接連携できる通知リスナー(Notification Listeners)を提供しています。

// 決定通知リスナーを登録し、APM トレースにフラグ状態を関連付ける
optimizelyClient.notificationCenter.addNotificationListener(
  'DECISION',
  ({ type, userId, attributes, decisionInfo }) => {
    if (type === 'flag') {
      const flagKey = decisionInfo.flagKey;
      const enabled = decisionInfo.enabled;
      const variationKey = decisionInfo.variationKey;

      // 現在の APM 分散トレーススパンにコンテキストタグとしてフラグ状態を付与
      tracer.getActiveSpan()?.setAttribute(`feature_flag.${flagKey}.enabled`, enabled);
      tracer.getActiveSpan()?.setAttribute(`feature_flag.${flagKey}.variation`, variationKey);
    }
  }
);

分散トレースにアクティブなフラグ評価結果をタグ付けすることで、サイト信頼性エンジニア(SRE)はフラグの状態ごとにエラーログやレイテンシメトリクスを絞り込むことができます。feature_flag.vector_search_engine.enabled == true であるリクエストでのみエラー率が跳ね上がっていることが判明した場合、チームはリグレッションを即座に特定し、広範なシステム安定性が損なわれる前にキルスイッチを発動できます。

プログレッシブロールアウトのライフサイクル:開発から廃棄まで

企業全体で数百の機能フラグを管理するには、規律あるライフサイクルガバナンスが不可欠です。放置された不要フラグは技術的負債となり、コードベースを複雑なネスト条件分岐で埋め尽くし、開発者の認知負荷を増大させます。

成熟したリリースワークフローは、通常 5 つの段階を経ます。

[フェーズ 1: ローカル開発& CI]
  │  - 新しいロジックを機能フラグでラップ
  │  - デフォルトのフォールバックを含むコードをコミット
  ▼
[フェーズ 2: 社内ドッグフーディング]
  │  - ターゲットルール: 社内スタッフ(@company.com)
  │  - 本番ステージングおよび本番環境で実動検証
  ▼
[フェーズ 3: カナリア&段階的トラフィック拡大]
  │  - 拡大ステップ: 1% -> 5% -> 25% -> 50%
  │  - APM メトリクス、CPU/メモリ、エラー率を監視
  ▼
[フェーズ 4: 100% 全面リリース]
  │  - グローバルトラフィックの 100% を有効化
  │  - 安全ネットとしてフラグを 1〜2 スプリント期間維持
  ▼
[フェーズ 5: フラグクリーンアップ&アーカイブ]
     - ソースコードからフラグラッパーを削除
     - Optimizely ダッシュボードでフラグをアーカイブ

1. 開発&ステージング(Development & Staging)

機能開発時、エンジニアは Optimizely でフラグキーを定義し、新規実装とフォールバックパスの両方を if (decision.enabled) ブロックで囲みます。コードはメインブランチにマージされ、継続的にデプロイされます。開発およびステージング環境では、フラグは QA 自動テストスイート向けに有効化されますが、本番環境では無効のままとなります。

2. 社内ドッグフーディング(Internal Dogfooding)

本番インフラへのデプロイ完了後、チームは社内メンバー(認証済みメールアドレス、IP 範囲、社内テスト Cookie で識別)に 100% のトラフィックを割り当てるオーディエンスルールを作成します。これにより、開発者、プロダクトマネージャー、社内関係者は、一般顧客に未検証ロジックを公開することなく、実稼働データベースを備えた本番環境で機能を試用できます。

3. カナリア&段階的トラフィック拡大(Canary & Phased Traffic Ramp)

ドッグフーディングで安定性が実証された後、チームは一般向けのプログレッシブロールアウトを開始します。

4. 100% 一般提供(General Availability)

ピーク時のトラフィック負荷に対してシステムが十分な回復力を示した時点で、チームはロールアウトルールを 100% に引き上げます。この段階ですべてのユーザーに新しい体験が届きますが、緊急事態への備えとしてフラグは 1〜2 スプリントサイクルの間保持されます。

5. コードのクリーンアップとアーカイブ(Code Sanitization & Archival)

新実装が 100% の状態で障害なく安定稼働したことを確認後、リリースチームは技術的負債解消チケットを発行します。エンジニアは optimizelyClient.decide() ラッパーとレガシーフォールバックロジックをコードベースから削除し、新しいコードパスのみを残します。最後に、Optimizely ダッシュボード上でフラグを Archived(アーカイブ済み) に指定し、プロジェクトのスキーマを常にクリーンかつ高速に維持します。

ガバナンス、権限、およびアクセス制御

大規模なエンジニアリング組織において、あらゆるチームメンバーが無制限に本番スイッチを操作できるようにすることは、重大なセキュリティおよび可用性のリスクを招きます。Optimizely はエンタープライズグレードのガバナンス機能によりこれらの懸念に対処します。

ビジネス価値とエンジニアリングへのインパクト

Optimizely Feature Experimentation の導入は、ソフトウェア組織全体に測定可能な組織的・経済的メリットをもたらします。

デプロイ速度の加速

デプロイをマーケティング施策のローンチやビジネス承認と同時に行う必要がなくなるため、エンジニアリングチームは 1 日に複数回コードを本番環境へ反映できるようになります。ソフトウェアエンジニアは小さくテスト容易なプルリクエストを継続的にマージでき、一括の月次リリースに伴う過酷な競合解消やデプロイ凍結を回避できます。

平均復旧時間(MTTR)の短縮

キルスイッチはローカルの Datafile 更新を通じて瞬時に機能するため、組織は平均復旧時間(MTTR)を数時間から数秒へと短縮できます。インシデントの緩和に新規コンテナイメージのビルドやデプロイを待つ必要がなくなり、ダウンタイムと顧客の不満を劇的に抑えることができます。

リリースエンジニアリングとビジネス実験の統合

オン/オフの二値トグルのみに特化したスタンドアロンのオープンソース機能フラグライブラリとは異なり、Optimizely はシステムエンジニアリングとプロダクト成長の溝を埋めます。DevOps チームがカナリアリリースに使用するのと同じインフラをマルチバリアント A/B テストへシームレスに拡張でき、配信するすべての機能についてユーザーエンゲージメント、リテンション、収益へのインパクトを正確に測定できます。

ソフトウェアチームのためのベストプラクティスまとめ

Optimizely を使用した機能フラグ管理および段階的ロールアウトにおいて信頼性と速度を最大化するために、エンジニアリングチームは以下の実践指針を遵守すべきです。

  1. 常に防御的フォールバックを実装する:SDK が未初期化状態やネットワーク障害に遭遇した場合でもアプリケーションが安全なデフォルトへ正常に縮退できるよう、すべてのフラグ判定ブロック内に堅牢なフォールバックロジックを記述する。
  2. 属性の命名規則をクリーンかつ一貫して保つ:フロントエンド、バックエンド、モバイルアプリケーション間でカスタム属性キー(userId、accountTier、region など)を標準化し、ソフトウェアスタック全体で統一されたオーディエンス評価を担保する。
  3. 高トラフィックなサーバー同期には Webhook を併用する:大量のリクエストを処理するバックエンドマイクロサービスでは、定期ポーリングに加えて Optimizely Webhook を構成し、Datafile の変更がミリ秒単位でクラスター全体に伝播するようにする。
  4. フラグを「一時的な在庫」として管理する:本番コード内に恒久的なフラグを放置しない。定期的なスプリントで廃棄されたフラグを削除する運用を確立し、条件分岐による技術的負債の蓄積を防ぐ。
  5. 運用メトリクスとビジネスメトリクスを段階に応じて分離する:初期のロールアウト段階(1% 〜 25%)ではインフラの健全性(レイテンシ、CPU、メモリ、エラー率)の監視に集中し、トラフィック規模が拡大した後にビジネスメトリクス(コンバージョン、エンゲージメント、収益)へと注目の軸を移行する。