3.0 KiB
3.0 KiB
按手机号关联的外呼业务日志(2026-09-19)
实现
已在 Agent RPC 执行/事实回报边界增加文件型结构化业务日志:
internal/calllog/log.go:JSONL 追加器;每条记录0600,父目录0700,写入后Sync。internal/rpc/server.go:Execute记录execution.prepared;ReportExecutionEvent记录 call status/finished、录音事实和 attempt summary。cmd/sip-go-agent/main.go:Agent 配置CallLogger;未指定路径时写入 Agent spool 的call-business.jsonl。internal/config/config.go:支持AGENT_CALL_BUSINESS_LOG与AGENT_CALL_PHONE_LOG_KEY。
脱敏边界
- 原始
callee只在进程内用于生成身份,永不序列化到日志。 phone_ref是使用受控注入密钥计算的 HMAC-SHA256,可跨任务关联同一号码;phone_mask只保留末四位(短号码全部掩码)。- 不写入凭据、SIP URI/服务端地址、音频、转写文本、prompt、变量或 OSS 本地路径。
- 日志 key 不得写入代码、配置样例、日志或证据;建议通过受控环境/secret 文件注入,长度至少 16 字节。key 轮换会产生新的手机号引用,轮换应作为单独运维动作登记。
记录字段
每条记录包含 schema_version、event_id、occurred_at、event_type、phone_ref、phone_mask,并按实际事实填充:
- 业务关联:
tenant_id、trace_id、task_id、task_item_id、task_revision、execution_id、attempt_id、call_id。 - 线路和节点:
route_policy_id、caller_profile_id、trunk_id、cell_id、agent_id。 - SIP/状态:
sip_stage、sip_status_code、sip_reason、call_state、attempt_state、status、result、reason_code。 - 录音/结果:
recording_id、recording_state、recording_size_bytes、recording_duration_ms、recording_sha256、duration_ms。
ReportExecutionEvent 只从 allow-list 字段解析事实 payload,不把任意 payload 或 transcript 文本复制到业务日志;call.finished 的 attempt_summary 会拆成独立 call.attempt 记录。
配置
# 可选路径;只配置 key 时默认落到 $AGENT_SPOOL_ROOT/call-business.jsonl
AGENT_CALL_BUSINESS_LOG=/var/lib/sip-go-agent/call-business.jsonl
AGENT_CALL_PHONE_LOG_KEY=<受控注入的至少16字节密钥>
设置路径时必须同时设置 key;只设置 key 时使用 spool fallback。未设置 key 时不会创建日志文件,避免退回明文手机号。
本地验证
已通过:
go test -race ./internal/calllog ./internal/rpc
go test -race ./...
go vet ./...
覆盖场景:同一手机号跨事件稳定关联、原始号码不出现在 JSONL、SIP 阶段/状态码/线路/执行与呼叫 ID/录音/结果字段、attempt summary 拆分、文件权限、非法身份拒绝和并发追加。
该日志是 Agent 本地业务审计材料,不替代 SaaS 的最终业务事件、MQ 应用收讫、OSS verified→MQ 回执或生产观测系统;本地测试通过也不代表真实 SIP/AI/OSS/P1 验收通过。