ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PostHog Web Analytics 支持工单分级排查实战指南:从队列枚举、诊断 Playbook 到修复产出

PostHog Web Analytics 支持工单分级排查实战指南:从队列枚举、诊断 Playbook 到修复产出 PostHog Web Analytics 支持工单分级排查实战指南从队列枚举、诊断 Playbook 到修复产出【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog本指南以 PostHog 仓库内.agents/skills/triaging-web-analytics-support/技能文档为主体完整呈现一套端到端的 Web Analytics 支持工单分级Triage方法论先在数据仓库中枚举工单队列再把工单归入六大诊断形态并执行对应 Playbook最后产出有证据支撑的回复草稿与修复 PR。读完你将掌握 PostHog 内部支持团队处理“指标对不上”“流量下降”“Tracker 不加载”等高频问题的完整排查链路并了解底层源码HogQL 通道分类、会话入口属性聚合、ClickHouse 字典如何支撑每一个诊断结论。说明该技能定位为内部工具Internal-only——它需要跨客户查询支持与用量数据涉及客户名称、流量数字的内容严禁进入公开产物PR、Issue、Commit。文中所有 SQL 均针对 PostHog 内部 MCP 数据项目USproject 2编写。一、分级工作的核心原则技能文档开篇给出两条贯穿始终的准则先诊断、后写码绝大多数被上报的“Bug”实际上是可解释的语义问题而真正的 Bug 往往先出现在错误追踪Error Tracking或原始数据里而不是代码里。先定层、再下结论任何症状都必须先判定它存在于哪一层——Capture采集→ Ingestion摄入→ 存储事件Stored Events→ 查询期分类Query-time Classification→ UI。例如原始count()的下降不可能由查询期的机器人排除逻辑引起分类规则的变更也不可能改变已存储的计数。在提出修复方案前必须先明确指出证据指向哪一层。这两条原则分别对应了工单分类阶段的“层拆分”与“先查既有先例”两个横切规则。二、第一步枚举工单队列工单存放在 PostHog 的 Conversations 产品中可以通过 PostHog MCP 的execute-sql工具对内部项目的system.support_tickets表project 2US进行查询Zendesk 镜像则承载了完整评论历史。该表在仓库中确有实现posthog/hogql/database/schema/system.py 中以PostgresTable注册了support_tickets见support_tickets: PostgresTable PostgresTable(namesupport_tickets, ...)并配套tags、assignee等内部联结表访问隔离通过ticket_id IN (SELECT id FROM system.support_tickets)形式的谓词作用域实现。技能文档提醒查询system.*表前务必先用system.information_schema.columns确认列结构。2.1 拉取未处理的 Web Analytics 工单references/ticket-queries.md 提供了开箱即用的队列扫描 SQLSELECT ticket_number, id, status, priority, channel_source, substring(last_message_text, 1, 400) AS last_msg, created_at, message_count FROM system.support_tickets WHERE status IN (new, open, pending) AND created_at now() - INTERVAL 21 DAY AND (last_message_text ILIKE %web analytics% OR last_message_text ILIKE %bounce% OR last_message_text ILIKE %utm% OR last_message_text ILIKE %pageview% OR email_subject ILIKE %web analytics%) ORDER BY created_at DESC使用该查询需要注意几个已知陷阱last_message_text只有最新一条消息且可能被截断这里截取前 400 字符message_count 1意味着还有你没看过的历史对话。关键词过滤会漏掉措辞不同的工单——因此还要同时阅读#support-web-analyticsSlack 频道中镜像过来的 Zendesk 工单流每条消息里的应用内工单链接携带 Conversations UUID。2.2 通过 Zendesk 仓库镜像取完整评论历史system.support_tickets没有消息表完整评论历史在 Zendesk 镜像表的一个 JSON 数组列中。核心技巧是使用arrayJoin展开child_eventsJSON 数组再用JSONExtractString提取正文SELECT created_at, body FROM ( SELECT created_at, JSONExtractString( arrayJoin(JSONExtractArrayRaw(assumeNotNull(toString(child_events)))), body) AS body FROM zendesk.ticket_events WHERE ticket_id {zendesk_ticket_id} ) WHERE body ! ORDER BY created_at ASC三个关键细节assumeNotNull必不可少——arrayJoin不能直接作用于Nullable列应在子查询之外应用LIMIT否则arrayJoin会先行展开导致 LIMIT 失效MCP 展示会截断长单元格应显式提取字段而不是直接倾倒原始 JSON。2.3 将请求者邮箱解析到组织/团队US 与 EUPostHog 内部数据项目区分 US 与 EU 区域且EU 客户数据无法从 US MCP 项目查询。跨区域解析请求者邮箱时使用UNION ALLSELECT us AS region, u.email, u.current_team_id FROM postgres.posthog_user u WHERE u.email {email} UNION ALL SELECT eu, u.email, u.current_team_id FROM eu_postgres_posthog_user u WHERE u.email {email}补充可用的辅助表postgres.posthog_organizationdomain仅已验证域名小组织常为空、按名称查询的postgres.posthog_organization、以及all_posthog_team。任一区域的单团队事件数据则改用querying-production-databases-via-metabase技能覆盖 prod-us 与 prod-eu 访问。三、第二步按诊断形态分类并执行 Playbook技能文档将 Web Analytics 工单归纳为六种诊断形态每种形态都有明确的触发词与第一步动作形态触发词第一步动作前端崩溃Frontend crash“everything crashes”、异常 ID、堆栈错误追踪查询sourcemap 后的帧可定位文件。US 与 EU 项目都要查两个数字对不上Two numbers dont match“两个不同的跳出率”、“insight X 与 tile Y 不一致”先查语义而非代码事件级 vs 会话入口级作用域、“landing vs containing”、any-event vs entry-event 过滤器解释大多数情况流量随时间下降Count drop over time“pageviews 下降”、“追踪丢失”层拆分原始存储计数 vs 查询期排除。看$pageview与$pageleave比值、UA 分段、SDK 版本固定机器人形态流量消失很常见不是 PostHog 的 BugTracker 不加载 / 计数低于竞品“数字低于其他工具”、GTM、consent、广告拦截器用 Playwright 对客户线上站点做运行时加载审计加载方式、首请求时机、黑名单模拟。见 references/loading-audit.md广告平台集成错误“无法重新添加 source”、OAuth 报错、“没有转化”Source 重建路径、OAuth 失败模式如 Microsoft AADSTS650052、归因连接键精确 campaign 名 归一化 source兜底需两个 UTM 同时存在渠道类型误分类“显示为 Direct”、“渠道不对”查 channel_definitions.json channel_type.py 中的决策树未知 source 被剥离的 referrer 会落到 Direct两条横切规则先定层再修复明确证据指向 Capture → Ingestion → 存储事件 → 查询期分类 → UI 中的哪一层。先查先例再动手检索既有 Issue/PR 与频道历史——技能文档明确提到自引用排除self-referral exclusion、AI 渠道类型、OAuth 错误提示等反复出现的诉求已有开放 Issue其上下文会改变正确的回应方式。3.1 Playbook前端崩溃拿到异常工单通常带异常 ID 或压缩后的堆栈chunk-XXXX.js帧。在内部项目的错误追踪中检索query-error-tracking-issues-list配合searchQuery和/webURL 过滤。Issue 行的source字段给出 sourcemap 后的文件用verbosity: stack查看事件可获得解析后的函数名。阅读命中的代码路径。文档记录的 Web Analytics 高频崩溃类kea-router 会 JSON 解析 query 参数——?someParam123会变成数字、?papb会变成数组任何由searchParams喂入的持久化 reducer 都可能永久持有非字符串值进而在每次 selector 重算日期变更、过滤变更时崩溃包括那些只是connect了该 logic 的场景。两端同时修复在 router 边界强制类型转换并且在读路径也做处理仅修边界无法覆盖已持久化的坏值补一个廉价的纯函数回归测试断言非字符串输入不会抛异常。区分 CI 噪音门禁 Job如 “X Tests Pass”会在依赖 Job 被重复运行的 superseded 版本取消时失败——先读门禁日志再追查幻影测试失败一个执行了零步骤就失败的 runner 属于基础设施问题重跑即可。3.2 Playbook两个数字对不上几乎总是作用域语义问题主要有三种形态Landing vs Containing落地 vs 包含总览图块按“任意事件匹配过滤器”圈定会话而按路径的跳出率/下钻行按会话入口值圈定。过滤器相同、分母不同两者都正确。事件级过滤 vs 会话入口级下钻按事件utm_campaign过滤会选中“包含任一匹配事件”的会话而 UTM 下钻图块按会话$entry_utm_campaign分组。一个在会话中途才带上 UTM 的会话能匹配过滤器却显示为 “(not set)”。算子漂移URL 的containsvsequals、路径清洗开/关、同名的事件属性 vs 会话属性。分辨率结论精确定义两套口径然后给客户对齐的一对——与会话级下钻比较时就用会话入口属性过滤。只有当两个表面声称同一口径却仍然不一致时才升级为 Bug。源码佐证该语义差异直接对应仓库中的会话入口属性聚合实现。posthog/hogql/database/schema/sessions_v2.py 中$entry_utm_campaign被定义为null_if_empty(arg_min_merge_field(initial_utm_campaign))——即会话入口属性由initial_utm_campaign经过argMin合并聚合而来这与事件级utm_campaign天然属于不同口径。相关查询构建器集中在 products/web_analytics/backend/hogql_queries/overview 与 stats_table 两套 query builder如 web_overview.py、stats_table.py。3.3 Playbook流量随时间下降决定性问题是哪一层掉了拉原始日序列通过querying-production-databases-via-metabase按天对事件做count()。如果原始计数下降那么任何查询期变更机器人分类、排除规则、物化都不可能是原因——它们永远不会改变已存储的计数。快速排除假线索的健全性检查$lib SDK 版本分段版本固定 无 SDK 回归、重复 UUID 计数去重、按星期几配对比较季节性、按小时分布区域/故障。机器人指纹只有$pageview下降而$pageleave持平损失集中在少数几个 UA 字符串且周环比萎缩 10~50 倍每个会话约 2 次 pageview 却没有 pageleave。这说明非人类流量停止执行 JS SDK——通常是客户侧边缘设施WAF、bot-fight 模式、JS challenge发生变化或爬虫停止。他们的服务器日志仍会计数这些请求这正是“我们的日志看起来没变”的原因。回复框架PostHog 存储的是它实际收到的内容识别消失的流量段请客户确认在具体日期他们的边缘设施改了什么并说明新的更低水平更接近真实人类流量。3.4 PlaybookTracker 不加载 / 计数低于竞品对客户线上页面执行运行时加载审计见 references/loading-audit.md。反复出现的高频结论投递链比端点代理更重要反向代理的api_host本身不可被拦截但如果 SDK经由 GTM加载拦截googletagmanager.com照样会杀死它。要么第一方脚本 第一方端点否则都不算数。Consent 延迟吃掉快速跳出即使在无横幅区域标签管理器与 consent 平台也是异步解析的每个在该窗口前离开的访客都不会发送任何数据。需要测量首请求时机与竞品脚本的差距。对等比较竞品工具在访问定义、机器人过滤、无 Cookie 计数上都有差异先量化加载链差距再谈口径差距。3.5 Playbook广告平台集成错误软删除的 Source 不会阻止重建前缀检查会排除已删除行所以出现 “Prefix already exists” 说明旧 Source 仍然活跃。OAuth 重连失败是重建的头号障碍Microsoft 的 AADSTS650052缺少租户管理员同意 / service principal会以裸invalid_clienttoast 形式出现。一定要问清楚确切的错误文本和它出现的位置登录弹窗 vs 表单字段 vs 创建 toast——每个位置对应不同的代码路径。账户选择器可能受项目管理员门控成员看到权限错误而管理员能看到账户。Marketing Analytics 归因逻辑转化事件优先用自己的 UTM 归因否则回退到窗口内最近一次同时携带utm_campaign和utm_source的 pageview然后按大小写敏感的精确 campaign 名 归一化 source 做 LEFT JOIN。任何缺失都会落入 “organic”。如果付费转化为 0 而 organic 行很胖说明归因连接键或“双 UTM 要求”失败而不是目标goals配置失败。原生广告源只需同步其统计表即可获得花费指标PostHog 事件只用于转化目标。3.6 Playbook渠道类型误分类这是最能体现“查询期分类”层概念的一类分类发生在查询期HogQL由 channel_definitions.json 驱动通过channel_definition_dict这个 ClickHouse 字典参与计算修改定义会自动重分类历史数据。默认决策树以 Direct 兜底unknown source$direct引用域最终映射到 Direct——因此在 referrer 被剥离的流量上一个无法识别的utm_source就会显示为 Direct。正确修法是添加定义行而不是改兜底逻辑——该兜底行为已被测试钉死为对垃圾 UTM 的刻意处理。定义变更需要 ClickHouse 迁移add_missing_channel_types只会 INSERT 缺失的 (domain, kind) 组合类型变更需要重建truncate → re-insert →SYSTEM RELOAD DICTIONARY。同时要更新create_channel_definitions_file.py否则下一次重新生成会回退 JSON。**同源插页bot challenge**会破坏document.referrer却保留 query 字符串——自引用且 UTM 完好的流量是其签名。缓解手段用before_send重写自引用、在客户自己的域名上加自定义渠道规则、缩小 challenge 范围。3.6.1 源码级佐证默认决策树与字典实现默认分类逻辑完整实现在 posthog/hogql/database/schema/channel_type.py 的_initial_default_channel_rules_expr()中其注释明确说明“该逻辑同时被官方文档引用改动需同步两边”。核心是一段multiIf决策树节选关键分支multiIf( match({campaign}, cross-network), Cross Network, ({medium} IN (cpc,cpm,cpv,cpa,ppc,retargeting) OR startsWith({medium},paid) OR {has_gclid} OR {gad_source} IS NOT NULL), coalesce(lookupPaidSourceType({source}), ..., Paid Unknown), ({referring_domain} $direct AND {medium} IS NULL AND ({source} IS NULL OR {source} IN ((direct),direct,$direct)) AND NOT {has_fbclid}), Direct, coalesce(lookupOrganicSourceType({source}), ..., Unknown) )要点付费判定优先gclid、fbclid、gad_source、paid medium 前缀Direct 判定要求 referrer 为$direct且 source/medium 为空最后兜底到 Referral/Unknown。自定义渠道规则CustomChannelRule支持 EXACT、IS_NOT、IS_SET、IS_NOT_SET、ICONTAINS、NOT_ICONTAINS、REGEX、NOT_REGEX 等算子通过multiIfcoalesce叠加在默认规则之上custom_rule_expr优先未命中则落到内置规则。底层字典在 posthog/models/channel_type/sql.py 中构建channel_definition是ORDER BY (domain, kind)的 MergeTree 表channel_definition_dict采用COMPLEX_KEY_HASHED()布局复合主键 domain, kindLIFETIME 为 3000~3600 秒通过 DICT_READER 只读账号从表加载。数据来自 channel_definitions.json仓库中约 1500 行每条记录形如[domain/medium, kind, domain_type, type_if_paid, type_if_organic, is_app]例如[email, medium, null, null, Email, false]、[andisearch.com, source, AI, null, AI, false]。相关的两个迁移文件为 posthog/clickhouse/migrations/0069_add_channel_definitions.py 与 posthog/clickhouse/migrations/0073_add_missing_channel_types.py。四、第三步产出工件Artifacts每个工单最终要产出三类工件回复草稿每一条论断都要落到file:line、查询结果或文档链接上。与其只解释客户“为什么错”不如直接给出对齐的过滤器/属性——例如用会话$entry_utm_campaign替代事件utm_campaign。修复 PR每个修复使用一个 worktree 分支conventional commit 规范提交用仓库模板创建 Draft PR。公开仓库安全红线泛化描述 Bug绝不包含客户名称、Zendesk 编号或客户流量数字Slack/工单链接需认证访问可作为来源上下文。会话笔记在.notes/维护一份持续更新的分级笔记每个工单一个章节且每个工单必须有明确的 “action left” 标记便于人类接手队列。五、第四步验证工具运行时加载审计与流量模拟references/loading-audit.md。生产查询侧检查按团队事件序列、UA 分段、摄入告警querying-production-databases-via-metabase技能覆盖 prod-us 与 prod-eu 访问。错误追踪MCP 的query-error-tracking-issues-list/query-error-tracking-issue-events配合verbosity: stack可获得 sourcemap 后的帧。5.1 运行时加载审计实操模式PlaywrightChromium双轮扫描 2~4 个代表性 URL落地页、一个深层页面、一个带 UTM 参数的页面正常轮Normal pass真实用户 UA、US 时区/语言环境。记录对 tracker 域名的每个请求及相对导航开始的时间戳。加载完成后再等约 10 秒评估页内状态window.posthog__loaded、config.api_host、config.token前缀、person_profiles、标签管理器容器与dataLayer长度、consent 平台对象及其解析后的状态、竞品 tracker 全局变量与脚本标签。黑名单轮Blocklist pass同上但中断匹配 EasyPrivacy 风格域名列表的请求googletagmanager.com、google-analytics.com、各分析厂商域名对比哪些 tracker 存活。结果解读要点加载方式head内联片段 vs 标签管理器 vs 打包引入。代理了api_host但走 GTM 投递的GTM 被拦截照样失效——投递链是最薄弱环节。首请求时差tracker 相对导航开始的第一条网络活动毫秒数与竞品的差距就是快速跳出的盲区。Consent 地理门控consent 平台在 GDPR 区域外常常根本不加载那些区域里的延迟来自标签管理器启动而不是横幅。两个重要注意事项主流 SDK 都会抑制自动化posthog-js 与多数竞品能检测navigator.webdriver不会从无头浏览器发送事件。审计中 0 条采集请求是预期现象与真实用户无关——断言应基于脚本/运行时存在性与时机而不是事件 POST。带?utm_...测试参数的访问无害但严禁向客户项目注入伪造的转化事件另外数字型主机名在new URL()中会被解析为 IPv4不要在合成输入上断言精确解析后的主机。5.2 既有先例与演进方向文档记录的既有资产每次审计现场编写约 120 行的会话级审计脚本一个更完整的 CLIcheck-loading、new-user、returning-user场景曾存在于内部沙箱仓库并有将其发布为 tools/traffic-sim/ 的开放计划该目录当前已存在于仓库中包含流量模拟相关脚本与文档。此外逐页对比表加载方式、片段位置、config key/host、与基线匹配度能让部分迁移状态一目了然——缺失 tracker 的页面会立刻显现。六、附录错误追踪交叉引用前端崩溃类工单中EU 客户报告的崩溃通常在 US 也有出现PostHog 员工与 US 用户执行的是同一份代码。在内部项目的错误追踪中用 MCP 工具检索即可Issue 行的source字段指出 sourcemap 后的文件verbosity: stack给出解析后的帧名——这样无需本地复现就能从压缩的客户堆栈定位到file:line。参考资源索引技能主文档.agents/skills/triaging-web-analytics-support/SKILL.md工单查询 SQL 集.agents/skills/triaging-web-analytics-support/references/ticket-queries.md六大形态诊断 Playbook.agents/skills/triaging-web-analytics-support/references/diagnostic-playbooks.md运行时加载审计指南.agents/skills/triaging-web-analytics-support/references/loading-audit.md支持工单数据表定义posthog/hogql/database/schema/system.py会话入口属性聚合posthog/hogql/database/schema/sessions_v2.py渠道分类决策树posthog/hogql/database/schema/channel_type.py渠道定义数据与字典posthog/models/channel_type/channel_definitions.json、posthog/models/channel_type/sql.py渠道定义迁移posthog/clickhouse/migrations/0069_add_channel_definitions.py、posthog/clickhouse/migrations/0073_add_missing_channel_types.pyWeb Analytics 查询构建器products/web_analytics/backend/hogql_queries/【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表