Skip to content

Log query fields

When agents use this: Interpret rows returned by sp logs or GET /api/recorder/logs — field names, meanings, and when correlation ids may be missing.

This reference describes CLI and API query output only. It does not document Parquet file paths, partition layout, or how to query storage directly. Use sp logs or the canonical HTTP API for all lookups.

Lookup key: trace_id is the required lookup key. replay_id, plan_id, plan_item_id, and mode (record or replay) are supported optional query filters — pass them as query parameters to separate record rows from a specific replay run within one trace.

Naming: API and Parquet rows use unprefixed column names (source, replay_id, …). OTLP on the wire may use sp.source, sp.replay_id, etc. before Vector maps them into storage.


Where rows appear

Each successful lookup returns one chronological stream of rows in data.rows (CLI --json) or the API rows array. Rows are ordered by event timestamp ascending.

Human-readable CLI output prints the same logical fields as API JSON.

See sp logs for the --trace-id lookup key, triage workflow, and required time bounds.


Field reference

Every row includes the core fields below. Correlation fields are included when the emitting runtime knew them at log time — they may be absent on contextless lines (see Absent correlation fields).

FieldAlways presentDescription
timestampyesEvent time of the log line. ISO-8601 UTC in JSON (for example 2026-06-27T10:00:10.123Z). Used for chronological ordering and for caller [since, until) filtering.
severityyesNormalized severity text from the emitting logger (for example DEBUG, INFO, WARN, ERROR). Each component controls which severities it emits through its own native logging configuration — Softprobe does not impose a product-wide severity filter.
bodyyesFull log message text. v1 returns the complete body; query results do not truncate message content.
service_nameyesRuntime service identity for the line (for example travel-ota, sp-backend). Identifies which process produced the row.
sourceyesWhich v1 pipeline source produced the row. Fixed values: agent, app, or backend (see source values).
trace_idwhen knownW3C OpenTelemetry trace id for the request or work unit that was active when the line was emitted. The only v1 lookup key.
span_idwhen knownOpenTelemetry span id for the active span when the line was emitted.
replay_idwhen knownOne replay attempt id when replay context was active at emit time. Also a supported optional query filter (&replay_id=).
plan_idwhen knownReplay plan id when plan context was active at emit time. Also a supported optional query filter (&plan_id=).
plan_item_idwhen knownOne case or operation inside a replay plan. Also a supported optional query filter (&plan_item_id=).
modewhen knownRecord/replay phase tag as emitted by the agent (record or replay). Optional column added after the original v1 contract — rows written by older writers omit it; read effective_mode instead. Also a supported optional query filter (&mode=record / &mode=replay).
effective_modeyes (derived)Server-derived phase for the row: the stored mode when present, otherwise inferred from replay_id (absent ⇒ record, present ⇒ replay). The authoritative phase field — prefer it over inspecting replay_id yourself. Response-only; not a stored column.

Not in v1 query results: session_id / sp.session_id.


source values

ValueMeaningTypical service_name examples
agentJava agent self-diagnostics (instrumentation, export, internal agent logging)Application service name under instrumentation
appApplication-under-test logs captured by the agent (Logback, Log4j2, JUL)travel-ota, customer app id
backendsp-backend diagnostic logs exported through OpenTelemetrysp-backend

Filter or scan by source when you only want application lines versus agent diagnostics versus backend lines in the same trace lookup.

bash
jq '[.rows[].source] | group_by(.) | map({source: .[0], n: length})' /tmp/sp-logs.json
jq -r '.rows[] | select(.source=="backend") | .body' /tmp/sp-logs.json | head -20

Absent correlation fields

Correlation fields (trace_id, span_id, replay_id, plan_id, plan_item_id) are omitted or empty when the runtime genuinely had no request or replay context at emit time. This is expected — not a query defect.

Common cases:

SituationTypical absent fieldsWhy
Process startup or shutdownSome or all correlation fieldsNo active HTTP/RPC request or replay dispatch yet, or context already cleared
Background / housekeeping linestrace_id, span_id, replay/plan idsThread or timer work outside record/replay traffic
Agent or backend idle diagnosticsreplay_id, plan_id, plan_item_idDiagnostic line with trace context only, or no inbound W3C context
Plan context not set on a lineplan_id, plan_item_idLine emitted outside a plan item dispatch even during replay

When diagnosing a failed replay, query by the trace_id from the replay case or pytest correlation block. When you need replay-scoped lines, pass &replay_id= (or &mode=replay) on the query itself — the server filters for you.

Case-scoped diagnosis: anchor the record window to the case row's recordTime (the true recording time; older backends omit it — falling back to requestDateTime mis-anchors the window, because that field is the replay send time, not the recording time) and the replay window to replayTime. Use two ±2 minute windows (one per anchor) instead of one span from record to replay. Both windows should normally have rows: an empty record window means a bad anchor (requestDateTime fallback) or genuinely missing recording logs — investigate it rather than treating it as normal. See sp logs — Case-scoped lookup.


Per-component logging ownership

sourceWho controls severity and what gets emitted
agentAgent / JVM logging configuration (sp.log.path, sp.log.console, sp.enable.debug, etc.)
appApplication Logback, Log4j2, or JUL settings
backendsp-backend logging and OpenTelemetry log export configuration

Softprobe attaches correlation ids and forwards lines each logger already emits. It does not change application log levels or filter severities product-wide.


Example row (JSON)

From sp logs --json or GET /api/recorder/logs:

json
{
  "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",
  "plan_id": "6a3f2aad59f0c4655b0f99da",
  "plan_item_id": "6a3f2aad59f0c4655b0f99da:1",
  "mode": "replay",
  "effective_mode": "replay"
}

A startup line from the same service might omit correlation fields entirely:

json
{
  "timestamp": "2026-06-27T09:59:55.000Z",
  "severity": "INFO",
  "body": "Started SpBootApplication in 4.2 seconds",
  "service_name": "sp-backend",
  "source": "backend",
  "effective_mode": "record"
}

Note the caveat visible in this example: contextless platform lines (no stored mode, no replay_id) derive effective_mode: "record" even though they are not recording traffic. Treat effective_mode as authoritative only on lines that carry request/replay context; combine with source for platform diagnostics.


Out of scope (v1)

This reference covers unified pipeline query output only. Not part of v1 unless separately specified:

  • Record trace tables, metrics tables, replay read migration, historical backfill
  • Non-replay-path service logs (dashboard, auth, and other Helm/workspace services)
  • Direct Parquet file access, object-store credentials, or standalone query tools

Zero code changes · Full-context visibility · Cost optimization