Files
go-omni/ws/observe/README.md

45 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WebSocket 可选观测
`ws/observe` 为 `ws.Client`、`ws.Server` 的会话提供连接日志和聚合快照。核心 `ws` 不依赖全局 Logger;观测器不启动后台 goroutine,不给每条消息增加日志、锁或 span。
```go
logger, err := logx.New(logx.Default())
if err != nil { return err }
defer logger.Close() // 必须晚于 Client/Server 的 Shutdown 完成
observer := observe.New(logger) // nil 表示只统计,不记日志
handlers := observer.Wrap(ws.Handlers{
OnMessage: func(ctx context.Context, session *ws.Session, message ws.Message) error {
return session.Send(ctx, message)
},
})
server, err := ws.NewServer(ws.ServerConfig{})
if err != nil { return err }
mux.Handle("/ws", server.Handler(handlers))
// 由项目按自己的采样周期读取,接入 metrics、Prometheus 或 OTel。
snapshot := observer.Snapshot()
```
导入路径为 `git.yuntuo.hk/k2safe/go-omni/ws/observe`。同一个 Observer 和同一组包装后的 Handlers 可供多个连接并发复用;每个会话有独立的开始时间。每个会话仅包装一次。使用客户端重连和 `ClientConfig.Prepare` 时,在每次 Prepare 返回前调用 `observer.Wrap(handlers)`。
快照包含:
- `Opened / Closed / Active`:已观察到的连接总数、关闭回调结束数、当前处于受观察生命周期中的连接数。连接可能在 OnOpen 执行前断开,此时仍在 OnClose 计入 Opened 和 Closed,日志时长为 0。
- `MessagesSent / MessagesReceived / BytesSent / BytesReceived`:已关闭会话的最终统计,加上当前会话的即时统计。发送成功表示写入完成;不是对端收到消息或业务处理成功的确认。统计口径与 `Session.Stats()` 一致。
- `WriteQueuedMessages / WriteQueuedBytes / ReadQueuedMessages / ReadQueuedBytes`:调用快照时,各活跃连接队列水位之和。接收侧包括仍在处理、尚未释放的消息。
- `SampledPeak*`:历次 Snapshot 观察到的聚合峰值;不是精确的历史峰值,采样间隔内的突增可能未被记录。
- `CloseCallbackPanics`:下游 OnClose 回调发生 panic 的次数。
Snapshot 为 O(活跃会话数),只在采样时读取 `Session.Stats()`,不会替换消息回调。避免在每条消息上采样;采样周期由项目根据连接规模决定。快照不会保存已关闭连接的 ID,也不引入高基数指标标签。自行导出 OTel 时,建议记录握手、连接时长、消息数与字节数;业务消息追踪应显式传递上下文,不自动延长握手 span 到整条连接的寿命。
日志只由适配器写入固定事件名、Session ID、时长、关闭码和固定阶段。不会展开错误文本、Cause、URL、请求头、消息体或对端关闭原因;业务自定义 `OpError.Op` 也通过固定白名单筛选。用户传入 Logger 自身已经附加的属性仍由用户负责。默认日志级别为 Info。
OnClose 的收尾使用 defer,即使业务回调 panic,也会归档消息统计、移除活跃记录、记录固定的 `on_close_panic` 阶段,再把 panic 交还核心处理。此处“关闭”表示 I/O 已停止且下游 OnClose 已返回或 panic;核心随后才关闭 `Session.Done()`。因此 `Snapshot.Active == 0` 不是生命周期完成屏障,停机必须等待 `Client/Server.Shutdown` 或 `Session.Done`,再关闭 Logger。观测器不会在 OnClose 中等待自身 Done,也不会在 Done 后继续写日志。
运行真实 TCP 与并发测试:
```sh
go test -race ./ws/observe
```