highlight.io SQL 编辑器完全指南:用自定义 ClickHouse SELECT 查询聚合日志、会话与追踪数据

发布时间:2026/9/25 3:13:46
highlight.io SQL 编辑器完全指南:用自定义 ClickHouse SELECT 查询聚合日志、会话与追踪数据 可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载SQL 编辑器是 highlight.io 仪表板Dashboard中提供的高级查询入口它允许你直接编写自定义SELECT查询来检索日志logs、会话sessions、追踪traces、错误errors等可观测数据并在后端自动转换为针对 ClickHouse 的查询后执行。本文以 官方 SQL Editor 文档 为骨架结合仓库中backend/clickhouse/query.go的查询转换实现与前端编辑器源码完整讲解宏、日期范围过滤、自定义字段、多序列、列别名等全部能力以及当前版本的限制与安全边界。一、SQL 编辑器是什么查询构建器之外的高级选项在 highlight.io 的仪表板中绝大多数图表都可以通过可视化查询构建器query builder配置。但当你需要对数据做更复杂的转换——例如跨字段聚合、多层分组、百分比统计、Top N 排序——可视化配置就显得力不从心。SQL 编辑器正是为此设计的替代方案直接编写自定义SELECT查询自由组合聚合函数、GROUP BY、ORDER BY、LIMIT等子句查询结果仍然渲染为查询构建器支持的同一套图表与表格无需额外适配查询使用 ClickHouse SQL 方言highlight.io 的所有遥测元数据都存储在 ClickHouse 中。从仓库源码看这个能力背后是 backend/clickhouse/query.go 中的transformSql函数前端编辑器提交原始 SQL 后后端会先解析、校验、改写再交给readMetricsSql执行并分桶聚合最终以MetricsBuckets的形式返回给图表组件渲染。前端编辑器基于 CodeMirror 实现位于 frontend/src/pages/Graphing/components/SqlEditor.tsx支持SQL 语法高亮与基础补全select、from、where、group by、order by、having、limit、offset等关键字表名补全可查询的六张资源表sessions、logs、traces、events、errors、metrics函数模板补全$time_interval(...)、sum、avg、min、max、count()、quantile(...)实时拉取当前项目在所选时间范围内的字段名通过GetKeysGraphQL 查询进行列名补全以及以$开头的仪表板变量补全后端返回的报错会以内联诊断linter形式标注在出错位置按Cmd/Ctrl Enter即可立即执行当前查询。二、编写第一条查询资源表与 ClickHouse 方言SQL 编辑器的底层是 ClickHouse因此支持 ClickHouse SQL 方言包括其丰富的日期时间函数、聚合函数与高阶语法。一个最基本的查询是统计某服务在选定时间范围内的日志条数SELECT count() FROM logs WHERE service_name prod这里需要注意几点FROM只能引用资源表。在 backend/clickhouse/query.go#L524-L531 中定义了可查询的六张资源表var resourceTables map[string]bool{ sessions: true, errors: true, logs: true, traces: true, events: true, metrics: true, }表名会被后端自动改写为真实的 ClickHouse 表名。transformSql中的tableReplacementVisitor会把TableIdentifier替换为对应model.TableConfig.TableName例如日志表映射为logs对应的存储表。查询会被自动注入项目ProjectId过滤条件。transformSql会要求查询只针对单一项目SQL queries must use 1 project id并把ProjectId对sessions、errors表为ProjectID等值条件拼入查询。禁止SETTINGS子句。解析阶段有一个settingsVisitor会检查语句中是否包含SettingsClause一旦发现直接报错SQL statement cannot include a settings clause防止用户篡改服务端设置的 ClickHouse 运行参数此外readMetricsSql还会检查查询字符串中不得出现内部使用的SQL_highlight_project_id设置项backend/clickhouse/query.go#L1530-L1550。查询在只读连接上执行。readMetricsSql使用client.connReadonly.Query执行改写后的 SQL确保编辑器不会对存储产生写操作。三、$time_interval宏让时间序列聚合更简单时间序列图表是最常见的监控需求但手写 ClickHouse 的时间分桶表达式既冗长又容易出错。为此 highlight.io 内置了一个宏$time_interval(duration)在后端该宏会被展开为toStartOfInterval(Timestamp, duration)。例如按小时统计prod服务在选定时间范围内的日志条数SELECT $time_interval(1 hour), count() FROM logs WHERE service_nameprod GROUP BY 1宏的实际展开逻辑可以在 backend/clickhouse/query.go#L317-L361 中看到functionReplacementVisitor遇到名为$time_interval的函数时会把函数名改写为toStartOfInterval校验参数必须恰好是 1 个且必须是字符串字面量否则分别报错$time_interval called with empty argument list、Expecting 1 argument for $time_interval或Expecting $time_interval argument to be a string literal.将参数列表替换为Timestamp与该时长字面量等价于toStartOfInterval(Timestamp, 1 hour)。也就是说$time_interval(1 hour)会按自然小时边界而非相对于查询起始时间对时间戳取整分桶返回每个桶的起始时间非常适合与GROUP BY 1搭配生成等距时间序列。时长为 ClickHouse 标准的 interval 字面量写法如1 hour、5 minutes、1 day具体取值参考 ClickHouse 的toStartOfInterval日期时间函数文档。前端常量定义在 frontend/src/pages/Graphing/components/Graph.tsx#L120export const TIME_INTERVAL_MACRO $time_interval export const TIMESTAMP_KEY Timestamp四、日期范围过滤仪表板时间范围自动生效仪表板顶部选择的时间范围会自动应用到所有 SQL 查询无需也不应在 SQL 里手动写时间条件。例如假设图表的配置如下SELECT count() FROM logs而仪表板的时间范围是Last 4 hours那么最终结果只会统计最近 4 小时内的日志。如果你在查询里写了WHERE子句它是在日期范围过滤之外附加生效的——即使WHERE引用了更早时间的数据超出 4 小时范围的结果也不会被包含。底层的实现逻辑在 backend/clickhouse/query.go#L434-L505transformSql会构造一个基于input.Params.DateRange起止时间的Timestamp toDateTime(start) AND Timestamp toDateTime(end)条件如果查询没有WHERE子句直接把日期范围条件连同ProjectId条件作为WHERE注入如果已有WHERE子句后端会先遍历该子句判断是否已经显式引用了TimestamptimestampVisitor只有当用户没有自行引用Timestamp时才把日期范围条件以AND方式并入最终与原WHERE组合成(原WHERE条件) AND (ProjectId条件) AND (日期范围条件)。因此当仪表板时间范围变化时图表会自动重新查询并动态更新你无需修改 SQL 内容。这也意味着不要在 SQL 里写死时间范围否则会与仪表板时间范围产生语义冲突。五、多序列同时绘制多条指标曲线要在一张图里展示多条序列只需在SELECT中放入多个聚合表达式。例如统计所有 trace 的每小时条数与平均耗时SELECT $time_interval(1 hour), count(), avg(duration) FROM traces GROUP BY 1第一个表达式$time_interval(1 hour)作为分桶键对应图表 X 轴的时间桶count()与avg(duration)是两个独立的聚合序列会各自渲染为一条曲线。同理也可以结合分组键产出更细的序列例如同时按小时与按服务版本分组SELECT $time_interval(1 hour), service_version, count() FROM logs GROUP BY 1, 2后端readMetricsSql会把查询结果按列类型扫描为MetricsBuckets时间桶取整后作为BucketID其余分组列作为Group聚合值作为MetricValuebackend/clickhouse/query.go#L1547-L1665。需要注意分桶数量上限后端常量MaxBuckets 240backend/clickhouse/query.go#L37前端 Graph.tsx#L122 也有同值MAX_BUCKETS当时间桶数超过上限时会被压缩因此尽量选择与时间范围匹配的 interval 粒度。六、查询自定义字段注意类型转换highlight.io 的日志、trace、session、error 都可以通过 SDK 记录自定义字段custom fields与元数据metadata。在 SQL 编辑器里这些字段可以直接按名称出现在查询中。但关键点在于这些自定义数据在后端是以无类型元数据的形式存储的ClickHouse 中的 Map/键值结构没有记录类型信息。因此做字符串类操作如比较、去重、分组通常可以直接使用做数值聚合时必须先显式转换为合适的类型。例如应用为每次会话记录了自定义整数字段cart_size用户购物车中的商品数量要计算每个邮箱对应的平均购物车大小就必须用toInt64()显式转换SELECT email, avg(toInt64(cart_size)) FROM sessions GROUP BY 1 ORDER BY 2 DESC LIMIT 100这条查询同时展示了几个常用技巧email是 session 的保留字段映射到真实列cart_size是自定义字段需要类型转换按平均值的序号2降序排列并限制返回前 100 行。底层的列替换逻辑在 backend/clickhouse/query.go#L295-L315columnReplacementVisitor对每个标识符做两件事先在当前表配置的KeysToColumns映射中查找如email、service_name、duration这类保留字段会直接替换为真实列名如果没找到则把该字段改写为对属性 Map 列的键访问表达式例如LogAttributes[cart_size]或Fields[cart_size]——具体访问哪一列由 backend/model/model.go#L2515-L2521 的GetAttributesColumn依据AttributesColumns前缀映射决定。以日志为例backend/clickhouse/logs.go#L56-L78 中的LogsTableConfig将AttributesColumns指向LogAttributes列session 表的SessionsTableConfig则将属性列指向Fieldsbackend/clickhouse/sessions.go#L454-L461。由于自定义字段没有类型元数据ClickHouse 的avg()无法直接作用于字符串类型的 Map 值这就是文档强调数值聚合前必须先toInt64/toFloat64等转换的原因。补充一个值得了解的实现细节当查询命中采样表sample后缀表采样规模定义在 backend/clickhouse/logs.go#L88-L92sampleSizeRows: 20_000_000时transformSql还会对count/sum类聚合自动乘以采样因子改写为any(_sample_factor) * count()形式backend/clickhouse/query.go#L353-L359从而在采样数据上给出近似正确的总量估算。七、列别名自定义图表标签如果希望图表和图例显示更友好的标签可以给查询表达式起别名。例如统计唯一用户数并命名为User CountSELECT uniqExact(email) as User Count FROM sessionsuniqExact(email)是 ClickHouse 的精确去重计数函数as User Count定义了带空格的别名渲染图表时该序列会以User Count作为标签显示而不是显示完整的聚合表达式。别名同样适用于时间分桶列与分组列例如把分桶列命名为Time让 X 轴更清晰SELECT $time_interval(1 hour) as Time, count() as Requests FROM logs GROUP BY 1注意别名如果包含空格或特殊字符需要像示例一样使用双引号包裹。八、当前限制与安全边界根据官方文档当前版本 SQL 编辑器有以下限制目前 SQL 编辑器仅支持单个SELECT查询——这一限制将在近期放开以支持嵌套SELECT、UNION查询以及公共表表达式CTE。在源码层面这一限制由两处强制保证backend/clickhouse/query.go#L205-L207解析语句后检查len(statements) ! 1否则报错Expected 1 SQL statement, found Nbackend/clickhouse/query.go#L533-L562 的GetTables同样只接受单条语句。此外结合 backend/clickhouse/query.go 与 backend/clickhouse/query.go#L231-L263 的校验逻辑还有几条隐含边界不允许SETTINGS子句资源表之间不能进行JOINResource tables cannot be used in JOIN expression查询必须限定在单一项目内查询通过只读连接执行且无法篡改内部项目标识设置。结语highlight.io 的 SQL 编辑器把 ClickHouse 的完整表达能力开放给了仪表板图表配合$time_interval宏可以快速产出时间序列日期范围自动注入让查询天然跟随仪表板时间多序列与列别名让一张图承载多个指标自定义字段则把 SDK 上报的元数据变成了可聚合的数值。理解后端transformSql的改写规则表名替换、字段映射、日期范围注入、采样因子补偿有助于写出既高效又符合预期的查询并在遇到报错时快速定位原因。如需继续深入可阅读以下仓库文件官方文档docs-content/general/6_product-features/6_dashboards/7_sql-editor.md后端查询转换与执行backend/clickhouse/query.go表配置与字段映射定义backend/model/model.go日志表配置示例backend/clickhouse/logs.go会话表配置示例backend/clickhouse/sessions.go前端编辑器实现frontend/src/pages/Graphing/components/SqlEditor.tsx前端宏常量定义frontend/src/pages/Graphing/components/Graph.tsx赞分享可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载相关推荐Windows热键冲突终极解决方案3分钟快速定位占用快捷键的程序Windows热键冲突终极解决方案3分钟快速定位占用快捷键的程序 你是否曾经按下CtrlS想保存重要文档却发现毫无反应或者尝试使用AltTab切换窗口可观测性后端Instatic与CSS框架Tailwind、Bootstrap集成教程Instatic与CSS框架Tailwind、Bootstrap集成教程 Instatic是一款现代化的自托管可视化CMS能够在1分钟内快速启动并运行。本教CMS后端前端ToolJet 数据库查询完全指南GUI 模式、SQL 编辑器、联表与 JSON 查询ToolJet 数据库查询完全指南GUI 模式、SQL 编辑器、联表与 JSON 查询 ToolJet 内置的 ToolJet DatabaseTJDB是低代码后端前端AI 应用MCP 服务上一篇Python-pinyin在Web开发中的应用构建智能拼音搜索系统下一篇Apache Doris CPU占用过高5个性能瓶颈分析工具实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询