使用 browser-data-collector 在 wp-calypso 中采集 RUM 数据并上报 Logstash 前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载导读本文围绕 wp-calypso 仓库 packages/browser-data-collector 包展开讲解如何在浏览器端以「开始 → 停止」的埋点模型采集真实用户监控RUM数据并通过wpcom-proxy-request将报告发送到 Logstash。读完本文你将掌握start/stop/cancel三个 API 的用法、报告与 Collector 的架构关系、全页加载与内联计时的差异以及如何编写自定义 Collector 扩展报告字段同时会看到该包在 client/dashboard 中的真实集成案例可作为接入参考。包定位为 Logstash 采集浏览器端 RUM 数据browser-data-collector是 wp-calypso 下的一个 TypeScript 包包名automattic/browser-data-collector当前版本 3.0.0其定位见 package.json 的描述A tool to collect data from different browser APIs.即一个从各类浏览器 API 采集数据并汇集成报告的工具。它的核心用途是采集RUMReal User Monitoring真实用户监控数据并发送到Logstash见 README。在真实调用中报告的发送通过 logstash.ts 中的request完成以POST方式调用/logstash接口请求体为params字符串其中feature: calypso_client、message: perf.nav采集到的数据放在properties字段中。换句话说每次stop()之后发出的是一个带perf.nav消息类型的性能导航事件。值得说明的演进信息见 CHANGELOG.md1.0.0 起改为纯 ESM2.0.0 移除了对 Performance Mark 与 Measure 采集器的支持user-timingAPI 文件仍保留在src/api下但不再导出对应 Collector3.0.0 又恢复了 CJS 构建。因此在当前仓库中该包同时提供 ESM 与 CJS 两种产物dist/esm/index.js与dist/cjs/index.js见 package.json。快速上手start / stop 两行代码完成一次上报官方 README 给出的用法非常精简READMEimport { start, stop } from automattic/browser-data-collector; start( my-page, { fullPageLoad: true } ); // Later in the same page stop( my-page );这一对调用会向 Logstash 发送一份报告报告包含但不限于READMEdurationstop()相对start()经过的毫秒数当fullPageLoad: true时则相对页面导航开始navigation start计算id报告名称即本例中的my-page环境数据如 Calypso 版本version或构建目标target来自 Performance Timing API 的一系列时间点数据。结合 index.ts 的源码可以看到start的完整签名与细节export const start async ( id: string, { fullPageLoad true, collectors [], }: { fullPageLoad?: boolean; collectors?: Collector[] } {} ): Promise void 几个关键行为fullPageLoad默认值为true。为true时创建「从页面加载起算」的报告为false时创建「从现在起算」的报告collectors允许传入额外的自定义采集器它们会在默认采集器之外追加执行同一id的报告若已在途存在inFlightReporters中重复调用start会被直接忽略避免重复埋点。stop的签名index.ts如下export const stop async ( id: string, { collectors [] }: { collectors?: Collector[] } {} ): Promise boolean 行为要点若id不存在在途报告stop静默返回false不抛出异常避免影响页面渲染若报告仍在start的异步过程中会等待其完成后再停止stop先运行停止阶段采集器再调用send( payload )发送发送成功返回true失败返回false。另外还有一个 README 未提及、但被 dashboard 实际使用的 APIcancel( id )index.ts。它从在途 Map 中删除指定 id 的报告且不发送用于「放弃本次采集」。架构Report、Collector、Transport、API 四层概念README 的 Architecture 一节README给出了四个核心概念概念作用Report存放采集数据的对象含id、开始时间、结束时间与额外元数据是最终发送给 Logstash 的 payloadCollector一个「给现有 Report 追加额外元数据」的函数Global Collectors应用于所有报告的采集器集合Transport将 Report 发送到后端系统的机制目前仅实现了 LogstashAPI与浏览器 API或更广义的外部数据源对话的适配层Collector 通过它取数再写入 Report对应到源码类型定义在 types.tsexport type ReportData Map string, number | string | boolean ; export type ReportPayload Record string, number | string | boolean ; export interface Report { id: string; data: ReportData; beginning: number; end?: number; stop: ( collector: Collector[] ) Promise ReportPayload ; } export type Collector ( report: Report ) Promise Report | Report;可以看到 Report 的内部数据是一个Mapstring, number | string | booleanCollector 的本质就是( report ) report这类「原地追加字段」的函数。Report 的生命周期fromPageStart 与 fromNowreport.ts 提供了两种构造方式ReportImpl.fromNow( id, collectors )起点为当前时刻对应fullPageLoad: falseReportImpl.fromPageStart( id, collectors )起点为页面导航开始对应fullPageLoad: true。构造函数report.ts中固定了全局采集器的组合这就是 README 所说的 Global Collectors所有报告共用的启动采集器pageVisibilityStart所有报告共用的停止采集器deviceMemory、environment、pageVisibilityStop、networkInformation全页加载报告额外使用启动采集器fullPageStart停止采集器performanceTiming、blockingResources内联报告额外使用启动采集器inlineStart停止阶段不再追加性能采集器。runCollectorsreport.ts用Promise.all并行执行所有采集器并用 try/catch 吞掉单个采集器的异常只console.warn保证「一个采集器失败不会毁掉整份报告」。停止时report.ts流程为记录end Date.now()→ 运行停止阶段采集器 → 将dataMap 规约成普通对象 → 返回{ id, duration, ...data }其中duration end - beginning。Transport目前唯一的 Logstash 实现logstash.ts 是唯一已实现的 Transport它直接依赖wpcom-proxy-requestexport const send async ( payload: Record string, unknown ): Promise boolean { return request( { method: POST, apiVersion: 1.1, path: /logstash, body: { params: JSON.stringify( { feature: calypso_client, message: perf.nav, properties: payload, } ), }, } ); };若未来要接入其他后端例如自建遥测服务只需按同接口实现新的 Transport 并在 index.ts 中替换send的引用即可——这是从代码结构可以推断的扩展点。内置 Collectors 一览及其数据来源所有内置 Collector 统一在 collectors/index.ts 中导出其对应的浏览器 API 适配层位于 src/api 目录。下表汇总了各采集器与所写字段Collector写入的字段数据来源API 层environmentversion、target、envapi/environment.ts分别取window.COMMIT_SHA、window.BUILD_TARGET、window.configData.env_iddeviceMemorymemoryapi/device-memory.tsnavigator.deviceMemorynetworkInformationnetworkapi/network-information.tsnavigator.connection.effectiveTypeperformanceTiming21 个导航时序字段见下文api/performance-timing.tsperformance.timingblockingResourcesresourcesCount、resourcesStart/End、resourcesCompressed/Uncompressed/Transferred、resourcesCacheRatioapi/resources-timing.tsperformance.getEntriesByType(resource)fullPageStartfullPage: true并把beginning设为navigationStartcollectors/full-page-start.tsinlineStartfullPage: false并把beginning设为Date.now()collectors/inline-start.tspageVisibilityStart/pageVisibilityStophiddencollectors/page-visibility.ts这些浏览器 API 的可选类型声明集中在 global-types.tsNavigator.deviceMemory、Navigator.connection.effectiveType、Window.COMMIT_SHA、Window.BUILD_TARGET、Window.configData.env_id以及EffectiveConnectionType枚举2g | 3g | 4g | slow-2g。performanceTiming21 个导航时序字段performance-timing.ts 将 api/performance-timing.ts 暴露的每个时间点都写入报告navigationStart、unloadEventStart、unloadEventEnd、redirectStart、redirectEnd、fetchStart、domainLookupStart、domainLookupEnd、connectStart、connectEnd、secureConnectionStart、requestStart、responseStart、responseEnd、domLoading、domInteractive、domContentLoadedEventStart、domContentLoadedEventEnd、domComplete、loadEventStart、loadEventEnd共 21 项。其中normalize( value, start )performance-timing.ts将所有值都转换为相对报告起点的偏移量若原始值为 0例如无重定向时redirectStart为 0直接返回 0避免产生负数。源码注释api/performance-timing.ts还提醒这些方法基于已废弃的 Navigation Timing 规范新规范PerformanceNavigationTiming尚未被所有浏览器支持因此当前实现选择沿用旧 API。blockingResources量化 DOMContentLoaded 之前的阻塞脚本blocking-resources.ts 是信息量较大的一个采集器逻辑为计算domContentLoaded domContentLoadedEventStart - navigationStart若 0直接返回页面尚未完成该阶段从资源条目中筛选出initiatorType script、responseEnd domContentLoaded、decodedBodySize 0的「阻塞性脚本」有体积可排除跨域资源统计数量resourcesCount以及这些资源最早requestStart到最晚responseEnd的时间区间resourcesStart/resourcesEnd累加encodedBodySize压缩后、decodedBodySize解压后、transferSize实际传输含头部得到resourcesCompressed/resourcesUncompressed/resourcesTransferred计算缓存命中率resourcesCacheRatio100 - round( min( 1, resourcesTransferred / resourcesCompressed ) * 100 )。由于resourcesTransferred含头部而resourcesCompressed不含比值可能略超 1故用Math.min(1, ...)封顶。这组字段可用来分析「DOMContentLoaded 之前到底有多少脚本在阻塞渲染以及其中多少命中缓存」是定位首屏性能瓶颈的实用数据。pageVisibility检测报告期间标签页是否被隐藏page-visibility.ts 通过监听visibilitychange事件记录「报告期间标签页是否曾变为 hidden」最终写入hidden布尔字段。它刻意不关心当前状态、也不监听变回 visible 的事件不监听时若页面本就隐藏会在collectorStart里直接置位。源码注释中明确了两点局限无法检测「页面加载到调用 start 之间」的隐藏且假设同一时刻只有一个报告在运行否则退订事件时可能互相干扰。自定义 Collector往报告里追加业务字段Collector 是公开的类型从 index.ts 重新导出因此可以非常容易地编写自定义采集器并通过start/stop的collectors参数挂载。import type { Collector } from automattic/browser-data-collector; const myCollector: Collector ( report ) { report.data.set( myMetric, myValue ); return report; }; start( my-page, { fullPageLoad: true, collectors: [ myCollector ] } );字段的值类型限于number | string | boolean见 types.ts。若需访问未声明的浏览器 API可以参照 global-types.ts 的方式补充全局类型声明再仿照 src/api 下的模式封装一个 API 适配层让 Collector 保持纯净。在 dashboard 的真实代码里自定义 Collector 还被用于注入用户与会话上下文见下文。采样上报与开关should-send 与 rum-tracking/logstashREADME 特别强调README报告发送是采样的以避免压垮 REST 端点该逻辑在should-send.ts中由于完整报告在should-send函数中可用因此不仅可以基于id还可以基于任何采集器抓取的属性来决定是否发送。从当前仓库源码结构看should-send.ts尚未包含在src目录中src 目录列表 中未见该文件属于 README 预告的规划能力。以仓库现状为准目前上报由「功能开关 调用时机」双层控制功能开关rum-tracking/logstash特性开关。在 config/dashboard-production.json、config/production.json、config/development.json、config/wpcalypso.json 等配置中均为true而在 config/test.json 中为false调用时机dashboard 的调用代码会先检查config.isEnabled( rum-tracking/logstash )未开启则直接返回不做任何采集见下文。真实集成案例client/dashboard 的路由级性能埋点该包在 wp-calypso 中的真实落地位置是 client/dashboard/app/performance-tracking.ts它把「路由切换」作为埋点粒度。核心逻辑export function startPerformanceTracking( routeId: string ) { if ( ! config.isEnabled( rum-tracking/logstash ) || isDashboardBackport() ) { return; } const id normalizeRouteId( routeId ); cancel( id ); start( id, { fullPageLoad: isFirstLoad } ); }要点normalizeRouteId去掉 TanStack Router routeId 末尾的斜杠如/plugins/manage/→/plugins/manage/作为指标用的规范 idperformance-tracking.ts路由beforeLoad阶段调用startPerformanceTracking首次加载时fullPageLoad: true后续路由切换为false内联计时performance-tracking.ts由于 TanStack Router 在 hover 预加载时beforeLoad的cause会被缓存可能产生多余的start()调用因此每次启动前先cancel( id )清掉在途报告规避「错误报告阻塞后续真实导航」的问题注释见 performance-tracking.ts停止时机放在组件渲染后usePerformanceTrackerStop在useLayoutEffect里先重置isFirstLoad再用requestAnimationFrame延迟一帧后调用stop( normalizedRouteId, { collectors: [ buildCollector( siteSlug ) ] } )performance-tracking.tsbuildCollector是自定义采集器的典型范例从queryClient缓存中读取当前用户与站点信息写入client来自config( client_slug )、sitesCount、userLocale以及siteId、siteIsJetpack、siteIsAtomic等字段performance-tracking.ts提供PerformanceTrackerStop /组件渲染为null放置在「页面视为已加载」的位置供路由布局直接挂载performance-tracking.ts。路由侧接线见 router/index.tsxbeforeLoad中调用startPerformanceTracking( routeId )。这一案例完整示范了「启动采集器注入上下文 → 页面加载完成停止 → 采样发送到 Logstash」的闭环可直接作为其他客户端如 Calypso 主应用client目录下的页面接入时的参考模板。结语browser-data-collector以极小的 API 面start/stop/cancel 可扩展的 Collector 类型承载了 wp-calypso 的浏览器端 RUM 采集职责报告生命周期由ReportImpl管理默认字段由一组 Global Collectors 固化环境、设备、网络、导航时序与阻塞资源信息分门别类写入最终经wpcom-proxy-request以perf.nav消息发往 Logstash。理解并复用这一套「报告 采集器 传输 API 适配」的架构可以帮助你在不侵入业务代码的前提下为任意页面接入标准化的性能遥测。赞分享前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载相关推荐使用 Elastic Agent 采集 Logstash 监控数据并在 Kibana 仪表盘中可视化使用 Elastic Agent 采集 Logstash 监控数据并在 Kibana 仪表盘中可视化 本文是一份面向 Logstash 运维与可观测性工程师的实数据工程后端Chef Data Collector 设计全解析跨模式运行数据采集与上报协议Chef Data Collector 设计全解析跨模式运行数据采集与上报协议 本文以 data_collector.md https://link.gitcDevOps运维IaCOneUptime 前端浏览器 RUM 接入指南使用 OpenTelemetry Browser SDK 采集真实用户监控数据OneUptime 前端浏览器 RUM 接入指南使用 OpenTelemetry Browser SDK 采集真实用户监控数据 导读 本文是 OneUptim可观测性后端运维前端云原生微服务AI Agent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考