# 错误码、日志与 trace_id 两个库互不导入。错误码库负责稳定的码和 HTTP 信封,日志库负责把同一次调用的运行记录留下来。对齐点只有两个: - 追踪头都是 `X-Trace-Id` - 日志通过 `ErrorCode()` / `ErrorFields()` 识别错误,不需要 `import error-code-system` ## 一次失败怎么串起来 ```text HTTP 中间件生成或沿用 X-Trace-Id │ ▼ errcode.Wrap(...) 得到规范码 │ ├─ httpx.WriteError → {"error":{"code","message","reason","trace_id"}} │ └─ log.WithContext(ctx).Error(msg, err) │ ▼ 日志条目含 trace_id + code + 字段 │ ▼ HTTP sink 批量 POST 到 :8092 │ ▼ GET /v1/logs?trace_id=... 或 ?q=agent.provider_unavailable ``` 查问题先拿响应里的 `trace_id` 或 `code`。`trace_id` 能拉出这一次调用的全部日志;`code` 能跨请求看同一类失败。副作用是 `possible` 或 `unknown` 的码不要无条件重放,先看日志里这次执行写过什么。 ## 最小示例 可运行副本:`Logging-System/examples/trace`(需要两个仓库是同级目录)。 ```go reg := errcode.NewRegistry() domains.RegisterAll(reg) cfg, _ := config.Load("log.json") // 见 Logging-System/docs/example.json log, _ := config.Build(cfg) defer log.Close() ctx := logsys.WithTrace(r.Context(), httpx.TraceID(r)) err := errcode.Wrap(cause, errcode.AgentProviderUnavailable, "模型不可达", "model", "glm-4") log.WithContext(ctx).Error("provider down", err) httpx.WriteError(reg, w, r, err) ``` 日志条目里会有 `trace_id=...` 和 `code=agent.provider_unavailable`。采集器侧: ```bash logctl query --addr http://127.0.0.1:8092 --trace <响应里的 trace_id> ``` ## 接入现有仓库时 本轮不改 Agent-Native / Agent-Squad。对应关系已经写在错误码仓库: - `docs/agent-native-mapping.md` - `docs/agent-squad-mapping.md` 接入时保持现有事件名和 `AssessStepFailure` 分类,只把对外的错误字符串换成规范码,并把 `run_id` 写入日志字段。`run_id` 回答「哪一次编排」,`trace_id` 回答「哪一次请求」,两者都保留。