前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Sentry-Go SDK 中文实践指南

Sentry-Go SDK 中文实践指南

作者头像
为少
发布2021-05-27 19:00:05
3.6K0
发布2021-05-27 19:00:05
举报
文章被收录于专栏:黑客下午茶黑客下午茶

介绍

Sentry-Go SDK 中文实践指南(http://sentry-go.hacker-linner.com/)

安装

Sentry 通过在应用程序的运行时中使用 SDK 捕获数据。

使用 Go Modules 时,无需安装任何软件即可开始将 Sentry 与 Go 程序一起使用。导入 SDK,然后当您下次构建程序时,go tool 会自动下载最新版本的 SDK。

代码语言:javascript
复制
import (
	"github.com/getsentry/sentry-go"
)

不使用或没有 Go Modules 时,要使用最新版本的SDK,请运行:

代码语言:javascript
复制
go get github.com/getsentry/sentry-go

有关如何管理依赖项的更多信息,请参阅有关 Modules 的 Go 文档。

配置

配置应在应用程序的生命周期中尽早进行。

代码语言:javascript
复制
package main

import (
	"log"
	"time"

	"github.com/getsentry/sentry-go"
)

func main() {
	err := sentry.Init(sentry.ClientOptions{
    // 在此处设置您的 DSN 或设置 SENTRY_DSN 环境变量。
		Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
    // 可以在这里设置 environment 和 release,
    // 也可以设置 SENTRY_ENVIRONMENT 和 SENTRY_RELEASE 环境变量。
		Environment: "",
		Release:     "",
    // 允许打印 SDK 调试消息。
    // 入门或尝试解决某事时很有用。
		Debug: true,
	})
	if err != nil {
		log.Fatalf("sentry.Init: %s", err)
	}
    // 在程序终止之前刷新缓冲事件。
    // 将超时设置为程序能够等待的最大持续时间。
	defer sentry.Flush(2 * time.Second)
}

验证

此代码段包含一个故意的错误,因此您可以在设置后立即测试一切是否正常:

代码语言:javascript
复制
package main

import (
	"log"
	"time"

	"github.com/getsentry/sentry-go"
)

func main() {
	err := sentry.Init(sentry.ClientOptions{
		Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
	})
	if err != nil {
		log.Fatalf("sentry.Init: %s", err)
	}
	defer sentry.Flush(2 * time.Second)

	sentry.CaptureMessage("It works!")
}

要查看和解决记录的错误,请登录 sentry.io(或者你私有部署的 sentry) 并打开您的项目。单击错误标题将打开一个页面,您可以在其中查看详细信息并将其标记为已解决。

处理 Panics

在 Go SDK 中捕获未处理的紧急情况(panics)的方法是通过 Recover 方法。它可以直接通过 defer 关键字使用,也可以作为实现的一部分使用。

用法

如下所示,直接使用 Sentry 时,它将从紧急状态中恢复,并根据收到的输入类型在内部决定是使用 CaptureException 还是 CaptureMessage 方法。由于出现字符串 panic 并不常见,建议在 SDK 初始化期间使用 AttachStacktrace 选项,该选项还将尝试为消息提供有用的堆栈跟踪。

代码语言:javascript
复制
func() {
	defer sentry.Recover()
	// do all of the scary things here(在这里做所有可怕的事情)^_^
}()

默认情况下,Sentry Go SDK 使用异步传输,在下面的代码示例中,需要使用 sentry.Flush 方法显式等待事件传递完成。这是必要的,因为否则程序将不会等待异步 HTTP 调用返回响应,并在到达 main 函数末尾时立即退出进程。在正在运行的 goroutine 中或使用 HTTPSyncTransport(在 Transports 部分中可以了解到)时,不需要它。

如果要控制单个 defer 调用的传递,或在捕获之前执行其他操作,则必须直接在 Hub 实例上使用 Recovery 方法,因为它可以接受 err 本身。

代码语言:javascript
复制
func() {
	defer func() {
		err := recover()

		if err != nil {
			sentry.CurrentHub().Recover(err)
			sentry.Flush(time.Second * 5)
		}
	}()

	// do all of the scary things here
}()

使用 Context

除了常规的 Recover 方法外,还有一种可用于紧急情况的方法,即 RecoverWithContext。它允许传递 context.Context 的实例作为第一个参数。这为我们提供了两个附加功能。

第一个是从上下文(context)提取 Hub 实例并使用它而不是全局实例 —— 这用于每个 http/server 包集成,因为它允许执行上下文分离。您可以在我们的 http 集成源代码中看到它的作用。

第二个功能是对 beforeSend 方法内部的 context.Context 本身的访问,可用于提取有关在 panic 下发生的情况的任何其他信息:

代码语言:javascript
复制
type contextKey int
const SomeContextKey = contextKey(1)

func main() {
	sentrySyncTransport := sentry.NewHTTPSyncTransport()
	sentrySyncTransport.Timeout = time.Second * 3

	sentry.Init(sentry.ClientOptions{
		Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
		Transport: sentrySyncTransport,
		BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
			if hint.Context != nil {
        // hint.Context.Value(SomeContextKey) 会给您存储的字符串,现在可以将其附加到事件中
			}
			return event
		},
	})

	ctx := context.WithValue(context.Background(), SomeContextKey, "some details about your panic")

	func() {
		defer sentry.RecoverWithContext(ctx)
		// do all of the scary things here
	}()
}

并发

并发的 Go 程序使用 goroutines(一种由 Go 运行时管理的轻量级线程形式)。由于 goroutine 同时运行,因此每个 goroutine 必须在本地跟踪其与 Sentry 相关的数据。否则,数据争用(data races)会在您的程序中引入细微的错误,其后果从明显的变化到意外的崩溃,甚至更糟的是,意外地将 Scope 中存储的数据混合在一起。在 Scopes and Hubs 部分中对此有更多的了解。

处理这个问题最简单的方法是为您启动的每个 goroutine 创建一个新的 Hub,但是这需要您重新绑定当前 Client 并自己处理 Scope。这就是为什么我们提供了一个名为 Clone 的辅助方法。它负责创建集线器、克隆现有 Scope 并将其与 Client 一起重新分配给新创建的实例。

克隆后,Hub 将完全隔离,可以在并发调用中安全使用。但是,不应使用在全局上公开的方法,而应在 Hub 上直接调用它们。

这是两个示例:

  • 建议对 Hub 进行安全的确定性调用
代码语言:javascript
复制
// Example of __CORRECT__ use of scopes inside a Goroutine
// 正确使用

go func(localHub *sentry.Hub) {
	// as goroutine argument
	localHub.ConfigureScope(func(scope *sentry.Scope) {
		scope.SetTag("secretTag", "go#1")
	})
	localHub.CaptureMessage("Hello from Goroutine! #1")
}(sentry.CurrentHub().Clone())

go func() {
	// or created locally
	localHub := sentry.CurrentHub().Clone()
	localHub.ConfigureScope(func(scope *sentry.Scope) {
		scope.SetTag("secretTag", "go#2")
	})
	localHub.CaptureMessage("Hello from Goroutine! #2")
}()
  • 阻止在 Hub 上进行的不确定性调用,该调用会泄漏线程之间的信息
代码语言:javascript
复制
// Example of __INCORRECT__ use of scopes inside a Goroutine - DON'T USE IT!
// 不正确使用

go func() {
	sentry.ConfigureScope(func(scope *sentry.Scope) {
		scope.SetTag("secretTag", "go#1")
	})
	sentry.CaptureMessage("Hello from Goroutine! #1")
}()

go func() {
	sentry.ConfigureScope(func(scope *sentry.Scope) {
		scope.SetTag("secretTag", "go#2")
	})
	sentry.CaptureMessage("Hello from Goroutine! #2")
}()

// 此时,两个事件都可以具有 `go#1` 标签或 `go#2` 标签。我们永远不会知道。

配置项

  • 基本选项

详细了解如何配置 SDK。这些选项是在首次初始化 SDK 时设置的,并作为对象传递给 init()

  • Releases & Health

了解如何配置您的 SDK 以告知 Sentry 您的版本。

  • Transports

通过 Transports,您可以更改将事件传递到 Sentry 的方式。

  • Environments

了解如何配置您的 SDK,以告知 Sentry 您的环境。

  • 过滤和采样事件

详细了解如何配置您的 SDK 以过滤和采样报告给 Sentry 的事件。

  • Shutdown and Draining

如果应用程序意外关闭,请详细了解我们的 SDK 的默认行为。

基本选项

可以使用多种选项对 SDK 进行配置。这些选项在很大程度上在 SDK 中进行了标准化,但是为了更好地适应平台特性,还存在一些差异。选项在 SDK 首次初始化时设置。

选项作为一个 sentry.ClientOptions 的实例传递给 Init() 方法:

代码语言:javascript
复制
sentry.Init(sentry.ClientOptions{
	Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
	Debug: true,
})
代码语言:javascript
复制
// ClientOptions 用来配置 SDK 客户端
type ClientOptions struct {
  // 要使用的 DSN。如果未设置 DSN,则实际上将禁用客户端。
	Dsn string
  // 在调试模式下,调试信息会打印到 stdout,以帮助您了解 sentry 在做什么。
	Debug bool
  // 配置 SDK 是否应生成堆栈跟踪并将其附加到纯捕获消息调用。
	AttachStacktrace bool
  // 事件提交的采样率(0.0-1.0,默认为 1.0)
	SampleRate float64
  // 用于与事件消息进行匹配的正则表达式字符串列表,如果适用,
  // 则捕获错误类型和值。如果找到匹配项,则将删除整个事件。
	IgnoreErrors []string
  // 发送回调之前。
	BeforeSend func(event *Event, hint *EventHint) *Event
  // 在面包屑之前添加回调。
	BeforeBreadcrumb func(breadcrumb *Breadcrumb, hint *BreadcrumbHint) *Breadcrumb
  // 要在当前客户端上安装的集成,接收默认集成
	Integrations func([]Integration) []Integration
  // io.Writer 实现应与 `Debug` 模式一起使用
	DebugWriter io.Writer
  // transport 使用
  // 这是实现 `Transport` 接口的结构的一个实例。
  // 默认来自 `transport.go` 的 `httpTransport`
	Transport Transport
  // The server name to be reported.
  // 要报告的服务器名称。
	ServerName string
  // 与事件一起发送的版本。
	Release string
  // 与事件一起发送的 dist。
	Dist string
  // 与事件一起发送的环境。
	Environment string
  // 面包屑的最大数量。
	MaxBreadcrumbs int
  // 指向 `http.Client` 的可选指针,它将与默认的 HTTPTransport 一起使用。
  // 使用您自己的客户端将忽略 HTTPTransport,HTTPProxy,HTTPSProxy 和 CaCerts 选项。
	HTTPClient *http.Client
  // 指向 `http.Transport` 的可选指针,它将与默认的 HTTPTransport 一起使用。
  // 使用您自己的 transport 将使 HTTPProxy,HTTPSProxy 和 CaCerts 选项被忽略。
	HTTPTransport *http.Transport
  // 要使用的可选 HTTP 代理。
  // 这将默认为 `http_proxy` 环境变量。
  // 或 `https_proxy`(如果存在的话)。
	HTTPProxy string
  // 要使用的可选 HTTPS 代理。
  // 这将默认为 `HTTPS_PROXY` 环境变量
  // 或 `http_proxy`(如果存在的话)。
	HTTPSProxy string
  // 要使用的可选 CaCert。
  // 默认为 `gocertifi.CACerts()`。
	CaCerts *x509.CertPool
}
提供 SSL 证书

默认情况下,TLS 使用主机的根 CA 设置。如果您没有 ca-certificates(这应该是解决丢失证书问题的首选方法), 而要使用 gocertifi,则可以提供预加载的证书文件作为 sentry.Init 调用的选项之一:

代码语言:javascript
复制
package main

import (
	"log"

	"github.com/certifi/gocertifi"
	"github.com/getsentry/sentry-go"
)

sentryClientOptions := sentry.ClientOptions{
	Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
}

rootCAs, err := gocertifi.CACerts()
if err != nil {
	log.Println("Could not load CA Certificates: %v\n", err)
} else {
	sentryClientOptions.CaCerts = rootCAs
}

sentry.Init(sentryClientOptions)
删除默认集成

sentry-go SDK 几乎没有内置的集成,这些集成可以使用其他信息增强事件或以一种或另一种方式管理事件。

如果您想了解更多有关它们的信息,请直接查看源代码。

但是,在某些情况下,您可能需要禁用其中一些功能。为此,您可以使用 Integrations 配置选项并过滤不需要的集成。例如:

代码语言:javascript
复制
sentry.Init(sentry.ClientOptions{
	Integrations: func(integrations []sentry.Integration) []sentry.Integration {
		var filteredIntegrations []sentry.Integration
		for _, integration := range integrations {
			if integration.Name() == "ContextifyFrames" {
				continue
			}
			filteredIntegrations = append(filteredIntegrations, integration)
		}
		return filteredIntegrations
	},
})

Releases & Health

发行版是部署到环境中的代码版本。当您向 Sentry 提供有关发行版的信息时,您可以:

  • 确定新版本中引入的问题和回归
  • 预测哪个提交引起了问题,谁可能负责
  • 通过在提交消息中包含问题编号来解决问题
  • 部署代码后接收电子邮件通知
绑定版本

配置客户端 SDK 时,请包含发行 ID(通常称为“版本”)。该 ID 通常是 git SHA 或自定义版本号。

发行版名称不能:

  • 包含换行符或空格
  • 使用正斜杠(“/”),反斜杠(“\”),句点(“.”)或双句号(“..”)
  • 超过200个字符

每个组织的版本都是全球性的;在它们前面加上特定项目的前缀,以便于区分。

代码语言:javascript
复制
sentry.Init(sentry.ClientOptions{
    Release: "my-project-name@2.3.12",
})

如何使版本对代码可用由您决定。例如,您可以使用在构建过程中设置的环境变量。

这将用发布值标记每个事件。我们建议您在部署 Sentry 之前告诉它一个新版本,因为这将解锁更多的特性,如我们的文档中所讨论的。但如果不这样做,Sentry 将在第一次看到带有该 release ID 的事件时自动在系统中创建一个 release 实体。

配置了 SDK 之后,您可以安装存储库集成,或者手动为 Sentry 提供您自己的提交元数据。请阅读我们关于版本的文档, 以获得关于集成、关联提交以及在部署版本时告知 Sentry 的更多信息。

Transports

通过 Transports,您可以更改将事件传递到 Sentry 的方式。

Sentry Go SDK 本身提供了两个内置传输。HTTPTransport,它是非阻塞的,默认情况下使用。和 HTTPSyncTransport 处于阻塞状态。每种传输方式都提供略有不同的配置选项。

用法

要配置传输,请提供一个 sentry.Transport 实例到 ClientOptions

代码语言:javascript
复制
package main

import (
	"time"

	"github.com/getsentry/sentry-go"
)

func main() {
	sentrySyncTransport := sentry.NewHTTPSyncTransport()
	sentrySyncTransport.Timeout = time.Second * 3

	sentry.Init(sentry.ClientOptions{
		Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
		Transport: sentrySyncTransport,
	})
}

每种运输方式都提供自己的工厂函数。NewHTTPTransportNewHTTPSyncTransport

选项
HTTPTransport
代码语言:javascript
复制
// HTTPTransport 是由 `Client` 使用的 `Transport` 接口的默认实现。
type HTTPTransport struct {
  // 传输缓冲区的大小。默认为30。
	BufferSize int
  // HTTP 客户端请求超时。默认为30秒。
	Timeout time.Duration
}
HTTPSyncTransport
代码语言:javascript
复制
// HTTPSyncTransport 是 `Transport` 接口的实现,它在每个捕获的事件之后都会阻塞。
type HTTPSyncTransport struct {
  // HTTP 客户端请求超时。默认为30秒。
	Timeout time.Duration
}

Environments

Sentry 在收到带有环境标签的事件时自动创建环境。环境是区分大小写的。环境名称不能包含换行、空格或斜杠,不能是字符串“None”,或超过64个字符。您不能删除环境,但可以隐藏它们。

代码语言:javascript
复制
sentry.Init(sentry.ClientOptions{
	Environment: "production",
})

在 sentry.io 的问题详细信息页面中,环境帮助您更好地过滤问题、版本和用户反馈。您可以在我们的文档中了解更多关于使用环境的信息。

过滤和采样事件

将 Sentry 添加到您的应用程序将为您提供有关错误和性能的大量非常有价值的信息,而这些信息是您以前无法获得的。而且很多信息都是好的-只要是正确的信息,而且数量合理。

Sentry SDK 有几个配置选项来帮助您控制这一点,允许您过滤掉您不想要的事件,并从您想要的事件中选取一个代表性的示例。

注意:Sentry UI 还提供了使用入站筛选器筛选事件的方法。不过,我们建议您在客户端级别进行过滤,因为它可以消除发送您实际上不需要的事件的开销。

过滤错误事件

配置您的 SDK,通过使用 beforeSend 回调方法并配置、启用或禁用集成来过滤错误事件。

Using beforeSend

所有的 Sentry SDK 都支持 beforeSend 回调方法。 beforeSend 在事件被发送到服务器之前被立即调用,因此它是您可以编辑其数据的最终位置。它将事件对象作为参数接收,因此您可以使用该参数根据定制逻辑和事件上可用的数据修改事件数据或完全删除它(通过返回 null)。

在 Go 中,函数可以用来修改事件或返回一个全新的事件。如果返回 nil, SDK 将丢弃该事件。

代码语言:javascript
复制
sentry.Init(sentry.ClientOptions{
	BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
		// Modify the event here
		event.User.Email = "" // Don't send user's email address
		return event
	},
})

还要注意,可以过滤面包屑,这在面包屑文档中已经讨论过了。

Event Hints

before-send 回调同时传递 event 和第二个参数 hint,它包含一个或多个 hint。

通常,一个 hint 保存原始异常,以便可以提取其他数据或影响分组。在本例中,如果捕获到某种类型的异常,则指纹被强制设置为公共值:

代码语言:javascript
复制
sentry.Init(sentry.ClientOptions{
	BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
		if ex, ok := hint.OriginalException.(DatabaseConnectionError); ok {
			event.Fingerprint = []string{"database-connection-error"}
		}

		return event
	},
})

有关可用提示的信息,请参见EventHint实现。

当 SDK 为传输创建一个事件或breadcrumb时,该传输通常是从某种源对象创建的。例如,错误事件通常是由日志记录或异常实例创建的。为了更好地定制,SDK 将这些对象发送到特定的回调(beforeSendbeforeBreadcrumb 或 SDK 中的事件处理器系统)。

使用 Hints

有两个地方提供 Hints:

  1. beforeSend / beforeBreadcrumb
  2. eventProcessors

事件和 breadcrumb hints 是包含各种用于组合事件或 breadcrumb 的信息的对象。通常, hints 保存原始异常,以便可以提取其他数据或影响分组。

用于事件,如 event_idoriginalExceptionsyntheticException(内部用于生成更干净的堆栈跟踪),以及附加的任何其他任意 data

对于面包屑,hints 的使用依赖于实现。对于 XHR 请求,hint 包含 XHR 对象本身;对于用户交互,hint 包含 DOM 元素和事件名等等。

在本例中,如果捕获到某种类型的异常,则指纹被强制设置为公共值:

Hints for Events

originalException

引起 Sentry SDK 创建事件的原始异常。这对于更改 Sentry SDK 分组事件的方式或提取其他信息很有用。

syntheticException

当引发字符串或非错误对象时,Sentry 会创建一个合成异常,这样您就可以获得一个基本的堆栈跟踪。这个异常被存储在这里以供进一步的数据提取。

Hints for Breadcrumbs

event

对于从浏览器事件创建的 breadcrumb, Sentry SDK 通常将事件作为 hint 提供给 breadcrumb。例如,这可以用于从目标 DOM 元素提取数据到 breadcrumb。

level / input

对于从控制台日志截取创建的面包屑。这将保留原始控制台日志级别和日志功能的原始输入数据。

response / input

用于从 HTTP 请求创建的面包屑。它保存响应对象(来自 fetch API )和 fetch 函数的输入参数。

request / response / event

用于从 HTTP 请求创建的面包屑。它包含请求和响应对象(来自节点 HTTP API )以及节点事件( responseerror )。

xhr

对于通过旧版 XMLHttpRequest API 通过 HTTP 请求创建的面包屑。这将保留原始的 xhr 对象。

采样错误事件

要向 Sentry 发送一个具有代表性的错误样本, 请将 SDK 配置中的 SampleRate 选项设置为0(发送了 0% 的错误)和1(发送了 100% 的错误)之间的数字。这是一个静态速率,它同样适用于所有错误。例如,对 25% 的错误进行抽样:

注意:误差采样率不是动态的;更改它需要重新部署。此外,设置SDK示例速率会限制对事件源的可见性。为您的项目设置速率限制(仅在容量大时降低事件)可能更适合您的需要。

Shutdown and Draining

大多数 SDK 的默认行为是在后台通过网络异步发送事件。这意味着如果应用程序意外关闭,可能会丢失一些事件。SDK 提供了处理这种情况的机制。

为避免程序终止时意外删除事件,请安排 sentry.Flush 进行调用,通常使用 defer

如果您使用多个客户端,请安排每个相应的客户端刷新。

Flush 会一直等到任何缓冲事件发送到 Sentry 服务器,直到最多阻塞给定的超时时间。如果超时,则返回 false。在这种情况下,某些事件可能尚未发送。

代码语言:javascript
复制
func main() {
	// err := sentry.Init(...)
	defer sentry.Flush(2 * time.Second)

	sentry.CaptureMessage("my message")
}

Serverless

Source Context

sentry-go SDK 附带了对 Serverless 解决方案的支持。但是,为了正确使用源上下文,您需要将源代码与二进制文件本身捆绑在一起。

例如,当使用 AWS Lambda 并给出这个树结构时:

代码语言:javascript
复制
.
├── bin
│   └── upload-image
│   └── process-image
│   └── create-thumbnails
├── functions
│   └── upload-image
│       └── main.go
│   └── process-image
│       └── main.go
│   └── create-thumbnails
│       └── main.go
├── helper
│   ├── foo.go
│   └── bar.go
├── util
│   ├── baz.go
│   └── qux.go

您可以使用以下命令构建二进制文件之一并将其与必要的源文件捆绑在一起:

代码语言:javascript
复制
GOOS=linux go build -o bin/upload-image functions/upload-image/main.go && zip -r handler.zip bin/upload-image functions/upload-image/ helper/ util/

唯一的要求是您在已部署的计算机上找到源代码。SDK 会自动完成其他所有操作。

Events Delivery

大多数(如果不是全部)无服务器解决方案在关闭进程之前不会等待网络响应。因此,我们需要确保将事件传递给 Sentry 的服务器。

可以使用 sentry.Flush 方法或通过将传输交换到 HTTPSyncTransport 来实现双重目的。

用法

Sentry 的 SDK 挂接到您的运行时环境中,并自动报告错误,异常和拒绝。

关键术语:

  • 事件是向 Sentry 发送数据的一个实例。通常,此数据是错误或异常。
  • 一个问题是一组相似的事件。
  • 事件的报告称为捕获。当一个事件被捕获,它被发送到 Sentry。

捕获的最常见形式是捕获错误。可以捕获为错误的内容因平台而异。通常,如果您有看起来像异常的东西,则可以将其捕获。对于某些 SDK,您还可以省略 capture_exception 的参数,Sentry 将尝试捕获当前异常。手动将错误或消息报告给 Sentry 也很有用。

除了捕获之外,您还可以记录导致事件的面包屑。面包屑与事件不同:它们不会在 Sentry 中创建事件,但将被缓冲直到发送下一个事件。在我们的面包屑文档中了解有关面包屑的更多信息。

捕获错误

要在 Go 中捕获事件,可以将实现 error 接口的任何结构传递给 CaptureException()。如果使用第三方库而不是原生 errors 包,我们将尽力提取堆栈跟踪。

SDK完全兼容(但不限于):

  • github.com/pkg/errors
  • github.com/go-errors/errors
  • github.com/pingcap/errors

如果有无法立即使用的错误包,请告诉我们!

代码语言:javascript
复制
f, err := os.Open("filename.ext")
if err != nil {
	sentry.CaptureException(err)
}

捕获消息

另一个常见的操作是捕获一条纯消息。消息是应该发送给 Sentry 的文本信息。通常情况下,消息不会被发出,但是对于某些团队来说,它们可能是有用的。

代码语言:javascript
复制
sentry.CaptureMessage("Something went wrong")

默认情况下,Sentry 的 Go SDK 使用异步传输。这意味着对 CaptureExceptionCaptureEventCaptureMessage 的调用无需等待网络操作即可返回。而是在后台 goroutine 中缓冲事件并通过网络发送事件。调用 sentry.Flush 以等待事件传递,然后程序终止。您可以使用其他传输方式(例如 HTTPSyncTransport)来更改默认行为。在 Transports 部分中有更多详细信息。

设置级别

级别 — 类似于日志级别 — 通常是基于集成默认添加的。您还可以在事件中覆盖它。

代码语言:javascript
复制
sentry.ConfigureScope(func(scope *sentry.Scope) {
	scope.SetLevel(sentry.LevelWarning)
})

迁移指南

如何从 raven-go 转到 sentry-go

安装

raven-go

代码语言:javascript
复制
go get github.com/getsentry/raven-go

sentry-go

代码语言:javascript
复制
go get github.com/getsentry/sentry-go

配置

raven-go

代码语言:javascript
复制
import "github.com/getsentry/raven-go"

func main() {
	raven.SetDSN("https://examplePublicKey@o0.ingest.sentry.io/0")
}

sentry-go

代码语言:javascript
复制
import (
	"fmt"
	"github.com/getsentry/sentry-go"
)

func main() {
	err := sentry.Init(sentry.ClientOptions{
		Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
	})

	if err != nil {
		fmt.Printf("Sentry initialization failed: %v\n", err)
	}
}

raven-go

代码语言:javascript
复制
SetDSN()
SetDefaultLoggerName()
SetDebug()
SetEnvironment()
SetRelease()
SetSampleRate()
SetIgnoreErrors()
SetIncludePaths()

sentry-go

代码语言:javascript
复制
sentry.Init(sentry.ClientOptions{
	Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
	DebugWriter: os.Stderr,
	Debug: true,
	Environment: "environment",
	Release: "release",
	SampleRate: 0.5,
	// IgnoreErrors: TBD,
	// IncludePaths: TBD
})

可用选项:请参阅配置部分。

提供 SSL 证书

默认情况下,TLS 使用主机的根 CA 设置。如果您没有 ca-certificates(这应该是解决丢失证书问题的首选方法),而要使用 gocertifi, 则可以提供预加载的证书文件作为 sentry.Init 调用的选项之一:

代码语言:javascript
复制
package main

import (
	"log"

	"github.com/certifi/gocertifi"
	"github.com/getsentry/sentry-go"
)

sentryClientOptions := sentry.ClientOptions{
	Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
}

rootCAs, err := gocertifi.CACerts()
if err != nil {
	log.Println("Couldn't load CA Certificates: %v\n", err)
} else {
	sentryClientOptions.CaCerts = rootCAs
}

sentry.Init(sentryClientOptions)

用法

Capturing Errors

raven-go

代码语言:javascript
复制
f, err := os.Open("filename.ext")
if err != nil {
	raven.CaptureError(err, nil)
}

sentry-go

代码语言:javascript
复制
f, err := os.Open("filename.ext")
if err != nil {
	sentry.CaptureException(err)
}

Capturing Panics

raven-go

代码语言:javascript
复制
raven.CapturePanic(func() {
	// do all of the scary things here
}, nil)

sentry-go

代码语言:javascript
复制
func() {
	defer sentry.Recover()
	// do all of the scary things here
}()

Capturing Messages

raven-go

代码语言:javascript
复制
raven.CaptureMessage("Something bad happened and I would like to know about that")

sentry-go

代码语言:javascript
复制
sentry.CaptureMessage("Something bad happened and I would like to know about that")

Capturing Events

raven-go

代码语言:javascript
复制
packet := &raven.Packet{
	Message: "Hand-crafted event",
	Extra: &raven.Extra{
		"runtime.Version": runtime.Version(),
		"runtime.NumCPU": runtime.NumCPU(),
	},
}
raven.Capture(packet)

sentry-go

代码语言:javascript
复制
event := sentry.NewEvent()
event.Message = "Hand-crafted event"
event.Extra["runtime.Version"] = runtime.Version()
event.Extra["runtime.NumCPU"] = runtime.NumCPU()

sentry.CaptureEvent(event)

Additional Data

See Context section.

Event Sampling

raven-go

代码语言:javascript
复制
raven.SetSampleRate(0.25)

sentry-go

代码语言:javascript
复制
sentry.Init(sentry.ClientOptions{
	SampleRate: 0.25,
})

Awaiting the response (not recommended)

代码语言:javascript
复制
raven.CaptureMessageAndWait("Something bad happened and I would like to know about that")

sentry-go

代码语言:javascript
复制
sentry.CaptureMessage("Something bad happened and I would like to know about that")

if sentry.Flush(time.Second * 2) {
	// event delivered
} else {
	// timeout reached
}

Context

Per-event

raven-go

代码语言:javascript
复制
raven.CaptureError(err, map[string]string{"browser": "Firefox"}, &raven.Http{
	Method: "GET",
	URL: "https://example.com/raven-go"
})

sentry-go

代码语言:javascript
复制
sentry.WithScope(func(scope *sentry.Scope) {
	scope.SetTag("browser", "Firefox")
	scope.SetContext("Request", map[string]string{
		"Method": "GET",
		"URL": "https://example.com/raven-go",
	})
	sentry.CaptureException(err)
})

Globally

SetHttpContext

raven-go

代码语言:javascript
复制
raven.SetHttpContext(&raven.Http{
	Method: "GET",
	URL: "https://example.com/raven-go",
})

sentry-go

代码语言:javascript
复制
sentry.ConfigureScope(func(scope *sentry.Scope) {
	scope.SetContext("Request", map[string]string{
		"Method": "GET",
		"URL": "https://example.com/raven-go",
	})
})

SetTagsContext

raven-go

代码语言:javascript
复制
t := map[string]string{"day": "Friday", "sport": "Weightlifting"}
raven.SetTagsContext(map[string]string{"day": "Friday", "sport": "Weightlifting"})

sentry-go

代码语言:javascript
复制
sentry.ConfigureScope(func(scope *sentry.Scope) {
	scope.SetTags(map[string]string{"day": "Friday", "sport": "Weightlifting"})
})

SetUserContext

raven-go

代码语言:javascript
复制
raven.SetUserContext(&raven.User{
	ID: "1337",
	Username: "kamilogorek",
	Email: "kamil@sentry.io",
	IP: "127.0.0.1",
})

sentry-go

代码语言:javascript
复制
sentry.ConfigureScope(func(scope *sentry.Scope) {
	scope.SetUser(sentry.User{
		ID: "1337",
		Username: "kamilogorek",
		Email: "kamil@sentry.io",
		IPAddress: "127.0.0.1",
	})
})

ClearContext

raven-go

代码语言:javascript
复制
raven.ClearContext()

sentry-go

代码语言:javascript
复制
sentry.ConfigureScope(func(scope *sentry.Scope) {
	scope.Clear()
})

WrapWithExtra

raven-go

代码语言:javascript
复制
path := "filename.ext"
f, err := os.Open(path)
if err != nil {
	err = raven.WrapWithExtra(err, map[string]string{"path": path, "cwd": os.Getwd()})
	raven.CaptureError(err, nil)
}

sentry-go

代码语言:javascript
复制
// use `sentry.WithScope`, see "Context / Per-event Section"
path := "filename.ext"
f, err := os.Open(path)
if err != nil {
	sentry.WithScope(func(scope *sentry.Scope) {
		scope.SetExtras(map[string]interface{}{"path": path, "cwd": os.Getwd()})
		sentry.CaptureException(err)
	})
}

Integrations

net/http

raven-go

代码语言:javascript
复制
mux := http.NewServeMux
http.Handle("/", raven.Recoverer(mux))

// or

func root(w http.ResponseWriter, r *http.Request) {}
http.HandleFunc("/", raven.RecoveryHandler(root))

sentry-go

代码语言:javascript
复制
go get github.com/getsentry/sentry-go/http
代码语言:javascript
复制
import sentryhttp "github.com/getsentry/sentry-go/http"

sentryHandler := sentryhttp.New(sentryhttp.Options{
	Repanic: false,
	WaitForDelivery: true,
})

mux := http.NewServeMux
http.Handle("/", sentryHandler.Handle(mux))

// or

func root(w http.ResponseWriter, r *http.Request) {}
http.HandleFunc("/", sentryHandler.HandleFunc(root))
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 黑客下午茶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
    • 安装
      • 配置
        • 验证
        • 处理 Panics
          • 用法
            • 使用 Context
            • 并发
            • 配置项
              • 基本选项
                • 提供 SSL 证书
                • 删除默认集成
              • Releases & Health
                • 绑定版本
              • Transports
                • 用法
                • 选项
                • HTTPTransport
                • HTTPSyncTransport
              • Environments
                • 过滤和采样事件
                  • 过滤错误事件
                  • Event Hints
                  • 使用 Hints
                  • Hints for Events
                  • Hints for Breadcrumbs
                  • 采样错误事件
                • Shutdown and Draining
                • Serverless
                  • Source Context
                    • Events Delivery
                    • 用法
                      • 捕获错误
                        • 捕获消息
                          • 设置级别
                          • 迁移指南
                            • 提供 SSL 证书
                              • 用法
                              相关产品与服务
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档