feat(observability): 管理面板可观测性接真实数据——metrics/trace/audit 三端点 + 审计持久化
- observability.go/observability_metrics.go/observability_trace.go/observability_audit.go:
拆分保证 ≤500行/函数≤80。metrics 并发安全 MetricsCollector(方法/路径/状态计数、平均/最大延迟、
近1s QPS窗口);trace 并发安全 RingBuffer(默认512, newest-first)+traceSink+MultiTraceWriter;
audit AuditStore 接口+内存回退+SQLite 持久化(NewSQLiteAuditStore 参数化 SQL+audit_logs 表)。
- server.go:Deps.AuditStore + Server.obs + 3 路由 GET /admin/observability/{metrics,trace,audit};
ObserveSpan/TraceSink 注入点;middleware logging recordMetric;audit 落库(仅 slog→Append)。
- 前端 Obs.tsx:metrics 接 4 张真实 StatCard+请求分布、trace 接 span 列表(展开 props/events)、
audit 从后端拉(前端内存审计作回退);api.ts/types.ts 加 obs 端点/类型(AdminObservabilityMetrics/
AdminTraceSpan/AuditRecord.id 放宽)。成本指标不伪造(保留'—'+注明)。
- wire.go 收口:Deps.AuditStore 注入 gateway.NewSQLiteAuditStore(ctx, a.db)(审计真落库),
未注入回退内存。
- Docs/api-client.md §2/v0.6。
实机验证:三端点 200,metrics 返回 totalRequests:4/qps:4/perPath/statusCounts:{200:4}。
go build/vet/test 全绿 + 前端 tsc。trace 数据源对接(gw.TraceSink→loop tracer)因 gw/tracer
构造顺序留作可选后置(端点已就绪, 未对接 span 空)。
This commit is contained in:
1 parent
76134ed47e
commit
e0a543cc37
12 files changed
+803
-22
No files matched your search
@@ -1,6 +1,7 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -16,15 +17,23 @@ func (s *Server) auditClaims(r *http.Request, what, result string) {
|
||||
if claims, ok := auth.ClaimsFromContext(r.Context()); ok {
|
||||
who = claims.Sub + ":" + string(claims.Role)
|
||||
}
|
||||
s.audit(who, what, result)
|
||||
s.audit(r.Context(), who, what, result)
|
||||
}
|
||||
|
||||
// audit emits one structured audit record on the gateway logger.
|
||||
func (s *Server) audit(who, what, result string) {
|
||||
// audit emits one structured audit record on the gateway logger and persists it to
|
||||
// the configured AuditStore (falling back to an in-memory store when none is
|
||||
// injected). A persist failure is logged but never blocks the admin write, so a
|
||||
// broken audit store cannot take down the audit trail's primary job.
|
||||
func (s *Server) audit(ctx context.Context, who, what, result string) {
|
||||
s.log.Info("admin audit",
|
||||
"who", who,
|
||||
"what", what,
|
||||
"when", time.Now().UTC().Format(time.RFC3339),
|
||||
"result", result,
|
||||
)
|
||||
if s.obs != nil && s.obs.audit != nil {
|
||||
if err := s.obs.audit.Append(ctx, who, what, result, time.Now()); err != nil {
|
||||
s.log.Error("admin audit persist", "err", err, "what", what)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user