顶级开源项目 Sentry 20.x JS-SDK 设计艺术(概述篇)

简介: 顶级开源项目 Sentry 20.x JS-SDK 设计艺术(概述篇)

概述



下面是一个实现新的 Sentry SDK 的指南。它涵盖了事件提交的协议,以及客户端的典型外观和行为准则。


编写一个SDK


SDK 的核心是一组实用程序,用于捕获有关应用程序中异常状态的数据。给定此数据后,它将构建并发送 JSON 有效负载并将其发送到 Sentry 服务器。


预计可用于生产环境的 SDK 包括以下各项:


  • DSN配置
  • 优雅故障(例如 Sentry 服务器不可达)
  • 设置属性(例如 tagsextra data
  • 支持 LinuxWindowsOS X(如果适用)

以下情况需要基于 Feature 的支持:

  • 如果有 Cookie 数据可用,则默认情况下不会发送
  • 如果有 POST 数据,则默认情况下不会发送

此外,强烈建议您使用以下功能:

  • 自动错误捕获(例如,未捕获的异常处理程序 uncaught exception
  • 日志框架集成
  • 非阻塞事件提交
  • 上下文数据助手(例如,设置当前用户,记录面包屑)
  • 事件取样
  • Honor SentryHTTP 429 Retry-After header
  • 事件前和事件后发送钩子
  • 堆栈跟踪中的局部变量值(在可能的平台上)
  • 为每个事件发送一个 environment。如果用户没有检测到或设置任何值,则应该使用 production

请参阅 features 页面,以获取有关常见的 Sentry SDK 功能的描述。


最终用户的用法


通常,对于最终用户来说,使用 SDK 包括三个步骤,无论使用哪种语言,这三个步骤看起来几乎是相同的:


  1. SDK 的初始化(有时对用户隐藏):

JavaScript


Sentry.init({dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'});


Python


Sentry.init({dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'});


  1. 捕获事件:

JavaScript


var resultId = Sentry.captureException(myException);


Python


result_id = sentry_sdk.capture_exception(my_exception);


  1. 使用事件捕获的结果:

JavaScript


alert(`Your exception was recorded as ${resultId}`);


Python


print('Your exception was recorded as %s', result_id);


理想情况下,init 允许多种配置方法。第一个参数应该总是 DSN 值(如果可能的话):

JavaScript


Sentry.init({
    'dsn': 'https://examplePublicKey@o0.ingest.sentry.io/0',
    'foo': 'bar'
})


请注意:SDK 应接受一个空的 DSN 作为有效配置。如果未初始化 SDK,或者使用空 DSN 初始化了 SDK,则 SDK 不应通过网络发送任何数据,例如捕获的异常。根据平台的不同,SDK 可能会避免执行不必要的初始化工作,并将其运行时占用空间降至最低。

此外,你应该提供全局函数来捕捉基本消息或异常:


  • Sentry.captureMessage(message)
  • Sentry.captureException(exception)


解析DSN


鼓励SDK通过构造函数允许任意选项,但必须允许第一个参数作为DSN字符串。该字符串包含以下位:


'{PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}{PATH}/{PROJECT_ID}'


您将向其发送请求的最终端点按照以下方式构造:


{BASE_URI} = '{PROTOCOL}://{HOST}{PATH}'
'{BASE_URI}/api/{PROJECT_ID}/{ENDPOINT}/'


Sentry 提供以下端点:


  • /envelope/ 用于使用 Envelopes 的任何提交。
  • /store/ 用于提交简单的 JSON 事件。
  • /minidump/ 用于包含 minidumpmultipart 请求。
  • /unreal/ 用于虚幻引擎4崩溃报告。
  • /security/ 用于浏览器 CSP 报告,通常在浏览器而不是 SDK 中进行配置。

有关如何组成适当的请求有效负载的信息,请查看相应的端点。


例如,给定以下构造函数:


Sentry.init({dsn: 'https://public@sentry.example.com/1'})


您应该解析以下设置:


对于纯 JSON 有效负载的最终 POST 请求随后将传输到:


'https://sentry.example.com/api/1/store/'


请注意:DSNsecret 部分是可选的,目前已被弃用。如果提供的 Sentry 的未来版本将完全忽略它,clients 仍然应该尊重它。DSN 解析代码不得要求设置 secret key


认证


预期将与消息正文(message body)一起发送身份验证标头(authentication header),该消息标头用作所有权标识符(ownership identifier):


X-Sentry-Auth: Sentry sentry_version=7,
  sentry_client=<client version, arbitrary>,
  sentry_timestamp=<current timestamp>,
  sentry_key=<public api key>,
  sentry_secret=<secret api key>


仅当 DSN 中包含 secret key 部分时,才必须包含 sentry_secret。协议的未来版本将完全弃用 secret key


请注意: 您应该在标头的 User-Agent 部分中包含 SDK 版本字符串,如果 auth 标头中未发送 sentry_client ,则将使用该字符串。


在无法发送自定义 X-Sentry-Auth 标头的情况下,可以通过查询字符串发送以下值:


?sentry_version=7&sentry_key=<public api key>&sentry_secret=<secret api key>...


sentry_key

  • 必需的。public key 应作为 SDK 配置的一部分提供。

sentry_version

  • 必需的。协议版本。该协议的当前版本为 7

sentry_client

  • 标识 SDK(包括其版本)的任意字符串。典型的模式是 client_name/client_version

例如,Python SDK 可能会将其作为 raven-python/1.0 发送。

sentry_timestamp

  • Unix 时间戳,表示生成此事件的时间。

sentry_secret

  • 应该作为 SDK 配置的一部分提供的密钥。

key 已被有效弃用,但由于某些较早的 Sentry 版本在大多数情况下都需要它,因此 SDK 仍应暂时释放该 key。该 secret key 将在Sentry的未来版本中完全淘汰。


HTTP Headers


我们建议始终发送以下标头:

  • content-type
  • content-length

根据 CORS 的策略,允许以下附加头:

  • x-sentry-auth
  • x-requested-with
  • x-forwarded-for
  • origin
  • referer
  • accept
  • authentication
  • authorization
  • content-encoding
  • transfer-encoding


请求压缩


强烈建议 SDK 在将请求正文发送到服务器之前先对其进行压缩,以保持数据量较小。首选方法是发送 content-encoding 标头。 RelaySentry 接受以下内容编码:

  • gzip:使用 LZ77 压缩算法。
  • deflate:使用 zlib 结构与 deflate 压缩算法。
  • br:使用 Brotli 算法。


传输编码


建议仅对非常大的请求使用传输编码(Transfer Encoding)。将标头设置为 transfer-encoding: chunked,这可以省略 content-length 标头,并要求将请求主体包装到 chunk 标头中。


有关更多详细信息,请参见 MDN。


读取响应


成功后,您将从服务器收到一个 HTTP 响应,其中包含 JSON 有效负载以及有关已提交有效负载的信息:


HTTP/1.1 200 OK
Content-Type: application/json
{
  "id": "fc6d8c0c43fc4630ad850ee518f1b9d0"
}


请注意 Sentry 将使用的响应代码。始终检查 200 响应,这将确认消息已交付。一个小级别的验证会立即发生,这可能会导致不同的响应代码(和消息)。


处理错误


我们强烈建议您的 SDK 妥善处理来自 Sentry 服务器的故障。具体来说,SDK 必须遵守 429 状态代码,并且在 Retry-After 之前不要尝试发送。如果 Sentry 不可用,则 SDK 应该丢弃事件,而不是重试。


要在开发过程中调试错误,请检查响应标头和响应正文。例如,您可能会收到类似于以下内容的响应:


HTTP/1.1 400 Bad Request
Content-Type: application/json
X-Sentry-Error: failed to read request body
{
  "detail":"failed to read request body",
  "causes":[
    "failed to decode zlib payload",
    "corrupt deflate stream"
  ]
}


X-Sentry-Error 标头和响应正文并不总是包含一条消息,但是它们仍然可以帮助调试客户端。发出时,它们将包含精确的错误消息,这对于识别根本原因很有用。


请注意: 我们不建议即使错误响应标头中声明了 Retry-AfterSDK 也不会在发生错误时自动重试事件提交。如果请求一次失败,则很有可能在下一次尝试时再次失败。重试次数过多可能会导致进一步的速率限制或 Sentry 服务器的阻塞。


并发(作用域 Scope 和集线器 Hub)


SDK 应该通过 hubsscopes 的概念来提供标准化的并发处理。统一 API 文档的“并发性”一章中对此进行了更详细的说明。


集成层


SDK 在可能的情况下应该在较低的层次上集成,这样可以捕获尽可能多的运行时。这意味着,如果 SDK 可以直接挂钩运行时或框架,这比要求用户子类化特定基类(或混合使用 helper)更可取。例如,Python SDK 将在框架中对核心功能进行 monkey 补丁,以自动拾取错误并集成作用域处理。

相关文章
|
1月前
|
Web App开发 存储 JavaScript
Node.js概述
Node.js概述
38 3
|
5月前
|
JavaScript 前端开发 开发者
JavaScript数据类型概述及Undefined与Null详解
JavaScript数据类型概述及Undefined与Null详解
N..
|
6月前
|
JavaScript 前端开发 API
Vue.js概述
Vue.js概述
N..
68 2
|
6月前
|
存储 XML 前端开发
编程笔记 html5&css&js 036 CSS概述
编程笔记 html5&css&js 036 CSS概述
|
6月前
|
数据采集 JavaScript 前端开发
Vue Nuxt.js 概述
Vue Nuxt.js 概述
104 0
|
存储 JavaScript 前端开发
【js】函数概述学习笔记(8)
【js】函数概述学习笔记(8)
41 0
|
Web App开发 JavaScript 前端开发
Node.js -- Node.js概述与安装和运行
Node.js -- Node.js概述与安装和运行
|
JavaScript 前端开发 数据库
Node.js 阻塞与非阻塞概述
Node.js 阻塞与非阻塞概述
|
XML 缓存 JavaScript
JavaScript-JavaScript概述及简单使用
JavaScript-JavaScript概述及简单使用
108 0
|
Web App开发 JavaScript 开发工具
零基础html5+div+css+js网页开发教程#001网页开发概述
零基础html5+div+css+js网页开发教程#001网页开发概述