直接 HTTP 采集 (protobuf)
要在不使用官方 SDK 的情况下发送遥测数据,请将 protobuf 编码的 TelemetryBatch 直接 POST 到采集端点。
大多数集成应改用官方的 Unity、UE5 或 Godot SDK。
本页面面向没有 SDK 的引擎,或拥有自建发送管线的团队,提供底层的接入方式。
| 项目 | 值 |
|---|---|
| 方法与 URL | POST https://ingest.framedash.dev/v1/events |
Content-Type | application/x-protobuf |
X-API-Key | 拥有 events:write 作用域的 Ingest 密钥 |
X-SDK-Version | SDK 版本标识符(例如 custom-1.0.0) |
Content-Length 必须与实际请求体大小一致。
若对请求体进行 gzip 压缩,请添加 Content-Encoding: gzip。
请将请求体(若使用 gzip,则为压缩后)保持在 126,000 字节以内。
超出则以 413 拒绝。
非 application/x-protobuf 的 Content-Type,或非 gzip 的 Content-Encoding,会返回 415。
缺少 Content-Length 会返回 411。
端点在接受批次进行异步处理后返回 202 及 { "status": "accepted" }。
这并不确认每个事件都通过了下游校验或已持久化存储;可解码的批次仍可能包含之后会被丢弃的无效事件。
采集到的事件需要约 20~30 秒才会出现在 builds、查询和仪表盘中。
短暂延迟并不意味着采集失败。
对自定义发送器进行端到端检查时,请给一个事件设置如 ingest_probe_<unique-id> 的唯一标记,并在每次运行时将 <unique-id> 替换为 UUID 等值。等待后再用拥有 data:admin 作用域的 Full 密钥精确查询该标记。Read-only 密钥的 analytics:read 作用域可以访问聚合分析 API,但不能执行这里使用的 raw SQL framedash query:
framedash query --api-key-file full.key --project-id <project-id> \ "SELECT count(), max(timestamp) FROM events WHERE event_name = 'ingest_probe_<unique-id>'"只有计数大于零且最大时间戳来自本次运行,才能确认持久化存储。每次测试都应使用新标记,以免旧的测试事件造成误判。
proto3 架构
Section titled “proto3 架构”请求体是编码后的 framedash.v1.TelemetryBatch 消息(proto3)的字节串。
api_key 与 sdk_version 通过 HTTP 头(X-API-Key、X-SDK-Version)传输,而不放在载荷中。
完整的架构定义如下。
syntax = "proto3";
package framedash.v1;
// 3D position vector for spatial analytics (heatmaps, player tracking).message Vector3 { float x = 1; float y = 2; float z = 3;}
// Source of the telemetry event.enum TelemetrySource { TELEMETRY_SOURCE_UNSPECIFIED = 0; TELEMETRY_SOURCE_PLAYER = 1; TELEMETRY_SOURCE_AUTOMATED = 2;}
// Core telemetry event emitted by game SDKs.// Each event maps to a single row in the ClickHouse `framedash.events` table.message GameTelemetryEvent { string event_name = 1; // Unix epoch in microseconds. Stored as DateTime64(6) in ClickHouse. int64 timestamp_us = 2; string session_id = 3; // Explicit player identifier — the only PII the SDK may collect. string player_id = 4; Vector3 position = 5; string map_id = 6; reserved 7; reserved "zone_id"; float fps = 8; float frame_time_ms = 9; int64 memory_used_bytes = 10; float gpu_time_ms = 11; // Free-form string key-value pairs for game-specific context. map<string, string> attributes = 12; // Free-form numeric metrics for game-specific measurements. map<string, double> metrics = 13; // Source of the telemetry event. TelemetrySource source = 14; string build_id = 15; string platform = 16; string engine_version = 17; // Camera orientation in degrees. // camera_yaw: horizontal rotation (0 = North, clockwise, [0, 360)). // camera_pitch: vertical rotation (-90 = straight down, +90 = straight up). // 'optional' enables has-field presence tracking — distinguishes // "not sent by SDK" (absent) from "facing North at level" (0, 0). optional float camera_yaw = 18; optional float camera_pitch = 19; // CPU game thread time in milliseconds (logic, AI, physics). // 0 = not collected (old SDK or unavailable). float game_thread_ms = 20; // CPU render thread time in milliseconds (draw commands, culling). // 0 = not collected (old SDK or unavailable). float render_thread_ms = 21;}
// Batch wrapper sent by SDKs via POST /v1/events.// api_key and sdk_version are transmitted in HTTP headers (X-API-Key, X-SDK-Version),// not in the Protobuf payload.message TelemetryBatch { repeated GameTelemetryEvent events = 1;}用 protoc(或 buf)编译 .proto,用生成的代码构建 TelemetryBatch 并序列化为字节。
将序列化后的字节写入文件,再用 curl --data-binary POST。
# 1. 编译 proto(以 Python 为例)protoc --python_out=. telemetry.proto
# 2. 在应用代码中构建 TelemetryBatch 并写入 batch.bin
# 3. 发送 POSTcurl -X POST https://ingest.framedash.dev/v1/events \ -H "X-API-Key: fd_your_ingest_key_here" \ -H "X-SDK-Version: custom-1.0.0" \ -H "Content-Type: application/x-protobuf" \ --data-binary @batch.bin每个事件都必须满足数据模型的摄取验证限制。
timestamp_us 必须在最近 30 天内,且不超过未来 48 小时;event_name 与 session_id 不能为空;字符串和 map 字段必须在上限之内;数值指标必须为有限值。
官方 SDK 会在发送前对这些值进行钳制。