事件表结构
Framedash 将原始遥测存储在 ClickHouse 的 events 表中。你可以从三个入口用 SQL 读取它:
- REST 的
POST /v1/query端点。 framedash queryCLI 命令。- MCP 的
query工具。
本页列出列和校验器规则,让你无需 Claude Code 插件也能编写查询。
访问与 scope
Section titled “访问与 scope”原始 SQL 需要具有 data:admin scope 的 API 密钥(Full 预设)。Read-only 密钥可以使用内置分析端点和 MCP 工具,但不能使用原始 query 路径。Ingest(events:write)密钥按设计既不能查询,也不能枚举自己的项目。
查询会被校验、改写以强制项目隔离,并在只读连接上执行。校验器强制:
- 仅允许
SELECT。不允许INSERT、UPDATE、DELETE、DROP、ALTER、CREATE、TRUNCATE、SYSTEM、OPTIMIZE、KILL,以及UNION/EXCEPT/INTERSECT。 FROM/JOIN中只能出现两个表:events(原始事件)和daily_sessions_project_mv(预聚合的每日会话)。直接写FROM events,隔离过滤会自动注入。- 不要在 SQL 中引用
tenant_id或project_id。它们会被自动限定,直接引用会被拒绝。 - 字符串字面量只能用单引号。双引号和反引号会被拒绝。
- 不允许
SETTINGS、FORMAT或GLOBAL子句。允许IN (SELECT ...)和IN ('a','b');不允许IN some_table。 - 若省略顶层
LIMIT,会自动追加一个。
结果为 { "rows": [ { "col": "value" } ], "rowCount": 123 } 的形状。CLI 和 MCP 工具会直接返回这个形状。直接调用 REST 端点时,会包在标准 API 信封中:{ "success": true, "data": { "rows": [...], "rowCount": 123 } }。MCP 的 query 工具上限为 1000 行;REST 端点和 CLI 上限为 10000 行。若需更大提取,请用 LIMIT ... OFFSET ... 分页,或收窄 timestamp 范围。
| 列 | 类型 | 说明 |
|---|---|---|
event_name | String | 事件名,例如 player_death、level_start、perf_heartbeat |
timestamp | DateTime64(6) | 事件时间(UTC) |
session_id | String | 游玩会话 id |
player_id | String | 稳定的玩家/设备 id |
position_x, position_y, position_z | Float32 | 世界坐标 |
map_id | String | 地图/关卡标识 |
fps | Float32 | 帧率(perf 事件) |
frame_time_ms | Float32 | 帧时间 ms(perf 事件) |
memory_used_bytes | Int64 | 内存字节数(perf 事件) |
gpu_time_ms | Float32 | GPU 时间 ms(perf 事件) |
game_thread_ms | Float32 | 游戏线程时间 ms |
render_thread_ms | Float32 | 渲染线程时间 ms |
camera_yaw, camera_pitch | Nullable(Float32) | 相机朝向 |
source | String | SDK 自身的内部事件(session_start、perf_heartbeat)为 automated;您的 Track(...) 调用为 player。不代表 CI 运行(见下方约定) |
build_id | String | 构建标识(perf-diff 候选) |
platform | String | 例如 windows、android |
engine_version | String | 引擎/构建版本字符串 |
attributes | Map(String, String) | 自定义字符串属性 |
metrics | Map(String, Float64) | 自定义数值指标 |
Map 类型的列用方括号访问:attributes['ci.branch']、metrics['score']。
没有 server_timestamp 列。事件时间请用 timestamp。选择未知列会返回查询错误,因此请先核对上面的列名。被拒绝的查询会返回 HTTP 400 及 ClickHouse 诊断信息(未知的列、表或函数,语法错误,类型不匹配,禁止的操作);仅基础设施故障返回 500。
- 自动的性能事件是
perf_heartbeat。perf 查询请用WHERE event_name = 'perf_heartbeat'过滤;并非所有事件都带有fps/frame_time_ms。 source = 'automated'标记 SDK 自身的内部事件(session_start、perf_heartbeat),用于与您的Track(...)调用区分,不论是否为 CI,每个会话都会设置它,因此不能单独用它识别 CI 运行。- 要筛选 CI 性能分析数据,请使用
build_id或attributes['ci.*']标签(由BeginAutomatedSession/BeginAutomatedSessionFromEnvironment设置),而不是source。 - CI 元数据放在
attributes中:attributes['ci.branch']、attributes['ci.commit']、attributes['ci.scenario'],以及一等列build_id。 - 事件名是你在
Track(...)中自选的自由字符串。官方 SDK 示例使用snake_case(player_death、level_start);请在整个项目中保持一种约定。 - 始终限定
timestamp,让查询裁剪分区(该表按天分区)以保持快速。
今日活跃玩家数:
SELECT uniqExact(player_id) AS dauFROM eventsWHERE timestamp >= today()最近 7 天按事件名的事件量:
SELECT event_name, count() AS events, uniqExact(session_id) AS sessionsFROM eventsWHERE timestamp >= today() - 7GROUP BY event_nameORDER BY events DESC按构建的性能百分位:
SELECT build_id, count() AS samples, round(quantile(0.50)(fps), 1) AS fps_p50, round(quantile(0.95)(frame_time_ms), 2) AS frametime_p95_msFROM eventsWHERE event_name = 'perf_heartbeat' AND timestamp >= today() - 14GROUP BY build_idORDER BY samples DESC