- 后端
- 前端
【免费下载链接】flagsmith
Flagsmith is an open-source feature flag platform with remote config, experimentation, and self-hosted or cloud deployment options.
本篇指南以 Flagsmith 开源仓库中的 API Usage 文档 为骨架,完整讲解 Flagsmith 如何追踪 SDK 发起的 API 调用、在组织/项目/环境各层级查看用量数据,并深入到
app_analytics应用的中间件、数据模型、聚合任务与查询接口,帮助你理解"谁在什么时候调用了多少次 API",同时为容量规划、成本核算与 Flag 清理提供数据依据。
Flagsmith 会在其数据存储中记录 SDK 发出的每一次 API 调用,并在组织设置页面的Usage标签页中呈现这些数据。本文将先梳理被追踪的四种请求类型与查看入口,再结合仓库源码拆解追踪链路(中间件识别 → 缓存聚合 → 异步入库 → 桶聚合 → 报表查询),最后介绍与 Flag Analytics 的关系及自托管部署时的存储配置。
一、Flagsmith 追踪哪些 API 请求
根据原文档,Flagsmith 只追踪以下四类由 SDK 发起的请求,其余管理类请求(Management API)、Flag Analytics 上报请求等不计入此用量统计:
| 序号 | 被追踪的请求类型 | 对应 API 路径(由源码Resource枚举验证) | 典型发起方 |
|---|---|---|---|
| 1 | Get Flags | /api/v1/flags | 远程评估(Remote Evaluation)模式下获取环境全部 Flag |
| 2 | Get Identity Flags | /api/v1/identities | 远程评估模式下获取某个 Identity 的 Flag |
| 3 | Set Identity Traits | /api/v1/traits | 上报/更新用户属性(Traits) |
| 4 | Get Environment Document | /api/v1/environment-document | 本地评估(Local Evaluation)SDK 定期拉取的环境文档 |
这四类资源在源码中有精确的一一对应定义。在 api/app_analytics/models.py 中,Resource是一个IntegerChoices枚举,并为每个资源提供了resource_name(flags、identities、traits、environment-document)与column_name(用于报表字段命名):
class Resource(models.IntegerChoices): FLAGS = 1 IDENTITIES = 2 TRAITS = 3 ENVIRONMENT_DOCUMENT = 4单元测试 以参数化方式直接验证了这四个路径与资源名的对应关系:/api/v1/flags → flags、/api/v1/traits → traits、/api/v1/identities → identities、/api/v1/environment-document → environment-document。
关于 Environment Document 的补充说明:SDK 文档 指出,本地评估模式下 SDK 初始化时会请求一次包含环境全部配置的 JSON 文档,之后默认每 60 秒刷新一次;因此一个运行中的服务实例每分钟产生一次 Environment Document 请求,这正是本地评估模式下唯一的 API 调用来源。
二、在哪里查看 API 用量
按原文档指引,查看入口如下:
- 登录 Flagsmith 控制台,进入Organisation settings(组织设置)页面;
- 点击Usage标签;
- 可在该页面进一步下钻(drill down)到具体的 Project(项目)与 Environment(环境),查看每个层级的调用量。
上方截图即展示了某个项目在特定环境(Staging)下的统计:界面按Flags、Identities、Traits分别计数,并给出Total API Calls总量,同时以堆叠柱状图展示按日(例如 2023-03-07 至 2023-04-05)的趋势分布。
报表字段的真实含义
用量报表的每条记录由 app_analytics/dataclasses.py 中的UsageData定义,最终通过 UsageDataSerializer 序列化输出:
class UsageDataSerializer(serializers.Serializer): flags = serializers.IntegerField() # Get Flags 次数 identities = serializers.IntegerField() # Get Identity Flags 次数 traits = serializers.IntegerField() # Set Identity Traits 次数 environment_document = serializers.IntegerField() # Environment Document 拉取次数 day = serializers.CharField() # 统计日期 labels = LabelsSerializer(allow_null=True, required=False)可以看到,报表中的四个计数列与上节四种请求类型一一对应——flags、identities、traits和environment_document,分别来源于Resource枚举的column_name属性。
三、底层实现:API 调用是如何被追踪的
原文档只说明了"会追踪",下面结合源码还原完整链路。整个实现位于 api/app_analytics/ 应用内。
3.1 中间件识别请求
核心是APIUsageMiddleware(api/app_analytics/middleware.py):
class APIUsageMiddleware: def __call__(self, request: HttpRequest) -> HttpResponse: if environment_key := request.headers.get("X-Environment-Key"): track_usage_by_resource_host_and_environment( resource=get_resource_from_uri(request.path), host=request.get_host(), environment_key=environment_key, labels=map_request_to_labels(request), ) response = self.get_response(request) return response几个关键细节:
- 以
X-Environment-Key请求头作为判定条件:只有携带该头(即 SDK 请求)的调用才被统计,这也是管理端请求不会被计入的原因; - 资源识别:
get_resource_from_uri()(track.py)解析request.path,要求路径形如/api/v1/<resource>/...,并取第三个分段映射到Resource枚举;不是 API 路径或未知资源则跳过; - 中间件仅在开关打开时挂载:设置项
ENABLE_API_USAGE_TRACKING(默认True)控制是否在 DjangoMIDDLEWARE中追加该中间件,见 api/app/settings/common.py。
此外还有一个可选的GoogleAnalyticsMiddleware(middleware.py),在配置了GOOGLE_ANALYTICS_KEY时挂载,向 Google Analytics 上报 pageview 与资源事件,属于可选的历史实现,不影响 InfluxDB/Postgres 用量统计。
3.2 先缓存聚合,再异步入库
为避免每个请求都触发一次数据库写入,统计采用了"内存缓存 + 定时刷盘"的模式(api/app_analytics/services.py):
def track_usage_by_resource_host_and_environment(resource, host, environment_key, labels): if resource and resource.is_tracked: if settings.USE_CACHE_FOR_USAGE_DATA: api_usage_cache.track_request(...) # 先写入进程内缓存 else: track_request.run_in_thread(...) # 直接异步入库APIUsageCache(api/app_analytics/cache.py)以(resource, host, environment_key, labels)为键累加计数,每隔API_USAGE_CACHE_SECONDS秒(默认 60,见 common.py)将累计值一次性刷新为后台任务track_request。
track_request任务(tasks.py)再根据后端类型写入:
USE_POSTGRES_FOR_ANALYTICS=True时,创建APIUsageRaw记录;- 否则若配置了
INFLUXDB_TOKEN,调用track_request_influxdb()将数据点写入 InfluxDB。
track_request_influxdb(track.py)写入的标签非常丰富,包含resource、organisation/organisation_id、project/project_id、environment/environment_id、host以及可选的客户端标签——这正是用量数据能够按项目、环境、主机下钻的根源。
四、用量数据的存储与聚合
4.1 两种分析后端
原文档没有展开存储细节,但自托管部署时这是核心配置项。分析数据可落在两种后端之一(common.py):
| 环境变量 | 默认值 | 说明 |
|---|---|---|
USE_POSTGRES_FOR_ANALYTICS | False | 为True时使用 PostgreSQL 表存储用量与评估数据,无需额外时序数据库 |
INFLUXDB_TOKEN | "" | 非空时使用 InfluxDB 作为分析后端 |
INFLUXDB_BUCKET | "" | InfluxDB 存储桶名 |
INFLUXDB_URL/INFLUXDB_ORG | "" | InfluxDB 连接地址与组织 |
在 analytics_db_service.py 的get_usage_data()中,二者优先级明确:USE_POSTGRES_FOR_ANALYTICS优先;其次INFLUXDB_TOKEN;两者都未配置时仅记录一条NO_ANALYTICS_DATABASE_CONFIGURED_WARNING警告并返回空数据(警告文案定义于 constants.py)。
4.2 数据模型与生命周期
Postgres 后端依赖四张模型表(models.py):
APIUsageRaw:原始 API 调用记录(environment_id、host、resource、count、labelsJSON 字段);APIUsageBucket:按时间桶聚合后的用量数据;FeatureEvaluationRaw:原始 Flag 评估记录(含identity_identifier、enabled_when_evaluated,用于多变量拆分测试);FeatureEvaluationBucket:聚合后的评估数据。
AbstractBucket提供了"桶不允许重叠"的校验逻辑,APIUsageBucket/FeatureEvaluationBucket在BEFORE_CREATE钩子中检查是否存在同环境、同时段、同标签的已有桶,防止聚合任务重复执行造成数据重复(models.py)。
数据生命周期由两个周期任务管理(tasks.py):
populate_bucket:每 60 分钟运行一次,按ANALYTICS_READ_BUCKET_SIZE(15 分钟,见 constants.py)把原始数据聚合进桶表;clean_up_old_analytics_data:每天运行一次,原始数据保留RAW_ANALYTICS_DATA_RETENTION_DAYS(默认 30 天),桶数据保留BUCKETED_ANALYTICS_DATA_RETENTION_DAYS(默认 90 天)后删除(common.py)。
InfluxDB 后端则利用时序库特性:原始数据写入INFLUXDB_BUCKET,并通过 select_downsampled_bucket 自动选择降采样桶——查询窗口超过 10 天用1h粒度,10 天内用15m粒度,保证查询性能。
五、用量数据查询接口与参数
5.1 管理 API 端点
用量数据不仅能在界面查看,还开放了管理 API(路由见 api/organisations/urls.py,视图见 views.py):
GET /api/v1/organisations/<organisation_pk>/usage-data/:按日返回各资源的调用次数;GET /api/v1/organisations/<organisation_pk>/usage-data/total-count/:返回总量计数。
两个端点均要求已认证用户且通过UsageDataPermission权限校验,并带有InfluxQueryThrottle限流。
5.2 查询参数
UsageDataQuerySerializer(serializers.py)定义了以下过滤参数:
| 参数 | 类型 | 说明 |
|---|---|---|
project_id | int(可选) | 只看指定项目 |
environment_id | int(可选) | 只看指定环境 |
period | 枚举(可选) | current_billing_period/previous_billing_period/90_day_period |
client_application_name、client_application_version、user_agent | str(可选) | 按标签过滤(见下文第六节) |
其中period的时间窗口计算由订阅信息缓存驱动(analytics_db_service.py):账单周期基于OrganisationSubscriptionInformationCache.current_billing_term_starts_at推算;90_day_period则固定为当前时间往前 90 天。未配置订阅周期而请求账单周期时返回404 NotFound(对应测试 test_analytics_db_service.py)。
5.3 报表聚合逻辑
Postgres 后端下,get_usage_data_from_local_db()只读取 15 分钟粒度的桶表,按(日期, 资源, 标签)分组求和(analytics_db_service.py),再由 mappers.py 将多行桶数据折叠成"每天一行、每资源一列"的UsageData。由于同一日期可能存在多种标签组合,map_usage_data_to_daily_totals 还会将所有标签组合累加成每日总量,供整组织视图使用。相关聚合正确性由 test_analytics_db_service.py 的多桶聚合测试覆盖。
六、标签(Labels):区分调用来源的进阶能力
原文档未提及,但从源码可见用量统计支持按来源打标签,这使报表可以按客户端应用名、版本、SDK/User-Agent 过滤,是理解"哪些客户端在消耗 API"的关键能力。
6.1 标签类型与请求头映射
constants.py 定义了可选请求头到标签的映射:
| 请求头 | 标签名 | 说明 |
|---|---|---|
Flagsmith-Application-Name | client_application_name | 客户端应用名 |
Flagsmith-Application-Version | client_application_version | 客户端应用版本 |
Flagsmith-SDK-User-Agent | sdk_user_agent | SDK 标识(浏览器场景替代User-Agent) |
User-Agent | user_agent | 浏览器自带 UA |
最终存储的标签固定为三种(types.py):client_application_name、client_application_version、user_agent。
6.2 标签收集受开关控制
标签并非无条件收集。mappers.py 中的map_request_to_labels()首先通过 OpenFeature 客户端查询名为sdk_metrics_labels的功能开关,只有该开关开启时才解析请求头并产出标签,否则返回空字典。这也解释了 test_middleware.py 中"不带可选头 → 标签为空""带应用名/版本头 → 标签正确解析"的两种断言场景。
6.3 User-Agent 的数值化存储
为压缩时序数据,已知 SDK 的 UA 会被映射为数值 ID:SDK_USER_AGENT_KNOWN_VERSIONS(constants.py)收录了 13 个官方 SDK 及其已知版本号(如flagsmith-python-sdk/5.0.0、flagsmith-nodejs-sdk/9.0.3等),未知版本统一归一化为"unknown";SDK_USER_AGENT_INFLUX_IDS 为每个 SDK 分配起始 ID(Python 系 90000、Node 系 70000 等),写入 Influx 时map_labels_to_influx_record_values()将 UA 转成数字,读取时再反向还原(mappers.py)。仓库还提供了 add-known-sdk-version.py 脚本,用于向该表新增已发布的 SDK 版本。
七、Flag Usage:Flag 级别的评估统计
原文档指出:除了 API 调用量,Flagsmith 还通过 Flag Analytics 追踪Flag 评估次数(Flag Evaluations),两者互为补充——API Usage 回答"调用了多少次接口",Flag Analytics 回答"每个 Flag 被评估了多少次"。
7.1 数据如何产生
- 在 SDK 端,每次调用如
flagsmith.hasFeature("myCoolFeature")都会在本地累计该 Flag 的评估计数;SDK 每隔一段时间(JS SDK 当前为 10 秒)向 Flagsmith API 上报一次,无评估则不上报(见 flag-analytics.md); - Flag Analytics默认关闭,需要在 SDK 初始化时显式开启(各 SDK 文档均有对应初始化选项);
- 上报的数据在界面可见大约需要30 分钟到 1 小时(桶聚合延迟所致)。
7.2 服务端接收与入库
API 端由SDKAnalyticsFlagsV1/SDKAnalyticsFlagsV2视图接收(app_analytics/views.py),路径形如/api/v1/analytics/flags。序列化器(serializers.py)在validate阶段会校验上报的feature_name必须属于该环境的真实 Feature,防止脏数据;随后:
- V1 接口把
{feature_name: count}扁平字典写入FeatureEvaluationCache(同样按 60 秒间隔刷新,cache.py); - V2 接口按
evaluations数组直接投递后台任务,Postgres 后端批量创建FeatureEvaluationRaw,Influx 后端写入feature_evaluation测量(tasks.py)。
评估数据同样经populate_feature_evaluation_bucket聚合成 15 分钟桶,再由get_feature_evaluation_data()(analytics_db_service.py)按 Flag、环境与时间窗查询——这正是 Flag 详情页 Usage 标签页图表的数据来源。
八、与计费的关系与部署提示
- SaaS / Flagsmith 托管环境的计费关系:被追踪的四类请求对应计费文档 Billing and API Usage 中的"可计费请求";Management API 请求、Flag Analytics 上报、实时 Flag 更新(WebSocket)连接均不计费。
- 自托管无请求上限:文档明确说明 Self-hosted 安装没有 API 请求数限制,但若需在自托管环境查看用量报表,必须正确配置
USE_POSTGRES_FOR_ANALYTICS=True或 InfluxDB 相关环境变量,否则分析查询只会返回空结果并输出警告日志。 - 数据保留窗口:原始数据默认仅保留 30 天、聚合数据保留 90 天(两者均可在
RAW_ANALYTICS_DATA_RETENTION_DAYS/BUCKETED_ANALYTICS_DATA_RETENTION_DAYS中调整);用量页面默认展示 90 天窗口。 - 调优选项:
USE_CACHE_FOR_USAGE_DATA(默认True)与API_USAGE_CACHE_SECONDS(默认 60)控制内存聚合粒度,高 QPS 场景可适当调大后者以减少写放大。
九、常见用途与排查建议
综合原文档与源码,API Usage 数据在以下几类场景中价值最大:
- 成本与容量规划:结合 Billing and API Usage 中的估算公式(如客户端
月会话数 × (2 次 Flag 更新 + 3 次 Flag 请求),服务端实例数 × 43200 次/月),用实际报表数据校准容量; - 评估模式选型:对比
environment_document与flags/identities的比例,可判断本地评估是否已真正降低远程调用量; - Flag 清理:Flag Analytics 中评估次数长期为 0 的 Flag 可安全考虑移除(flag-analytics.md);
- 异常排查:结合标签(客户端应用名/版本)下钻,可定位某个客户端版本的异常高频调用,例如代码缺陷导致的重复评估。
相关资源索引
- 本文主题文档:api-usage.md
- Flag 级评估统计:flag-analytics.md
- 计费与用量估算:billing-api-usage.md
- 环境文档与本地评估:SDK 集成文档
- 核心实现:app_analytics 应用(中间件 middleware.py、模型 models.py、聚合任务 tasks.py、查询服务 analytics_db_service.py)
- 分析后端配置:common.py
- 单元测试:test_middleware.py、test_analytics_db_service.py
- 后端
- 前端
【免费下载链接】flagsmith
Flagsmith is an open-source feature flag platform with remote config, experimentation, and self-hosted or cloud deployment options.
相关推荐
FluentRead 模型用量(Model Usage)深度指南:本机 Token 统计、缓存构成与请求追踪
FluentRead 模型用量(Model Usage)深度指南:本机 Token 统计、缓存构成与请求追踪 模型用量是 FluentRead 内置的一项本地可
前端AI 应用本地部署openai-agents-python 用量(Usage)追踪完全指南:从 Token 统计、按请求明细到原始载荷保留
openai agents python 用量(Usage)追踪完全指南:从 Token 统计、按请求明细到原始载荷保留 导读 本文聚焦 openai agen
人工智能AI AgentAgent 框架多智能体工具调用MCP ClientsDevPod追踪系统终极指南:深入理解请求链路追踪机制 🚀
DevPod追踪系统终极指南:深入理解请求链路追踪机制 🚀 DevPod 作为开源开发者环境管理工具,其 请求链路追踪机制 是确保系统稳定性和性能的关键。本文
开发工具CLI桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考