Sentry(v20.12.1) K8S 云原生架构探索,JavaScript Enriching Events(丰富事件信息)

系列

  1. Sentry-Go SDK 中文实践指南
  2. 一块儿来刷 Sentry For Go 官方文档之 Enriching Events
  3. Snuba:Sentry 新的搜索基础设施(基于 ClickHouse 之上)
  4. Sentry 10 K8S 云原生架构探索,Vue App 1 分钟快速接入
  5. Sentry(v20.12.1) K8S云原生架构探索,玩转前/后端监控与事件日志大数据分析,高性能高可用+可扩展可伸缩集群部署
  6. Sentry(v20.12.1) K8S 云原生架构探索,Sentry JavaScript SDK 三种安装加载方式
  7. Sentry(v20.12.1) K8S 云原生架构探索,SENTRY FOR JAVASCRIPT SDK 配置详解
  8. Sentry(v20.12.1) K8S 云原生架构探索, SENTRY FOR JAVASCRIPT 手动捕获事件基本用法
  9. Sentry(v20.12.1) K8S 云原生架构探索,SENTRY FOR JAVASCRIPT Source Maps 详解
  10. Sentry(v20.12.1) K8S 云原生架构探索,SENTRY FOR JAVASCRIPT 故障排除
  11. Sentry(v20.12.1) K8S 云原生架构探索,1分钟上手 JavaScript 性能监控
  12. Sentry(v20.12.1) K8S 云原生架构探索,JavaScript 性能监控之管理 Transactions
  13. Sentry(v20.12.1) K8S 云原生架构探索,JavaScript 性能监控之采样 Transactions

Add Context

自定义上下文容许您将任意数据附加到事件。一般,此上下文在其生命周期中捕获的任何 issue 之间都是共享的。您没法搜索这些,但能够在 issue 页面上查看它们:javascript

Structured Context

附加自定义 data 的最佳实践是经过结构化上下文。上下文必须始终是一个 dictionary 或 map,它的值能够是任意的。使用 setContext 并给 context 一个惟一的名称:html

Sentry.setContext("character", {
  name: "Mighty Fighter",
  age: 19,
  attack_type: "melee",
});

Size Limitations

发送上下文时,请考虑有效负载大小限制。 Sentry 不建议在上下文中发送整个应用程序状态和大数据 blob。若是超过最大有效负载大小,Sentry 将响应 413 Payload Too Large,并拒绝该事件。使用 keepalive: true 时,该请求可能会永远保持待处理状态。前端

Passing Context Directly

从咱们的 JavaScript SDK 5.16.0 版本开始,能够将某些上下文数据直接提供给 captureExceptioncaptureMessage 调用。提供的数据将与当前范围内已经存储的数据合并,除非使用回调方法明确将其清除。java

此功能有三种不一样的变体形式:react

  1. 包含可更新属性的普通对象
  2. 咱们将从中提取属性的 Scope 实例
  3. 回调函数,它将接收当前 scope 做为参数并容许修改

咱们容许传递如下上下文 keys:tags, extra, contexts, user, level, fingerprintjson

Example Usages后端

Sentry.captureException(new Error("something went wrong"), {
  tags: {
    section: "articles",
  },
});

显式清除已经存储在 scope 中的内容:api

Sentry.captureException(new Error("clean as never"), scope => {
  scope.clear();
  scope.setTag("clean", "slate");
  return scope;
});

使用 Scope 实例传递数据(其属性仍将与全局 scope 合并):浏览器

const scope = new Sentry.Scope();
scope.setTag("section", "articles");
Sentry.captureException(new Error("something went wrong"), scope);

使用 Scope 实例传递数据并忽略全局配置的 Scope 属性:微信

const scope = new Sentry.Scope();
scope.setTag("section", "articles");
Sentry.captureException(new Error("something went wrong"), () => scope);

Clearing Context

Context 保留在当前 scope 内,所以在每一个操做(请求等)结束时将其清除。您还能够 push 和 pop 本身的做用域,以将上下文数据应用于特定的代码块或函数。

Sentry 支持两种不一样的 scope 来设置上下文:

  1. global scope,Sentry 在操做结束时不会丢弃
  2. 用户建立的 scope

这将在之后的全部事件中更改:

这将在之后的全部事件中更改:

仅针对在 withScope 回调中捕获的错误,将更改此状态,而后自动将其恢复为先前的值:

Sentry.withScope(function(scope) {
  scope.setUser(someUser);
  Sentry.captureException(error);
});

若是你想从做用域中(Scope)删除全局配置的数据,你能够调用:

Sentry.configureScope(scope => scope.clear());

Additional Data

除告终构化上下文(structured contexts),Sentry 还支持经过 setExtra 添加非结构化 "Additional Data"。Additional Data 已经废弃,而应使用结构化上下文,并应尽量避免使用。

Identify Users

用户包含一些关键信息,这些信息构成了 Sentry 中的惟一身份。每一个选项都是可选的,但必须存在一个选项才能使Sentry SDK 捕获用户:

id: 您的用户内部标识符。

username: 用户名。一般用做比内部 ID 更好的标签。

email: username 的替代或补充。Sentry 知道电子邮件地址,而且能够显示诸如 Gravatars 之类的内容并解锁消息传递功能。

ip_address: 用户的 IP 地址。若是用户未经身份验证,Sentry 将 IP 地址用做用户的惟一标识符。Sentry 将尝试从 HTTP 请求数据中提取此信息(若是有)。设置为 "{{auto}}",以使 Sentry 从 connection 中推断 IP 地址。

此外,您能够提供保留名称以外的任意 key/value 对,Sentry SDK 会将这些 key/value 对与 user 一块儿存储。

识别用户:

Sentry.setUser({ email: "john.doe@example.com" });

您还能够清除当前设置的 user:

Sentry.configureScope(scope => scope.setUser(null));

Set Transaction Name

当前 transaction 名称用于对 Performance 产品中的 transactions 进行分组,并用 failure 点注释错误事件。

transaction 名称能够引用当前的 Web 应用程序路由或正在执行的当前 task。 例如:

  • GET /api/{version}/users/
  • UserListView
  • myapp.tasks.renew_all_subscriptions

理想状况下,transaction 名称不包含诸如用户 ID 之类的变量值,但具备较低的基数,同时仍能够惟一地标识您所关心的代码。

咱们的许多框架集成已经设置了 transaction 名称。本身设定:

Sentry.configureScope(scope => scope.setTransactionName("UserListView"));

这将覆盖当前正在运行的 transaction 的名称。

Customize Tags

Tags 是既可索引又可搜索的 key/value 字符串对。Tags 具备强大的 UI 功能,例如过滤器(filters)和标签分布图(tag-distribution maps)。Tags 还能够帮助您快速访问相关事件,并查看一组事件的标签分布(tag distribution)。Tags 的常见用法包括主机名(hostname),平台版本(platform version)和用户语言(user language)。

咱们将自动为一个事件的全部 tags 创建索引,以及 Sentry 看到标签的频率和最后一次。咱们还将跟踪不一样 tags 的数量,并能够帮助您肯定各类 issues 的热点。

定义 tags 很容易,并将它们绑定到 current scope,确保 scope 内的全部将来事件都包含相同的标签:

Sentry.setTag("page_locale", "de-at");

某些 tags 由 Sentry 自动设置。强烈建议您不要覆盖这些 tags,而应使用本身的名称命名。

一旦开始发送标记的数据(tagged data),您将在 Sentry Web UI 中看到它:Project 页面侧栏中的过滤器(filters),在事件内进行汇总以及在聚合事件(aggregated event)的 tags 页面上。

Attachments

Sentry 能够经过在事件旁边存储其余文件(例如日志文件)做为附件来加强崩溃报告。 附件使崩溃中的文件不只能够上传到Sentry,并且能够持久保存以进行进一步调查。

Uploading Attachments

要添加 attachment,请建立一个事件处理器(event processor),该事件处理器以 multipart form data 请求的形式将文件上传到附件端点。这须要使用其 ID 将附件与事件相关联:

public attachmentUrlFromDsn(dsn: Dsn, eventId: string) {
  const { host, path, projectId, port, protocol, user } = dsn;
  return `${protocol}://${host}${port !== '' ? `:${port}` : ''}${
    path !== '' ? `/${path}` : ''
  }/api/${projectId}/events/${eventId}/attachments/?sentry_key=${user}&sentry_version=7&sentry_client=custom-javascript`;
}

Sentry.addGlobalEventProcessor((event: Event) => {
  try {
    const client = Sentry.getCurrentHub().getClient();
    const endpoint = attachmentUrlFromDsn(
      client.getDsn(),
      event.event_id
    );
    const formData = new FormData();
    formData.append(
      'my-attachment',
      new Blob([JSON.stringify({ logEntries: ["my log"] })], {
        type: 'application/json',
      }),
      'logs.json'
    );
    fetch(endpoint, {
      method: 'POST',
      body: formData,
    }).catch((ex) => {
      // we have to catch this otherwise it throws an infinite loop in Sentry
      console.error(ex);
    });
    return event;
  } catch (ex) {
    console.error(ex);
  }
});

Sentry 每一个事件最多容许 100MB 的附件,包括崩溃报告文件(若是适用)。超过此大小的上传将被 HTTP 错误 413 Payload Too Large 拒绝,而且数据将当即被丢弃。要添加更大或更多的文件,请考虑使用辅助存储选项。

附件存留 30 天;若是超出了配额中包含的总存储空间,则不会存储附件。您能够随时删除附件或其包含的事件。删除附件不会影响您的配额(quota) - Sentry 存储附件后当即将其计入您的配额。

Access to Attachments

要限制对附件的访问,请导航到您组织的 General Settings,而后选择 Attachments Access 下拉菜单来设置适当的访问权限 - 您的组织的任何成员、组织账单全部者、成员(member)、管理员(admin)、经理(manager)或全部者(owner)。

默认状况下,启用存储后,将授予全部成员访问权限。若是成员无权访问该项目,则没法下载附件。该按钮将在 Sentry 中显示为灰色。成员只能查看附件已存储。

Viewing Attachments

附件显示在所显示事件的 Issue Details 页面的底部。

或者,附件也会显示在 Issue Details 页面上的 Attachments 选项卡中,您能够在其中查看附件的类型以及相关事件。单击 Event ID,以打开该特定事件的 Issue Details 信息。

Sentry 使用 breadcrumbs 建立事件发生以前的事件线索。这些事件与传统日志很是类似,可是能够记录更丰富的结构化数据。

此页面概述了手动 breadcrumb 录制(recording)和自定义(customization)。了解有关 Issue Details 页面上显示的信息的更多信息,以及如何过滤 breadcrumbs 以快速解决 Using Breadcrumbs 中的问题。

Manual Breadcrumbs

每当发生有趣的事情时,您均可以手动添加 breadcrumbs。例如,若是用户进行身份验证或发生其余状态更改,则能够手动记录一个面包屑。

Sentry.addBreadcrumb({
  category: "auth",
  message: "Authenticated user " + user.email,
  level: Sentry.Severity.Info,
});

可用的 breadcrumb keys 包括 type, category, message, level, timestamp(许多SDK会自动为您设置)和 data,在此处能够放置您但愿包含面包屑的任何其余信息。使用这六个 key 之外的 key 不会致使错误,可是会致使在由 Sentry 处理事件时删除数据。

Automatic Breadcrumbs

SDK 及其相关的集成将自动记录许多类型的 breadcrumbs。例如,浏览器 JavaScript SDK 将自动记录全部 location 更改。

Customize Breadcrumbs

SDK 容许您经过 before_breadcrumb 挂钩自定义 breadcrumbs。此挂钩传递了已经组装好的 breadcrumb,而且在某些SDK 中传递了可选 hint。该函数能够修改 breadcrumb 或经过返回 null 决定彻底放弃它:

Sentry.init({
  // ...

  beforeBreadcrumb(breadcrumb, hint) {
    return breadcrumb.category === "ui.click" ? null : breadcrumb;
  },
});

User Feedback

当用户遇到错误时,Sentry 能够收集其余反馈。当您一般能够呈现简单的错误页面(经典的500.html)时,这种类型的反馈很是有用。

要收集 feedback,请使用可嵌入的 JavaScript widget,该小部件将请求并收集用户的姓名,电子邮件地址以及发生的状况的描述。提供反馈后,Sentry 会将反馈与原始事件配对,从而使您对问题有更多看法。

下面的屏幕截图提供了 User Feedback 小部件的示例,尽管您的个性化可能因您的自定义而有所不一样:

Collecting Feedback

要集成 widget,您须要运行 2.1 版或更高版本的 JavaScript SDK。该 widget 将使用您的公共 DSN 进行身份验证,而后传递在后端生成的 Event ID。

若是您但愿使用 widget 的替代产品,或者没有 JavaScript 前端,则可使用 User Feedback API。

确保您有可用的 JavaScript SDK:

<script
  src="https://browser.sentry-cdn.com/6.0.1/bundle.min.js"
  integrity="sha384-z2Rmh4rfoBkdxaENH00ggKo5Bx8b2SJs+MWQrjWx4DbET95Zr2mxV2Vet3CCj4iW"
  crossorigin="anonymous"
></script>

若是您使用的是 ReactAngular 之类的框架,则收集用户反馈的最佳位置是您的错误处理组件。(有关示例,请参阅特定于平台的文档。)若是您不使用框架,则能够在发送事件以前使用 beforeSend 收集反馈:

<script>
  Sentry.init({
    dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
    beforeSend(event, hint) {
      // Check if it is an exception, and if so, show the report dialog
      if (event.exception) {
        Sentry.showReportDialog({ eventId: event.event_id });
      }
      return event;
    },
  });
</script>

Customizing the Widget

您能够根据组织的须要自定义窗口小部件,尤为是为了本地化目的。全部选项均可以经过 showReportDialog 调用传递。

Sentry 的自动语言检测 override(例如 lang=de

Param Default
eventId 手动设置事件的ID。
dsn 手动设置要报告的dsn。
user 手动设置 user data [具备下面列出的 key 的对象]。
user.email 用户的电子邮件地址。
user.name 用户名。
lang [automatic] – 覆盖 Sentry 的语言代码
title 看来咱们遇到了问题。
subtitle 咱们的团队已收到通知。
subtitle2 若是您想提供帮助,请告诉咱们下面发生的状况。 – 在小屏幕分辨率下不可见
labelName 名称
labelEmail Email
labelComments 发生了什么?
labelClose 关闭
labelSubmit 提交
errorGeneric 提交报告时发生未知错误。 请再试一次。
errorFormEntry 有些字段无效。请更正错误,而后重试。
successMessage 您的反馈已发送。 谢谢!
onLoad n/a

Scopes and Hubs

捕获事件并将其发送到 Sentry 后,SDK 会将事件数据与当前做用域(scope)中的额外信息合并。SDK 一般会在框架集成中为您自动管理 scopes,而您无需考虑它们。可是,您应该知道什么是 scope 以及如何利用它来发挥本身的优点。

What's a Scope, what's a Hub

您能够将 hub 视为咱们的 SDK 用于将事件路由到 Sentry 的中心点。调用 init() 时,将建立一个 hub,并在其上建立一个 client 和一个 blank scope。而后,该 hub 与当前线程相关联,并将在内部保存一堆 scopes。

scope 将包含应与事件一块儿发送的有用信息。例如,contexts 或 breadcrumbs 存储在 scope 上。当推入做用域时,它将继承父做用域的全部数据,而且当其弹出时,全部修改都将还原。

默认的 SDK 集成将智能地推送和弹出做用域。例如,Web 框架集成将在您的路由(routes)或控制器(controllers)周围建立和销毁做用域。

How do the Scope and Hub Work

当您开始使用 SDK 时,将自动为您建立一个 scope 和 hub。hub 不太可能直接与之交互,除非您正在编写集成或但愿建立或销毁做用域。另外一方面,做用域更多地面向用户。您能够随时调用 configure-scope 修改存储在 scope 上的数据。例如,这用于 modify the context。

当您在内部调用诸如 capture_event 之类的全局函数时,Sentry 会发现当前的 hub 并要求其捕获事件。而后,hub 将在内部将事件与最高 scope 的数据合并。

Configuring the Scope

使用范围时,最有用的操做是 configure-scope 函数。它可用于从新配置当前 scope。例如,这可用于添加自定义标签或向 sentry 告知当前已经过身份验证的用户。

Sentry.configureScope(function(scope) {
  scope.setTag("my-tag", "my value");
  scope.setUser({
    id: 42,
    email: "john.doe@example.com",
  });
});

这也能够在注销时取消用户设置时应用:

Sentry.configureScope(scope => scope.setUser(null));

Local Scopes

咱们还支持一键式推送和配置 scope。一般将其称为 with-scopepush-scope,若是您只想发送一个特定事件的数据,这也很是有用。在下面的示例中,咱们使用该函数将 leveltag 附加到仅一个特定错误:

Sentry.withScope(function(scope) {
  scope.setTag("my-tag", "my value");
  scope.setLevel("warning");
  // will be tagged with my-tag="my value"
  Sentry.captureException(new Error("my error"));
});

// will not be tagged with my-tag
Sentry.captureException(new Error("my other error"));

尽管此示例看起来与 configure-scope 类似,但有很大的不一样,从某种意义上说 configure-scope 实际上会更改当前的 active scope,全部对 configure-scope 的后续调用都将保留所作的更改。

另外一方面,使用 with-scope 会建立当前做用域的副本,并保持隔离状态,直到函数调用完成。所以,您能够在此处不想设置其余位置的上下文信息,也能够经过在做用域上调用 clear 来根本不附加任何上下文信息,而“全局”范围保持不变。

中文文档陆续同步到:

我是为少。
微信:uuhells123。
公众号:黑客下午茶。
谢谢点赞支持👍👍👍!
相关文章
相关标签/搜索