コンテンツにスキップ

使用ベースの請求

多くのCloudflareの顧客は、複数の顧客を持つソフトウェア・アズ・ア・サービス(SaaS)製品を運営しています。このような企業にとって大きな懸念は、各顧客のコストを理解し、より広範な顧客の行動を理解することです。

顧客が使用するすべてのウェブリクエストのデータを保持することは高コストになる可能性があり、ページビューを顧客に帰属させることも同様です。Cloudflareでは、この問題をAnalytics Engineを通じて利用可能な同じ社内技術で解決しました。

使用データの記録

Analytics EngineはCloudflare Workersと共に使用するように設計されています。すでにCloudflare Workersを使用してリクエストを処理している場合は、わずか数行のコードでAnalytics Engineにデータを送信し始めることができます:

[...]
// この例では、各SaaS顧客にユニークなIDを付与し、Workerがそれを
// `customer_id`という変数に割り当てていると仮定しています
const { pathname } = new URL(request.url);
env.USAGE_INDEXED_BY_CUSTOMER_ID.writeDataPoint({
"indexes": [customer_id],
"blobs": [pathname]
});

SaaS顧客の活動はしばしば指数関数的なパターンに従います:ある顧客は1秒あたり1億リクエストを行う一方で、別の顧客は1日あたり100リクエストを行うかもしれません。すべてのデータを一緒にサンプリングすると、大きな顧客の使用が小さな顧客のデータをゼロにサンプリングする原因となる可能性があります。Analytics Engineを使用すると、これを防ぐことができます:上記の例のコードでは、顧客のユニークIDをインデックスとして提供し、Analytics Engineが顧客の個別の活動をサンプリングするようにします。

使用状況の表示

顧客データは、Grafana(視覚化用)またはJSON(独自のツール用)を使用して表示を開始できます。Analytics Engineのドキュメントの他の部分では、これを詳細に説明しています。

すべてのエンドポイントにわたる顧客の使用状況を確認します:

SELECT
index1 AS customer_id,
sum(_sample_interval) AS count
FROM
usage_indexed_by_customer_id
GROUP BY customer_id

Grafanaで実行すると、このクエリは各顧客の使用状況を要約したグラフを返します。sum(_sample_interval)はサンプリングを考慮しています - 他のAnalytics Engineのドキュメントを参照してください。このクエリは「どの顧客が最も活発か?」という質問に対する答えを提供します。

上記の例のwriteDataPoint呼び出しはエンドポイント名を書き込みます。これを行うと、顧客の活動をエンドポイントごとに分解できます:

SELECT
index1 AS customer_id,
blob1 AS request_endpoint,
sum(_sample_interval) AS count
FROM
usage_indexed_by_customer_id
GROUP BY customer_id, request_endpoint

これにより、異なる顧客が使用しているエンドポイントに関する洞察を得ることができます。これはビジネス目的(たとえば、顧客のニーズを理解するため)や、エンジニアが活動や行動を確認するため(可観測性)に役立ちます。

顧客の請求

Analytics Engineは、使用状況の信頼できる近似に基づいて顧客に請求するために使用できます。最良の近似を得るために、請求を生成する際には、顧客ごとに1つのクエリを実行することをお勧めします。これにより、複数の顧客を一度にクエリするよりもサンプリングが少なくなる可能性があります。

SELECT
index1 AS customer_id,
blob1 AS request_endpoint,
sum(_sample_interval) AS usage_count
FROM
usage_indexed_by_customer_id
WHERE
customer_id = 'substitute_customer_id_here'
AND timestamp >= toDateTime('2023-03-01 00:00:00')
AND timestamp < toDateTime('2023-04-01 00:00:00')
GROUP BY customer_id, request_endpoint

各月の終わりにこのクエリを各顧客に対して一度実行することで、請求書を作成するためのデータを得ることができます。これは単なる例です:おそらく、請求の方法に合わせてこの例を調整したいでしょう。

請求書を作成する際には、日々のコストも提供したいと思うでしょう。以下のクエリは、日ごとの使用状況を分解します:

SELECT
index1 AS customer_id,
toStartOfInterval(timestamp, INTERVAL '1' DAY) AS date,
blob1 AS request_endpoint,
sum(_sample_interval) AS request_count
FROM
usage_indexed_by_customer_id
WHERE
customer_id = 'x'
AND timestamp >= toDateTime('2023-03-01 00:00:00')
AND timestamp < toDateTime('2023-04-01 00:00:00')
GROUP BY customer_id, date, request_endpoint

上記の使用状況クエリを取り入れ、顧客に請求する方法に合わせて調整し、バックエンドシステムを実行してこれらのクエリを実行し、返されたデータに基づいて顧客の料金を計算する必要があります。