Appearance
ClickHouse 是高性能开源列式数据库,适合实时分析场景。通过 OpenRouter Broadcast,可以将 LLM 请求 trace 直接流式写入 ClickHouse 的 OPENROUTER_TRACES 表,支持自定义仪表盘和 BI 工具对接。Schema 中高频查询字段(token 计数、费用、时间戳、模型信息、用户 ID)以强类型列存储;INPUT/OUTPUT/METADATA 等可变结构以 JSON 字符串存储,通过 JSONExtract 函数查询。
ClickHouse 是高性能开源列式数据库,专为实时分析设计。OpenRouter 可以将 trace 直接流写入你的 ClickHouse 数据库,支持高性能分析和自定义仪表盘。
配置步骤
第一步:创建 traces 表
在连接 OpenRouter 前,先在 ClickHouse 数据库中创建 OPENROUTER_TRACES 表。具体建表 SQL 可在 OpenRouter 控制台配置页面中找到。
第二步:设置权限
确保 ClickHouse 用户拥有 CREATE TABLE 权限:
sql
GRANT CREATE TABLE ON your_database.* TO your_database_user;第三步:在 OpenRouter 开启 Broadcast
前往 Settings > Observability,打开 Enable Broadcast 开关。
第四步:配置 ClickHouse
点击 ClickHouse 旁边的编辑图标,填写:
| 字段 | 填写内容 |
|---|---|
| Host | ClickHouse HTTP 端点(如 https://clickhouse.example.com:8123) |
| Database | 目标数据库名(默认 default) |
| Table | 表名(默认 OPENROUTER_TRACES) |
| Username | ClickHouse 认证用户名(默认 default) |
| Password | ClickHouse 认证密码 |
ClickHouse Cloud 的 Host URL 通常为 https://{instance}.{region}.clickhouse.cloud:8443,在 ClickHouse Cloud 控制台的 Connect 下可以找到。
第五步:测试并保存
点击 Test Connection 验证配置,测试通过后自动保存。
第六步:发送测试 Trace
通过 OpenRouter 发送一个 API 请求,查询 ClickHouse 表验证数据已写入。
常用查询示例
按模型统计成本
sql
SELECT
toDate(TIMESTAMP) as day,
MODEL,
sum(TOTAL_COST) as total_cost,
sum(TOTAL_TOKENS) as total_tokens,
count() as request_count
FROM OPENROUTER_TRACES
WHERE TIMESTAMP >= now() - INTERVAL 30 DAY
AND STATUS = 'ok'
AND SPAN_TYPE = 'GENERATION'
GROUP BY day, MODEL
ORDER BY day DESC, total_cost DESC;用户活跃度分析
sql
SELECT
USER_ID,
uniqExact(TRACE_ID) as trace_count,
uniqExact(SESSION_ID) as session_count,
sum(TOTAL_TOKENS) as total_tokens,
sum(TOTAL_COST) as total_cost,
avg(DURATION_MS) as avg_duration_ms
FROM OPENROUTER_TRACES
WHERE TIMESTAMP >= now() - INTERVAL 7 DAY
AND SPAN_TYPE = 'GENERATION'
GROUP BY USER_ID
ORDER BY total_cost DESC;错误分析
sql
SELECT
TRACE_ID, TIMESTAMP, MODEL, LEVEL, FINISH_REASON, METADATA, INPUT, OUTPUT
FROM OPENROUTER_TRACES
WHERE STATUS = 'error'
AND TIMESTAMP >= now() - INTERVAL 1 HOUR
ORDER BY TIMESTAMP DESC;Provider 性能对比
sql
SELECT
PROVIDER_NAME, MODEL,
avg(DURATION_MS) as avg_duration_ms,
quantile(0.5)(DURATION_MS) as p50_duration_ms,
quantile(0.95)(DURATION_MS) as p95_duration_ms,
count() as request_count
FROM OPENROUTER_TRACES
WHERE TIMESTAMP >= now() - INTERVAL 7 DAY
AND STATUS = 'ok'
AND SPAN_TYPE = 'GENERATION'
GROUP BY PROVIDER_NAME, MODEL
HAVING request_count >= 10
ORDER BY avg_duration_ms;查询 JSON 列中的自定义元数据
sql
SELECT
TRACE_ID,
JSONExtractString(METADATA, 'team') as team,
JSONExtractString(METADATA, 'pipeline_version') as pipeline_version,
TOTAL_COST, TOTAL_TOKENS
FROM OPENROUTER_TRACES
WHERE JSONHas(METADATA, 'team')
AND SPAN_TYPE = 'GENERATION'
ORDER BY TIMESTAMP DESC;表结构设计
强类型列
常用字段以强类型列存储,支持高效过滤和聚合:
- 标识符:TRACE_ID、USER_ID、SESSION_ID 等
- 时间戳:DateTime64,毫秒精度时序分析
- 模型信息:成本和性能分析
- 指标:token 计数和费用
JSON 字符串列
访问频率较低或结构可变的数据以 JSON 字符串存储:
- ATTRIBUTES:完整 OTEL 属性集
- INPUT/OUTPUT:可变消息结构
- METADATA:用户自定义键值
- MODEL_PARAMETERS:模型专属配置
使用 ClickHouse 的 JSONExtract* 函数查询这些字段。
元数据键映射
| 键 | ClickHouse 映射 | 说明 |
|---|---|---|
trace_id | TRACE_ID 列 / METADATA JSON | 自定义 trace 标识符 |
trace_name | METADATA JSON | trace 自定义名称 |
span_name | METADATA JSON | 中间 span 名称 |
generation_name | METADATA JSON | LLM 生成的名称 |
字段映射说明:
user字段映射到USER_ID强类型列session_id字段映射到SESSION_ID强类型列trace中的自定义键存储在METADATAJSON 字符串列
Privacy Mode
当为此目的地开启 Privacy Mode 时,prompt 和 completion 内容会从 trace 中排除。其他 trace 数据(token 用量、费用、时间、模型信息、自定义元数据)仍正常发送。
常见问题
Q: ClickHouse Cloud 和自托管 ClickHouse 的配置有区别吗?
A: 主要区别在 Host URL 和端口。ClickHouse Cloud 使用 HTTPS 端口 8443;自托管通常是 HTTP 端口 8123 或自定义端口。两者的认证方式(用户名/密码)相同。
Q: 如何对 METADATA 中的自定义字段建立索引以加速查询?
A: 可以使用 ClickHouse 的物化列(materialized column)功能:ALTER TABLE OPENROUTER_TRACES ADD COLUMN team String MATERIALIZED JSONExtractString(METADATA, 'team'),然后对该列创建索引。适合有高频过滤需求的自定义字段。
Q: Test Connection 失败提示 "Table not found",如何解决?
A: 表必须在连接前手动创建。从 OpenRouter 控制台的配置页面复制建表 SQL,在 ClickHouse 中执行后再重试 Test Connection。确保连接字符串中的数据库名和表名与建表时一致。