源码分析Sentry用户行为记录实现过程
Posted 南城FE
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码分析Sentry用户行为记录实现过程相关的知识,希望对你有一定的参考价值。
今日介绍前端异常监控利器Sentry平台中用户行为记录的源码实现过程,为什么使用Sentry,可以看以前的文章【前端异常监控平台对比】。
前言
在日常排查问题过程中,用户的行为操作记录能给到我们很大的参考及排查方向。目前市面上有的平台还不能记录用户的行为记录,Sentry提供了很好的行为记录查询,如下图所示。从用户跳转页面,到点击元素请求接口,发生异常,如图所示,极大可能是因为接口相应的数据没有达到预期导致页面发送错误,本文将探讨Sentry JS SDK中是如何记录用户的操作行为记录。
源码实现
SDK初始化时会调用init
方法,最终init
方法的 initAndBind
指向 getCurrentHub().bindClient()
Hub.prototype.bindClient = function (client)
// 获取最后一个
var top = this.getStackTop();
// 把 new BrowerClient() 实例 绑定到top上
top.client = client;
if (client && client.setupIntegrations)
client.setupIntegrations();
;
这里调用了默认的集成 client.setupIntegrations()
,最终指向 @sentry/core/integration.js
,这里的 options 即 sdk 初始化时传入并处理后的 options。
export function setupIntegrations(options)
var integrations = ;
getIntegrationsToSetup(options).forEach(function (integration)
integrations[integration.name] = integration;
setupIntegration(integration);
);
return integrations;
setupIntegration
调用 setupOnce
初始化拦截,这里的 setupOnce
是每个集成功能都有的能力。
export function setupIntegration(integration)
if (installedIntegrations.indexOf(integration.name) !== -1)
return;
integration.setupOnce(addGlobalEventProcessor, getCurrentHub);
installedIntegrations.push(integration.name);
logger.log("Integration installed: " + integration.name);
breadcrumbs面包屑的setupOnce函数
@sentry/broswer/integrations/breadcrumbs.js
– setupOnce
函数,可以看到对console,dom事件,网络请求,页面变化都做了拦截处理。
Breadcrumbs.prototype.setupOnce = function ()
var _this = this;
if (this._options.console)
addInstrumentationHandler(
callback: function ()
var args = [];
for (var _i = 0; _i < arguments.length; _i++)
args[_i] = arguments[_i];
_this._consoleBreadcrumb.apply(_this, __spread(args));
,
type: console,
);
if (this._options.dom)
addInstrumentationHandler(
...,
type: dom,
);
if (this._options.xhr)
addInstrumentationHandler(
..,
type: xhr,
);
if (this._options.fetch)
addInstrumentationHandler(
...,
type: fetch,
);
if (this._options.history)
addInstrumentationHandler(
...,
type: history,
);
;
addInstrumentationHandler
出自 @sentry/utils/instrument.js
,最终调用了instrument
方法,此方法实现了每种拦截类型的具体捕获逻辑。
function instrument(type)
if (instrumented[type])
return;
instrumented[type] = true;
switch (type)
case console:
instrumentConsole();
break;
case dom:
instrumentDOM();
break;
case xhr:
instrumentXHR();
break;
case fetch:
instrumentFetch();
break;
case history:
instrumentHistory();
break;
case error:
instrumentError();
break;
case unhandledrejection:
instrumentUnhandledRejection();
break;
default:
logger.warn(unknown instrumentation type:, type);
再看针对日志打印的具体拦截捕获回调函数,所有捕获的回调函数最终都会调用 getCurrentHub().addBreadcrumb
添加行为记录,只是不同类型的行为记录会传入不同的处理参数。
Breadcrumbs.prototype._consoleBreadcrumb = function (handlerData)
var breadcrumb =
category: console,
data:
arguments: handlerData.args,
logger: console,
,
level: Severity.fromString(handlerData.level),
message: safeJoin(handlerData.args, ),
;
if (handlerData.level === assert)
if (handlerData.args[0] === false)
breadcrumb.message = "Assertion failed: " + (safeJoin(handlerData.args.slice(1), ) || console.assert);
breadcrumb.data.arguments = handlerData.args.slice(1);
else
// Dont capture a breadcrumb for passed assertions
return;
getCurrentHub().addBreadcrumb(breadcrumb,
input: handlerData.args,
level: handlerData.level,
);
getCurrentHub().addBreadcrumb
最终调用于 @sentry/hub/scope.js
,在这里增加了时间的记录,以及最大记录条数的处理,最终将行为记录保存在 this._breadcrumbs(Scope)
数组中。
Scope.prototype.addBreadcrumb = function (breadcrumb, maxBreadcrumbs)
var mergedBreadcrumb = __assign( timestamp: dateTimestampInSeconds() , breadcrumb);
this._breadcrumbs =
maxBreadcrumbs !== undefined && maxBreadcrumbs >= 0
? __spread(this._breadcrumbs, [mergedBreadcrumb]).slice(-maxBreadcrumbs)
: __spread(this._breadcrumbs, [mergedBreadcrumb]);
this._notifyScopeListeners();
return this;
;
在控制台打印全局注入的__SENTRY__
对象可以在 hub
对象中的 _breadcrumbs
看到以下格式的数据。
最终在发起异常上报时,通过调用this.getStackTop()
获取到当前scope
中的数据一起上报,这里的 this.getStackTop().scope
即包括上述的 _breadcrumbs
行为数据,除此之前还有 _user
用户信息, _tags
标签数据, _extra
额外数据等。
Hub.prototype._invokeClient = function (method)
var _a;
var args = [];
for (var _i = 1; _i < arguments.length; _i++)
args[_i - 1] = arguments[_i];
var top = this.getStackTop();
if (top && top.client && top.client[method])
(_a = top.client)[method].apply(_a, __spread(args, [top.scope]));
;
最终异常上报的数据格式,如下图所示。
整体流程图
最后
整体源码分析就到这里了,Sentry是一款功能强大的前端异常监控平台,涉及的功能及数据分析很多,有兴趣的同学可以尝试看看,看我觉得有用记得点个赞再走吧,收藏起来说不定哪天就需要了。
以上是关于源码分析Sentry用户行为记录实现过程的主要内容,如果未能解决你的问题,请参考以下文章