Sentry-Go SDK 中文实践指南(二)

简介: Sentry-Go SDK 中文实践指南(二)

采样错误事件


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

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


Shutdown and Draining


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


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

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


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


func main() {
  // err := sentry.Init(...)
  defer sentry.Flush(2 * time.Second)
  sentry.CaptureMessage("my message")
}


Serverless


Source Context


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

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


.
├── 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


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


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

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


f, err := os.Open("filename.ext")
if err != nil {
  sentry.CaptureException(err)
}


捕获消息


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


sentry.CaptureMessage("Something went wrong")


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


设置级别


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


sentry.ConfigureScope(func(scope *sentry.Scope) {
  scope.SetLevel(sentry.LevelWarning)
})


迁移指南



如何从 raven-go 转到 sentry-go

安装

raven-go


go get github.com/getsentry/raven-go


sentry-go


go get github.com/getsentry/sentry-go


配置

raven-go


import "github.com/getsentry/raven-go"
func main() {
  raven.SetDSN("https://examplePublicKey@o0.ingest.sentry.io/0")
}


sentry-go


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


SetDSN()
SetDefaultLoggerName()
SetDebug()
SetEnvironment()
SetRelease()
SetSampleRate()
SetIgnoreErrors()
SetIncludePaths()


sentry-go


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 调用的选项之一:


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


f, err := os.Open("filename.ext")
if err != nil {
  raven.CaptureError(err, nil)
}


sentry-go


f, err := os.Open("filename.ext")
if err != nil {
  sentry.CaptureException(err)
}


Capturing Panics

raven-go


raven.CapturePanic(func() {
  // do all of the scary things here
}, nil)


sentry-go


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


Capturing Messages

raven-go


raven.CaptureMessage("Something bad happened and I would like to know about that")


sentry-go


sentry.CaptureMessage("Something bad happened and I would like to know about that")


Capturing Events

raven-go


packet := &raven.Packet{
  Message: "Hand-crafted event",
  Extra: &raven.Extra{
    "runtime.Version": runtime.Version(),
    "runtime.NumCPU": runtime.NumCPU(),
  },
}
raven.Capture(packet)


sentry-go


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


raven.SetSampleRate(0.25)


sentry-go


sentry.Init(sentry.ClientOptions{
  SampleRate: 0.25,
})


Awaiting the response (not recommended)


raven.CaptureMessageAndWait("Something bad happened and I would like to know about that")


sentry-go


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


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


sentry-go


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


raven.SetHttpContext(&raven.Http{
  Method: "GET",
  URL: "https://example.com/raven-go",
})


sentry-go


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


SetTagsContext

raven-go


t := map[string]string{"day": "Friday", "sport": "Weightlifting"}
raven.SetTagsContext(map[string]string{"day": "Friday", "sport": "Weightlifting"})


sentry-go


sentry.ConfigureScope(func(scope *sentry.Scope) {
  scope.SetTags(map[string]string{"day": "Friday", "sport": "Weightlifting"})
})


SetUserContext

raven-go


raven.SetUserContext(&raven.User{
  ID: "1337",
  Username: "kamilogorek",
  Email: "kamil@sentry.io",
  IP: "127.0.0.1",
})


sentry-go


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


raven.ClearContext()


sentry-go


sentry.ConfigureScope(func(scope *sentry.Scope) {
  scope.Clear()
})


WrapWithExtra

raven-go


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


// 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


mux := http.NewServeMux
http.Handle("/", raven.Recoverer(mux))
// or
func root(w http.ResponseWriter, r *http.Request) {}
http.HandleFunc("/", raven.RecoveryHandler(root))


sentry-go


go get github.com/getsentry/sentry-go/http


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))


相关文章
|
2月前
|
Shell Go 开发工具
【Azure Developer】Go语言调用Azure SDK如何登录到中国区Azure环境
【Azure Developer】Go语言调用Azure SDK如何登录到中国区Azure环境
|
3月前
|
JSON Java Serverless
函数计算产品使用问题之如何使用Go SDK从HTTP上下文中提取JSON数据
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
3月前
|
分布式计算 大数据 Go
MaxCompute操作报错合集之使用go sdk调用GetTunnelEndpoint出现报错:InvalidAction.NotFoundSpecified api is not found,该如何解决
MaxCompute是阿里云提供的大规模离线数据处理服务,用于大数据分析、挖掘和报表生成等场景。在使用MaxCompute进行数据处理时,可能会遇到各种操作报错。以下是一些常见的MaxCompute操作报错及其可能的原因与解决措施的合集。
|
5月前
|
安全 Go 开发工具
对象存储OSS产品常见问题之go语言SDK client 和 bucket 并发安全如何解决
对象存储OSS是基于互联网的数据存储服务模式,让用户可以安全、可靠地存储大量非结构化数据,如图片、音频、视频、文档等任意类型文件,并通过简单的基于HTTP/HTTPS协议的RESTful API接口进行访问和管理。本帖梳理了用户在实际使用中可能遇到的各种常见问题,涵盖了基础操作、性能优化、安全设置、费用管理、数据备份与恢复、跨区域同步、API接口调用等多个方面。
116 9
|
12月前
|
资源调度 Kubernetes Go
SchedulerX支持Go版本SDK
Go语言越来越流行,SchedulerX是阿里云的分布式任务调度服务,新增支持Go版本SDK
101 0
|
Kubernetes Go 开发工具
开发 k8s 管理平台 - k8sailor 03. 使用 client-go sdk 链接集群
开发 k8s 管理平台 - k8sailor 03. 使用 client-go sdk 链接集群
259 0
开发 k8s 管理平台 - k8sailor 03. 使用 client-go sdk 链接集群
|
Go 开发工具
【Go】The selected directory is not a valid home for Go SDK
【Go】The selected directory is not a valid home for Go SDK
395 0
【Go】The selected directory is not a valid home for Go SDK
|
存储 自然语言处理 NoSQL
表格存储 Go SDK 开发入门
本文将结合电商订单场景为例,介绍表格存储 Tablestore Go SDK 的基本使用方法。
295 0
|
JavaScript Java Serverless
|
8天前
|
Go
Go 语言循环语句
在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。
18 1
下一篇
无影云桌面