文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Sentry 开发者贡献指南- SDK 开发(会话)

2024-12-02 10:26

关注

对于基本的健康跟踪,Sentry 接受包含会话更新事件的 envelopes。这些会话更新事件可用于通知 Sentry 有关 release 和 project 相关 project 健康状况的信息。

注意: 在本地使用 session 时,请确保使用必要的环境变量更新配置文件 ~/.sentry/sentry.config.py:

SENTRY_EVENTSTREAM = 'sentry.eventstream.kafka.KafkaEventStream'

基本操作

服务器模型

目前,Sentry 的 session system 已针对易于扩展性和操作成本进行了优化。这意味着该协议非常适合实现这一目标。其中一些优化显示在协议中,client 准确地遵循协议以避免在服务器上创建 bad data 非常重要。

服务器每小时都有预先物化(pre-materialized)的 session 数据。当会话更新事件到来时,服务器将立即将数据具体化(materialize)到正确的存储桶中。这意味着该协议仅限于“附加”。这也意味着 client 需要在其一侧存储会话的整个状态。

会话更新负载

一个 session update 是名为 session 的 envelope 中的一项。它包含一个大致如下所示的 JSON 负载:

  1.   "sid""7c7b6585-f901-4351-bf8d-02711b721929"
  2.   "did""optional distinct user id"
  3.   "init"true
  4.   "started""2020-02-07T14:16:00Z"
  5.   "duration": 60, 
  6.   "status""exited"
  7.   "attrs": { 
  8.     "release""my-project-name@1.0.0"
  9.     "environment""environment name"
  10.     "ip_address""optional user ip address for filtering"
  11.     "user_agent""optional user agent for filtering" 
  12.   } 

请注意,这必须包含在 envelope 中。所以完整的事件看起来像这样:

  1. {} 
  2. {"type":"session"
  3. {"sid":"..."

存在以下字段:

sid

如果初始会话状态为 exited,则允许客户端跳过它。

did

系统会在存储此 ID 之前自动对其进行哈希处理。

seq

值 0 是保留的,因为 init 设置为 true 的会话将自动将 seq 强制为 0。

timestamp

必须是 ISO 日期时间字符串。如果未发送,服务器将采用当前的 UTC 时间戳。在数据模型中,这称为 received。

started

必须是 ISO 日期时间字符串。

init

如果将其设置为 true,则表示这是会话的第一个事件。这让服务器优化会话计数,因为不需要重复数据删除(客户端无论如何都是权威的)。在内部设置此标志时,处理时 seq 更改为0。

duration

status

一个 session 只能有效地处于两种状态:ok,这意味着会话处于活动状态或终止状态之一。当会话从 ok 移开时,它不能再被更新。

errors

重要的是,当会话进入 crashed 时,此计数器也会增加。(例如:crash 本身也始终是一个 error)。如果未设置或为 0,摄取应强制 errors 为 1。

attrs

Session Aggregates Payload(会话聚合有效负载)

特别是对于 request-mode(请求模式) 会话(见下文),通常每秒有数千个请求和会话。

假设这些 session 将是短时间的,并且不希望跟踪它们的持续时间, 那么在它们被发送到 Sentry 之前,可以在 SDK 端将这些 session 聚合在一起。

SDK 应聚合关闭的 session,并按 started 时间、distinct_id 和 attrs 对它们进行分组。这些组将作为 sessions envelope 项发送。它包含一个大致如下所示的 JSON 负载:

  1.   "aggregates": [ 
  2.     { 
  3.       "started""2020-02-07T14:16:00Z"
  4.       "exited": 123 
  5.     }, 
  6.     { 
  7.       "started""2020-02-07T14:16:00Z"
  8.       "did""optional distinct user id"
  9.       "exited": 12, 
  10.       "errored": 3 
  11.     } 
  12.   ], 
  13.   "attrs": { 
  14.     "release""my-project-name@1.0.0"
  15.     "environment""development" 
  16.   } 

请注意,这必须包含在 envelope 中。所以完整的 envelope 看起来像这样:

  1. {} 
  2. {"type""sessions"
  3. {"aggregates": [...], "attrs": {...}} 

aggregates

attrs

崩溃与会话

会话(Session)和错误(error)事件是 Sentry 中两个不同的系统。 Session 更新可以在不发送错误事件的情况下完成,同样,可以在没有 session 更新的情况下发送 error。

这使 client 可以完全控制应如何执行 session 更新。激励因素是服务器可以在某些情况下自由拒绝 error 事件,在这种情况下记录 session 信息仍然很有趣。例如,如果项目对 error 事件应用了 rate limit,则它们的 session 数据仍然可以绕过此 rate limit 路由到项目。

但是,强烈建议在与 crash 事件相同的 envelope 中发送 session 更新,以防 session 转换到 crashed 状态。如果网络不可靠,这将确保事件同时到达系统。

重要客户端行为

这些是 client 必须遵守的重要规则:

属性不可变性

当前不允许 session 更改后续更新中的任何属性,包括 did、started 或其他属性。唯一允许更改的属性是 session 状态、持续时间或错误计数。如果一开始不知道 user,则应该延迟 session 开始,或者一旦知道 user 就应该重新启动 session。

会话计数/初始化

发送到系统的初始 session 更新必须将 init 设置为 true。这是必要的,因为服务器当前不会将总 session 计数作为优化进行重复数据删除。如果初始的 init: true flag 丢失,则 Sentry 可能无法正确摄取 session。

终止会话状态

Session 可以存在两种状态:进行中(progress)或终止(terminated)。终止的 session 不得接收进一步的更新。退出(exited)、崩溃(crashed)和异常(abnormal)都是终止状态。当 session 达到此状态时,client 不得再报告任何 session 更新或启动新 session。

鼓励 SDK 区分结束 session 的不同方式:

异常的 session 结束通常会在应用程序重新启动时被记录下来。

崩溃、异常与错误

Session 应该在遇到未处理的错误(例如应用程序完全崩溃)时转换为 crashed。对于无法完全崩溃的应用程序(例如网站),如果用户遇到错误对话框,则转换到 crashed 状态是可以接受的。对于我们为每个传入请求创建 session 的 server 环境,crashed 基本上就像状态代码 500 内部服务器错误。因此,如果在请求期间发生未处理的错误(unhandled error),会话应该 crashed。

Abnormal 是其命运未知的 session。例如,对于桌面应用程序,如果 session 被存储但未观察到应用程序退出但也没有崩溃, 则将 session 转换为 abnormal 是有意义的。在这些情况下,用户通过任务管理器强制关闭应用程序、机器断电或其他情况。可以通过将 session 持久保存到磁盘来存储 session。这个保存的文件可以在应用程序重启时检测到,以关闭 abnormal 的会话。

错误的 session 由大于零的 errors 计数器确定。 client 需要对被视为 error 的事件进行计数,并将计数与 session 更新一起发送。正常且错误计数大于零的 session 被视为错误 session。所有崩溃和异常 session 也始终被视为错误,但会从最终错误 session 计数中减去。

退出

Session 可以转换为 exited,这与 ok 状态完全相同, 但有一个区别:转换为 exited 的 session 的 session 持续时间是平均的。这让 Sentry 向您显示非崩溃 session 的持续时间。

警报

当 issue 影响到指定百分比的会话时触发警报。创建新的 issue alert 并选择 "When" 条件 An issue affects more than {X} percent of sessions(问题影响超过 {X}% 的会话)。在 Issue Alert Configuration 文档中查看更多问题警报选项。

SDK 注意事项

一般来说,SDK 可以使用两种独立的健康报告模式。一个是非常短暂的 session,另一个是用户参与的 session。

短时会话 (server-mode / request-mode)

这些 session 大致对应于服务器设置中的 HTTP 请求或 RPC 调用。

用户参与的会话 (user-mode / application-mode)

这些 session 更对应于实际的用户 session 或应用程序运行。这就是您在 Web 浏览器、移动世界、命令行应用程序或类似应用程序中会看到的内容。

从 API 的角度来看,这两种情况看起来很相似,但对于 SDK 的建议不同。

选择会话模式

虽然理论上可以在单个应用程序中使用两种会话模式,但建议 SDK 默认使用最适合语言生态系统主要用例的单一模式。这类似于某些 SDK 支持的全局 Hub 模式,并且可以以相同的方式使用。

当 SDK 配置为使用 user-mode 会话或全局 Hub 模式时,应在应用程序启动时启动单个会话,并应在应用程序的运行时持续存在。根据 SDK 内部结构,此单个 session 可以在所有应用程序线程和线程本地 Hub 之间共享。

使用 server-mode 会话时,不会启动应用程序范围的 session, 并且由集成或用户在收到请求时启动 session 并在返回响应时结束 session。

统一 API 的含义

SDK 应该遵循的统一 API 定义了 Hub、Scope 和 Client 的概念。

从概念上讲,session 是 Hub 的关注点,与 scope 不同,session 不应嵌套。当任何一种事件发生时,应该只有一个明确的 session 来跟踪错误计数。

在考虑通过 SDK 的事件流时,从静态 capture_event 函数,通过线程本地 Hub,进入 Client::capture_event(event, scope) 方法;根据 SDK 的内部实现细节,将 session 附加到 Scope 可能是有意义的, 这将使 Client 可以将 event 和 session 更新捆绑到单个 envelope 中以发送到 Sentry。

会话更新以及何时向上游发送更新

对于所有 SDK,只要在调用 apply_to_scope 的类似位置捕获数据以增加 error 计数, 或根据 distinct ID / user ID 更新 session,将自动更新当前 session。

SDK 通常应旨在减少向上游发送的 envelope 数量。

跟踪大量会话的 server-mode SDK 应考虑使用定期 session 刷新器(每 60 秒), 将会话预聚合到单个 session_aggregates envelope 项中。

User-Mode SDK 可能会选择在同一 envelope 中发送 session 更新以及捕获的事件。关闭 session 的最终 session 更新可以类似于 Server-Mode session 进行批处理。

在任何一种情况下,必须为 session 的第一次传输正确设置 init 标志, 并且 session 元数据(例如 distinct ID)在初始传输后必须是不可变的。

会话的预聚合

如果 SDK 配置为使用 server-mode session,则应在将 session 计数发送到 Sentry 之前对其进行分组和预聚合。每当 session 关闭(转换到 terminal 状态),并且之前没有向上游发送(其 init 标志为 true)时,它就有资格进行聚合,其执行方式如下:

公开 API

公开的最基本的 API 位于 hub 级别,可让您启动和停止 session 记录:

API:

Hub.start_session()

在当前 scope 上存储一个 session 并开始跟踪它。这通常会将一个全新的 session 附加到 scope,并隐式地结束任何已经存在的 session。

Hub.end_session()

结束 session,设置适当的 status 和 duration,并将其加入队列以发送到 Sentry。

Hub.start_auto_session_tracking() / Hub.stop_auto_session_tracking()

停止并重新激活自动 session 跟踪。

初始化选项:

auto_session_tracking

这通过集成 启用/禁用 自动 session 跟踪。

SDK 实现指南

在开始在 SDK 中实现此功能之前,请与团队联系。

我们通过从 SDK 发送 session 有效负载来跟踪 Sentry 中每个项目 release 的健康状况。 Session 有效负载提供诸如 session 持续时间以及是否存在错误/崩溃等数据。

SDK 以两种模式之一跟踪 session:

单个 session 是一般情况,非常适合通常只涉及单个用户的(相对短暂的)应用程序。例子:

当发送单个 session 不受欢迎或不切实际时,将使用 session 聚合。为了限制资源使用(即内存和网络),SDK 会跟踪有关最近发生的一批会话的摘要信息, 实际上不必处理代表构成聚合的各个 session 的 session 对象。此模式适用于运行任意长时间并为潜在的多个用户处理更大吞吐量的应用程序,例如 Web Server、后台 Job Worker 等。请注意,对于这些类型的应用程序,session 的更好定义与执行匹配单个 HTTP 请求或任务,而不是整个应用程序进程的单个执行。

在任何一种情况下,SDK 都应默认创建和报告 session,根据应用程序类型选择单独报告或作为聚合报告。

如果 SDK 可以检测到 session 聚合更好地为应用程序提供服务,则它不得报告应用程序范围的 session。应用程序范围的 session 可能仍会在 SDK 初始化期间创建,但必须中止并且永远不会发送到 Sentry。例如,在 Node.js SDK 中,如果应用程序使用提供的 requestHandler 集成,我们可以检测到它可能是一个 web server。

单个会话功能

配置

如果用户不想跟踪 session,他们应该能够禁用 session。

报告 session 和确定 Sentry 中项目的 Release Health 的先决条件,例如 release 应由 SDK 自动检测,例如通过查找 env 变量。

(也许,需要讨论)如果我的先决条件不能被检测到(例如,没有好的方法来确定 release 版本), 那么我们设置一些默认值,以便我们总是可以默认报告 session (取决于讨论,这可能不会是 SDK 代码的更改,但在 Relay 中,基本上删除了 session 有效负载中的硬要求)。

会话的生命周期

默认情况下,会话应该只为由 Sentry.init 初始化的全局 hub/client 启用,并默认为任何其他手动创建的 client 禁用。 Session 在 SDK 初始化时开始(理想情况下,当默认 client 绑定到全局 hub 时)并在以下情况之一发生时结束:显式调用 Hub.endSession() 方法;或程序无错误终止;或程序以未处理的异常终止;或程序以未处理的 promise rejection 而终止。

必须注意永远不要尝试为已经结束的 session 向 Sentry 发送新的 session 负载。例如,如果用户使用 Hub.endSession() 手动结束 session,则程序终止时不应有任何新的 session 更新。

会话属性和可变性

向 Sentry 发送会话

Session 最初在一定的(最初是硬编码的,配置越少越好)延迟(大约 1 到 30 秒 TBD)后发送, 然后在程序终止时更新持续时间、最终状态和错误计数。请注意,作为一种优化,short lived 程序不会向 Relay 发送 2 个 session 请求, 而只会向 Relay 发送最后一个带有状态和持续时间的请求。

会话聚合功能

配置

默认情况下应启用 session,session 在 web server 收到请求后立即启动,并在响应完全发回后立即结束。

会话的生命周期

 

Session 从不被跟踪或单独发送,相反,它们被聚合,聚合每 30 秒发送一次,最后一次当 web server 终止。作为对上述点的实现提示,当 "Client" 关闭或刷新时,相关联的 "Session Flusher" 也应被刷新并在传输被刷新/关闭之前提交当前聚合。确保这对于 Serverless 来说是合理的 — 我们不会使用 "request mode" 和 SessionFlusher,因为我们不能在 request-response 流之外进行任何工作。提供一种与现有 Node 框架(Express、Next.js、Koa)集成的简单方法。

 

来源:黑客下午茶内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯