Skip to content

Go SDK

github.com/wearzdk/kestrel/sdks/go —— 独立的 Go module,仅依赖标准库。

安装

bash
go get github.com/wearzdk/kestrel/sdks/go@latest

初始化

最常见的"单项目、单进程"用法走包级 Init

go
import kestrel "github.com/wearzdk/kestrel/sdks/go"

if err := kestrel.Init(
    "https://kestrel.example.com",
    os.Getenv("KESTREL_TOKEN"),
    kestrel.WithRelease(os.Getenv("GIT_COMMIT")),
); err != nil {
    panic(err)
}

如果需要隔离的 client(多项目、测试),改用 kestrel.NewClient(endpoint, token, opts...),对返回的 *Client 调方法。Client 跨 goroutine 共用安全。

Recover panic

把 Kestrel 接进现有服务最 idiomatic 的方式,是在 panic 边界放一个 defer

go
func handle(w http.ResponseWriter, r *http.Request) {
    defer kestrel.RecoverAndSwallow(r.Context()) // 捕获后返回 500
    // ...你的 handler...
}

两个变体:

  • kestrel.Recover(ctx) —— 捕获后重抛。当外层已经有自己的 recovery(默认 panic handler、框架 middleware)时用这个。
  • kestrel.RecoverAndSwallow(ctx) —— 捕获并阻止 panic 继续传播。在 HTTP / RPC 边界用,得到一个干净的 500,而不是 goroutine 崩溃。

slog handler

把结构化日志接进来,改任何 log 调用点:

go
import "log/slog"

base := slog.NewJSONHandler(os.Stdout, nil) // 你原来的 handler
// client 传 nil 表示用 kestrel.Init 配置的那个。
h := kestrel.NewSlogHandler(base, nil, slog.LevelError)
slog.SetDefault(slog.New(h))

// 之后任何地方:
slog.Error("payment failed", "txn", txnID, "err", err)
// ...既会写到 stdout,也会作为 Kestrel 事件上报。

低于阈值时包装层是直通 —— 零分配、零网络。只有 Error(及以上)触发上报。

手动捕获

go
if err := doThing(ctx); err != nil {
    kestrel.Capture(ctx, err, map[string]any{"request_id": reqID})
    return err
}

退出前 Flush

异步上报走 goroutine 池。短生命周期的程序(CLI、serverless handler)退出前调一下 kestrel.Flush(ctx),把队列里的事件发完:

go
defer func() {
    flushCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    _ = kestrel.Flush(flushCtx)
}()

不做的事

SDK 不 wrap errors.Is / errors.As,不插桩 net/http,不挂 database/sql,不修改任何你没显式交给它的 package。上面三个入口(Recover、slog handler、Capture)就是全部接入面。

发布

git tag sdks/go/vX.Y.Z 即发布新版本 —— Go module proxy 会自动收录。Go SDK 与服务端、其它 SDK 独立版本。

基于 MIT 协议发布。