☰
highlight.io 用户分析实战:基于事件数据源与 CountDistinct 构建独立用户点击统计图
2026/9/25 3:51:38 网站建设 项目流程
  • 可观测性
  • 后端

【免费下载链接】highlight

highlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.

项目地址:https://gitcode.com/gh_mirrors/hi/highlight
点击查看免费下载

这篇指南以 highlight.io 的 Dashboards(仪表盘)产品为核心,讲解如何利用事件(events)数据源与CountDistinct 聚合函数,从零搭建一张统计"点击了页头链接(header links)的独立用户数"的柱状图。你将掌握事件源选型、过滤器编写、函数与分组配置、以及从"独立用户(unique users)"切换为"独立会话(unique sessions)"的完整方法,并理解 CountDistinct 在底层 ClickHouse 查询中是如何被生成与执行的。

教程目标与核心概念

用户分析(User Analytics)的核心问题通常是:"有多少不同的用户在使用我的应用的某个功能?"。本教程的目标是追踪点击了页头(header)中链接的独立用户数,借此理解用户与应用的交互行为与趋势。

实现这一目标依赖 highlight.io 的三层能力:

  1. 事件数据源:会话中产生的点击(Click)、导航(Navigate)以及自定义事件,都可以作为指标查询的数据来源;
  2. 用户标识:通过H.identify()上报的identifier属性,用于区分"不同用户";
  3. CountDistinct 聚合:对标识字段去重计数,从而得到独立用户数而非事件总数。

在动手前,建议先阅读 Dashboards 总览 与 图表编辑(Graphing)文档 了解编辑器全貌。

准备工作:确保事件与用户标识被正确上报

在仪表盘中做用户分析之前,需要确认应用侧已经正确上报了事件与用户标识,否则图表将无数据可查。

上报用户标识

调用H.identify()为会话绑定用户级标识(如邮箱、ID),该调用会自动为会话建立索引,使其可以被这些属性过滤:

H.identify('eliza@corp.com', { id: 'ajdf837dj', phone: '867-5309' })

其中第一个参数即identifier属性(如eliza@corp.com),是本教程 CountDistinct 去重的依据。还可以通过 metadata 中的highlightDisplayName、email、avatar覆盖会话查看器中的显示名与用户头像。

上报自定义事件

本教程过滤目标为自定义事件header-link-*,其中*表示被点击链接的后缀(例如点击首页链接会触发header-link-home)。这类事件需要在你的应用中手动上报,上报后即可在事件搜索与仪表盘中按事件名过滤。

分步搭建图表:独立用户点击统计

下面按官方教程的完整步骤,在 highlight.io Dashboards 的图表编辑器中配置这张柱状图。

第 1 步:选择数据源(Source)

在图表编辑器中,将Source(数据源)设置为events(事件)。事件数据源包含会话中的点击、导航动作以及自定义事件,能提供用户与应用交互的细粒度信息。这与 logs、traces、sessions、errors 等数据源并列,是 highlight.io 六类可查询资源之一。

第 2 步:选择图表类型(View Type)

将View type设置为Bar chart / histogram(柱状图/直方图)。柱状图擅长比较不同类别之间的数值,非常适合按事件名分组后对比各类事件的独立用户量。也可以按需切换到 Line chart(折线图)或 Table(表格)。

第 3 步:应用过滤器(Filters)

在Filters输入框中写入事件搜索查询,聚焦到目标事件。本例中过滤到自定义事件header-link-*:

event=header-link-*

事件搜索的默认键是event,如果只输入header-link-*也会被解析为event=*header-link-*。关于键值语法、正则(=[regex])、exists等操作符的完整说明,可参考 搜索语法文档。

第 4 步:应用函数(Function)——CountDistinct 独立用户数

此时查询返回的是事件总数,而非用户数。要得到去重后的独立用户数,将Function(函数)更新为CountDistinct,字段选择identifier属性。identifier是每个用户的唯一标识(如邮箱或 ID),对它的值去重计数即可得到独立用户数。

关于标识的更多说明(显示名、头像、未识别会话的行为等),见 识别用户(Identifying Users)文档。

第 5 步:分组数据(Group by)

开启Group by,按event name(事件名)对结果分组。这样,被过滤出的header-link-*事件会被拆分为具体发生的事件(如header-link-pricing、header-link-docs),每一类独立显示一根柱。

第 6 步:分析结果

最终的图表展示的是所有被过滤会话中,每个事件的去重邮箱数(即独立用户数)。借助这张图你可以:

  • 找出被点击最多的事件(即页头中最受欢迎链接);
  • 观察用户参与度随时间的变化趋势;
  • 判断应用中哪些区域被最频繁访问。

第 7 步:细化指标——切换到独立会话

如果希望统计独立会话(unique sessions)而非独立用户,只需将CountDistinct的字段从用户标识改为secure_session_id(事件发生的会话 ID)。这在需要区分"用户量"与"访问量"、计算 DAU(日活跃用户)等场景下非常有用。关于事件的更多搜索与属性用法,见 事件搜索文档。

第 8 步:解读数据并采取行动

利用图表洞察应用的整体使用情况:

  • 识别页面上被使用最多的部分;
  • 发现参与度下降的趋势并调查潜在原因;
  • 识别驱动更高参与度的成功功能或内容;
  • 基于用户参与模式规划有针对性的改进或营销活动。

建议定期监控并复查这些指标,随着应用与用户群体的演进持续调整。

底层实现:CountDistinct 如何变成 SQL

理解 CountDistinct 的底层执行有助于判断查询开销与结果语义。在 backend/private-graph/graph/schema.graphqls 中,MetricAggregator枚举定义了可用的聚合函数,包括Count、CountDistinct与CountDistinctKey(CountDistinctKey专用于对某个键去重计数):

enum MetricAggregator { Count CountDistinct CountDistinctKey # ... Min / Avg / P50 / P90 / P95 / P99 / Max / Sum 等 }

前端图表配置的聚合函数会映射到后端 Go 代码,最终翻译为 ClickHouse SQL。在 backend/clickhouse/query.go 的getFnStr函数中可以看到具体的翻译规则:

case modelInputs.MetricAggregatorCountDistinctKey, modelInputs.MetricAggregatorCountDistinct: if useState { return fmt.Sprintf("uniqState(toString(%s))", column) } return fmt.Sprintf("round(count(distinct %s) * 1.0)", column)

也就是说:

  • CountDistinct(identifier)最终生成为count(distinct identifier),即 ClickHouse 对identifier去重后计数;
  • 在增量聚合(State 模式,用于指标预聚合)下则使用uniqState(toString(identifier)),把去重计数的中间状态持久化下来,避免重复全表扫描;
  • getLimitFnStr(query.go)在限制分组数量(如 "Limit 10 by Count")时使用同样的去重逻辑。

这正是"图表上的一个下拉选项,背后是一整套 ClickHouse 去重计数执行链路"的体现。

进阶:事件搜索、自动注入属性与漏斗分析

事件的自动注入属性

事件在写入时会被注入一批默认属性,均可作为过滤与分组依据。与本教程直接相关的有:

属性说明示例
event发生的事件名SessionsPageLoaded
identifier传入H.init/H.identify的用户标识1
secure_session_id事件所在会话的 IDe1845285cb360410aee05c61dd0cc57f85afe6da
identified会话是否成功识别了用户false
first_session是否为该用户的首个会话false
browser_name/os_name/country/city/state浏览器、系统与地理位置信息Chrome/Mac OS X/Greece

完整的自动注入属性表见 事件搜索文档 的 "Searchable Attributes" 小节。

特殊事件:Click 与 Navigate

highlight.io SDK 默认记录两类事件:

  • Click 事件:由鼠标按下动作触发(即使点击的是非可交互元素,如页头空白处),主要属性包括clickTextContent(被点击内容的文本)、clickTarget(被点击的 HTML 元素)、clickSelector(被点击元素的完整 HTML 路径);
  • Navigate 事件:由 URL 变化触发(含刷新),主要属性包括url、landing_page、exit_page、reload。

本教程以自定义事件header-link-*为例,但同样可以直接对默认 Click 事件做用户分析,例如统计"点击了页头导航区域的独立用户数"。

用漏斗(Funnel)串联多个事件

事件分析不仅限于单张图。在事件搜索中选择Funnel Chart视图类型,可以查看一个会话中按步骤依次发生多个事件的比例——例如"点击页头链接 → 访问定价页 → 触发注册"的转化漏斗,与上述独立用户统计互为补充。

常见问题与最佳实践

Q1:CountDistinct 与 Count 有什么区别?Count 统计事件发生次数(同一用户点击多次会重复计入);CountDistinct 对指定字段去重(同一用户多次点击只计一次)。做"独立用户数"时必须用 CountDistinct +identifier。

Q2:什么时候用secure_session_id而不是identifier?统计"有多少次独立访问"时用secure_session_id(每次会话计一次);统计"有多少个独立的人"时用identifier(每人计一次)。指标含义(访问量 vs 用户量)完全不同。

Q3:图表的其他字段怎么配?

  • Bucket by:默认按Timestamp聚合为时间序列;也可以改为其他数值字段做直方图分布(如duration);禁用后则在整个时间范围内做聚合(适合表格形式的汇总指标);
  • Group by 的 Limit:可以限制展示的分组数量,例如按 Count 只展示 Top 10 事件,让图表更聚焦;
  • Graph title:为每张图设置清晰的标题,便于在仪表盘中识别。

最佳实践:先确认事件与H.identify()已正确上报,再搭建图表;同时用"事件总数"与"独立用户数"两张图对比,可以快速判断某个页头链接是"少数人频繁点击"还是"多数人少量点击";最后定期复查指标定义,随着产品功能与用户规模演进及时调整分组维度与过滤条件。

至此,你已经掌握了在 highlight.io 中用事件数据源 + CountDistinct 做用户分析的完整流程,可以将其推广到任意自定义事件、默认 Click/Navigate 事件,以及漏斗分析等更复杂的场景中。

  • 可观测性
  • 后端

【免费下载链接】highlight

highlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.

项目地址:https://gitcode.com/gh_mirrors/hi/highlight
点击查看免费下载

相关推荐

上一篇:终极编程语言宝典:1000+ Hello World示例全解析
下一篇:如何快速实现iOS网络监控?Reachability.swift完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询