Go SDK
服务端埋点:下单、支付、任务完成这类只有后端知道的事件。只依赖标准库,事件先进内存队列,后台批量发送,不会拖慢你的请求。
安装
bash
go get github.com/mosongcc/evstats/evs-sdks/go包名是 evstats,要求 Go 1.22 及以上。版本标签是 evs-sdks/go/vX.Y.Z。
用法
go
package main
import (
"context"
"log"
"os"
evstats "github.com/mosongcc/evstats/evs-sdks/go"
)
func main() {
client := evstats.New(evstats.Config{
Endpoint: "https://stats.example.com/sa",
Key: os.Getenv("EVSTATS_KEY"), // evs_wk_xxx
})
defer client.Close()
err := client.Track(context.Background(), evstats.Event{
DistinctID: "user_42",
Event: "order_paid",
Properties: map[string]any{"amount": 99, "plan": "pro"},
})
if err != nil {
log.Print(err)
}
}Track 把事件放进内存队列就返回,不等网络。进程退出前调用一次 Close,它会尽量把队列发完,最多等 CloseTimeout(默认 3 秒)。
Event
| 字段 | 规则 |
|---|---|
DistinctID | 必填。服务端没有浏览器匿名 ID,调用方给一个稳定的 ID,通常就是用户 ID。写进 anonymousId |
UserID | 可选。设置后写进 userId,anonymousId 仍是 DistinctID |
Event | 必填,事件名 |
Time | 零值时用入队时间 |
Properties | map[string]any,值只能是字符串、数字、布尔 |
想让服务端事件和网页事件落在同一个画像里:网页登录后 identify("user_42"),服务端用 DistinctID: "user_42"。
其它方法
| 方法 | 发送 |
|---|---|
Identify(ctx, distinctID, userID, traits) | type=identify,把 distinctID 与登录用户 userID 关联。traits 可为 nil |
Profile(ctx, distinctID, properties) | profile_set,设置用户属性 |
ProfileSetOnce(ctx, distinctID, properties) | profile_set_once,已存在的属性不覆盖 |
ProfileIncrement(ctx, distinctID, properties) | profile_increment,值必须是数字 |
Flush(ctx) | 立即发送队列里的全部事件 |
Close() | 发完队列后停止。只调用一次 |
用户属性和 identify 不计入事件次数。
Config
| 字段 | 默认 | 说明 |
|---|---|---|
Endpoint | 必填 | 完整采集地址,原样请求,不拼路径 |
Key | 必填 | 项目的写入密钥 |
FlushInterval | 500ms | 发送间隔 |
BatchSize | 100 | 单批条数,也是上限 |
QueueSize | 1000 | 内存队列长度 |
DropPolicy | DropOldest | 队列满时丢最旧的一条,Track 仍返回 nil;ReturnError 时不入队,返回 ErrQueueFull |
HTTPClient | 超时 5 秒 | 自定义 *http.Client |
Debug | false | 用 slog 记每次请求的状态码和密钥前缀,不记密钥全文 |
LibVersion | 构建时写入 | 写进 context.library.version |
CloseTimeout | 3 秒 | Close 最多等多久 |
行为
ctx只管入队之前:已经结束的ctx让Track返回ctx.Err()且不入队;入队之后与ctx无关,取消它不会取消已经入队的事件。- 并发:
Track可以在多个 goroutine 里同时调用;内部一个发送 goroutine。 - 重试:网络失败、超时、429、5xx 按 200ms 起退避,最多 5 次,重试沿用同一个
messageId;400、401 不重试。 - 压缩:单批超过 32KB 时 gzip,小批不压缩。
Close之后再调用返回ErrClosed。