Skip to content

本页翻译可能滞后于英文版,如有出入以英文版为准。

sp logs

Agent 何时使用: 无需直接访问 Parquet 文件或存储凭据,即可在调用方提供的时间范围内,检索某个 W3C trace 的应用、agent 和 sp-backend 关联日志。

前置条件: 已启用统一日志管道(Vector 采集 + Parquet 存储 + 查询接线)。参见安装 sp-backend(服务端)— 统一日志管道日志关联 ID

v1 仅支持 trace-id、固定查询——没有 SQL、没有即席查询语言、没有 sp logs status 健康检查命令,也没有 replay/plan 查询键。

API: sp-backend 上的 GET /api/recorder/logs?trace_id=…&since=…&until=…。顶层命令 sp logs 使用相同的契约。


概要

在调用方提供的时间窗口内,按 trace_id 查询统一日志行。

bash
sp logs --trace-id <id> --since <time> --until <time> [--json]

标志

Flag是否必填说明
--trace-idW3C trace id——v1 唯一的查询键
--since包含式下界——ISO-8601 UTC(例如 2026-06-27T10:00:00Z
--until排除式上界——ISO-8601 UTC
--json用于自动化和 Agent Skills 的稳定 JSON 封装

规则:

  • 每次查询都必须提供 --trace-id--since--until。时间范围是半开区间:[since, until)
  • v1 不提供 --limit 或行截断——请缩小时间窗口,或在本地过滤(greptail、重定向到文件)。
  • 不支持的查询键(--replay-id--plan-id--plan-item-id--include-recording-log)会在读取 Parquet 之前校验失败。
  • 只要能访问到部署端点,v1 日志查询无需身份认证。
  • 当日志管道被禁用或查询依赖不可用时,命令会快速失败并给出清晰的错误。它不会返回空的成功结果,也不会回退到旧版日志存储。

示例

bash
# 回放失败后按 trace 范围查询(从 replay API 或 pytest 输出中获取 trace_id)
sp logs \
  --trace-id 2057ad46a7ce03d3955385f2a4142d29 \
  --since 2026-06-27T10:00:00Z \
  --until 2026-06-27T10:05:00Z \
  --json

# 人类可读输出
sp logs \
  --trace-id 2057ad46a7ce03d3955385f2a4142d29 \
  --since 2026-06-27T10:00:00Z \
  --until 2026-06-27T10:05:00Z

# 结果较大——重定向或用管道(v1 没有 --limit)
sp logs --trace-id 2057ad46a7ce03d3955385f2a4142d29 --since --until > /tmp/trace.log
grep ERROR /tmp/trace.log | head -20

Agent Skills 工作流(CLI 或 API):

bash
# 标准 CLI
sp logs --trace-id "$TRACE_ID" --since "$SINCE" --until "$UNTIL" > .spcode/unified-logs-"$TRACE_ID".log
grep ERROR .spcode/unified-logs-"$TRACE_ID".log | head -20

# HTTP API(相同契约)
curl -s "$SP_API_URL/api/recorder/logs?trace_id=$TRACE_ID&since=$SINCE&until=$UNTIL" > .spcode/unified-logs-"$TRACE_ID".json

输出

人类可读(默认): 按时间顺序的日志流——每行一条记录,包含时间戳、严重级别、sourceservice_name 和正文。

--json 相同的逻辑数据,采用标准 CLI 封装(okcommanddata)。顶层 data 字段:

Field含义
lookup查询类型(trace)、查询值,以及调用方的 [since, until) 边界
rows日志行——参见日志查询字段
warnings非致命的 schema 跳过或类似提示(可能为空)

v1 响应包含 source_summary,也不做按来源的行数分桶统计。

各行包含 pytest 标签、套件名称或测试节点 id。

当发射端具备相应上下文时,可选的 Softprobe 标签(replay_idplan_idplan_item_id……)可能出现在个别行上——它们不是过滤键。


按 case 范围查询(双窗口)

在诊断某个回放 case 时,你通常会有两个时间戳:

  • recordTime——case 最初被录制的时间(API 字段 requestDateTime
  • replayTime——回放运行执行的时间

不要在一次请求中从 recordTime 一直查询到 replayTime。那会跨越其间的每一个分钟分区,可能扫描数百个 Parquet 文件。

正确做法是运行两次窄范围查询(在每个锚点前后各 ±2 分钟),并在客户端合并各行:

bash
export SP_API_URL="${SP_API_URL:-http://127.0.0.1:18090}"
TRACE_ID="<32-hex from replay case traceId>"
RECORD_TIME_MS=1714000000000   # requestDateTime from case row
REPLAY_TIME_MS=1714046100000   # replayTime from case row
PADDING_MS=$((2 * 60 * 1000))

# Window 1: recording
RECORD_SINCE=$(date -u -d "@$(( (RECORD_TIME_MS - PADDING_MS) / 1000 ))" +%Y-%m-%dT%H:%M:%SZ)
RECORD_UNTIL=$(date -u -d "@$(( (RECORD_TIME_MS + PADDING_MS) / 1000 ))" +%Y-%m-%dT%H:%M:%SZ)

curl -s "${SP_API_URL}/api/recorder/logs?trace_id=${TRACE_ID}&since=${RECORD_SINCE}&until=${RECORD_UNTIL}" \
  -H "Accept: application/json" -o /tmp/sp-logs-record.json

# Window 2: replay
REPLAY_SINCE=$(date -u -d "@$(( (REPLAY_TIME_MS - PADDING_MS) / 1000 ))" +%Y-%m-%dT%H:%M:%SZ)
REPLAY_UNTIL=$(date -u -d "@$(( (REPLAY_TIME_MS + PADDING_MS) / 1000 ))" +%Y-%m-%dT%H:%M:%SZ)

curl -s "${SP_API_URL}/api/recorder/logs?trace_id=${TRACE_ID}&since=${REPLAY_SINCE}&until=${REPLAY_UNTIL}" \
  -H "Accept: application/json" -o /tmp/sp-logs-replay.json

# Merge and sort by timestamp (example with jq)
jq -s '[.[].rows[]] | sort_by(.timestamp)' /tmp/sp-logs-record.json /tmp/sp-logs-replay.json

SoftProbe 工作台的 View case logs 操作会自动使用相同的双窗口模式。回放窗口通常包含你需要的日志行;录制窗口往往为空,但查询成本很低。

参见日志查询字段日志关联 ID


排查回放失败

sp diagnose replay 或 pytest 失败之后使用。id 来源参见日志关联 ID

bash
export SP_API_URL="${SP_API_URL:-http://127.0.0.1:18090}"
TRACE_ID="<32-hex from replay case traceId or pytest correlation block>"
SINCE="2026-06-27T10:00:00Z"
UNTIL="2026-06-27T10:05:00Z"

curl -s "${SP_API_URL}/api/recorder/logs?trace_id=${TRACE_ID}&since=${SINCE}&until=${UNTIL}" \
  -H "Accept: application/json" -o /tmp/sp-logs.json

jq '.rows | length' /tmp/sp-logs.json
jq '[.rows[].source] | group_by(.) | map({source: .[0], n: length})' /tmp/sp-logs.json
jq '.warnings' /tmp/sp-logs.json
jq -r '.rows[] | select(.source=="backend" and .severity=="ERROR") | .body' /tmp/sp-logs.json | head -20
现象可能原因
0 行 + warnings 非空Backend Parquet 读取器与 schema 不同步——重新构建 sp-backend 镜像
0 行,warnings 为空trace_id、时间窗口有误,或采集尚未刷盘
来自 agentappbackend 的日志行管道正常——检查 diff 制品,并查看日志 body 了解 compare/mock 时序

Pytest: 在失败输出中查看 Softprobe correlationtrace_id)和 Unified logs(行数/来源汇总)。

Agent Skills: 优先用 shell(curljqgrep)——不要在插件代码中实现 Parquet 读取器。


JSON 输出

json
{
  "ok": true,
  "command": "logs",
  "data": {
    "lookup": {
      "type": "trace",
      "value": "2057ad46a7ce03d3955385f2a4142d29",
      "windows": [
        {
          "since": "2026-06-27T10:00:00Z",
          "until": "2026-06-27T10:02:00Z"
        }
      ]
    },
    "rows": [
      {
        "timestamp": "2026-06-27T10:00:10.123Z",
        "severity": "WARN",
        "body": "Replay comparison mismatch",
        "service_name": "sp-backend",
        "source": "backend",
        "trace_id": "2057ad46a7ce03d3955385f2a4142d29",
        "span_id": "8d10c94a2a6f4e11",
        "replay_id": "6891fd300c676b31"
      }
    ],
    "warnings": []
  }
}

JSON 错误

校验和 API 失败使用标准 CLI stderr 封装:

json
{
  "ok": false,
  "command": "logs",
  "error": {
    "code": "API_ERROR",
    "message": "API error 1: trace_id is required",
    "httpStatus": 200,
    "backend": {
      "responseCode": 1,
      "responseDesc": "trace_id is required"
    }
  }
}

校验消息示例:trace_id is requiredunsupported logs query parameter: replay_idsince is requireduntil is requiredsince must be before untilsince and until must be ISO-8601 UTC timestampsunsupported logs query parameter: <name>log pipeline is disabledlog pipeline is unavailable


REST 映射

CLIMethodPath
--trace-idGET/api/recorder/logs?trace_id=<id>&since=<ts>&until=<ts>

与其他 sp 命令托管在同一个 sp-backend 基础 URL 上。只要能访问到部署端点,v1 日志查询无需身份认证。


已废弃命令(v1)

以下统一化之前的路径已被移除,且没有做兼容垫片:

已废弃替代方案
sp record logs overviewsp logs --trace-id <id> --since … --until …
sp record logs downloadsp logs --trace-id <id> …(重定向到文件)或 --json 配合 jq
sp replay logs(包括 --overviewsp logs --trace-id <id> …(重定向到文件)或 --json 配合 jq
sp logs --replay-id--plan-id--plan-item-id拒绝——仅使用 --trace-id
--include-recording-log已移除——不支持 record-link 查询
GET /api/record-logs/*GET /api/recorder/logs?trace_id=…
GET /api/replay-logs/*GET /api/recorder/logs?trace_id=…

不在范围内(v1)

  • sp logs status / 管道健康状态命令
  • Replay-id、plan-id 或 plan-item-id 查询键
  • 直接的 Parquet 路径、catalog URL、对象存储凭据或 SQL
  • 查询结果中的 sp.session_id
  • --limit / 行截断——请改为缩小时间边界或在本地过滤
  • 日志查询的身份认证
  • Record trace 表、metrics 表、回放读取迁移、历史回填,以及非回放路径的服务日志(dashboard、auth 等)——回放数据仍保留在旧版兼容回放的存储路径上

相关

零代码改动 · 全上下文可见性 · 成本优化