Scope (this repo)
- In scope: VS Code extension client —
packages/apex-lsp-vscode-extensionand code that runs in the extension host and uses the services extension /enableFileTraces(seesrc/observability/extensionTracing.ts). - Out of scope for default guidance: Language server and parser packages (
packages/apex-parser-ast,packages/apex-ls, etc.) — do not treat file-span export as a requirement there unless product explicitly adds tracing. Server-side LSP work stays focused on protocol and semantics.
Local OTLP export to ~/.sf/vscode-spans/ for AI consumers. Spans and log records interleaved in one JSONL file. The actual exporter and record format come from the shared @salesforce/vscode-services SDK layer (SdkLayerFor(context)), which the extension obtains from the salesforce.salesforcedx-vscode-services extension.
Choose One: OTLP vs File
- OTLP (
enableLocalTraces): Grafana/Jaeger UI — for humans - File (
enableFileTraces):.jsonlon disk — for AI agents, Cursor
Use only one at a time.
Settings Required
These settings live in the shared salesforcedx-vscode-salesforcedx section provided by the services extension (not the apex section).
| Setting | Default | Purpose |
|---|---|---|
salesforcedx-vscode-salesforcedx.enableFileTraces |
false |
Enables file capture (spans + logs) |
salesforcedx-vscode-salesforcedx.logLevel |
error |
Minimum log level for exported records. Set to info or debug to see most logs. |
SF_LOG_LEVEL env var |
— | Fallback when VS Code setting unset (fatal maps to error) |
The extension registers an onDidChangeConfiguration listener (extensionTracing.ts) that tears down and rebuilds the tracing runtime when enableFileTraces, enableConsoleTraces, or enableLocalTraces change — so toggling these settings takes effect without a window reload. (Other SDK-layer behavior may still depend on activation; reload if a change does not take effect.)
Where It Lives
All records in one directory: ~/.sf/vscode-spans/
Filename pattern: {ISO-timestamp}.jsonl (e.g., 2026-05-22T15-33-01-398Z.jsonl)
Find latest: ls -lt ~/.sf/vscode-spans/ | head -1
Record Format
Each line is independent JSON. Discriminate on the "kind" field.
Spans (kind: "span")
{"kind":"span","traceId":"abc123","spanId":"def456","parentSpanId":"","name":"apex-language-server-extension.activate","spanKind":1,"startTimeUnixNano":"1779461510277547833","endTimeUnixNano":"1779461510278117291","attributes":{"componentCount":"5"},"events":[],"links":[],"status":{"code":1,"message":""},"resource":{"attributes":{"extension.name":"apex-language-server-extension","service.name":"apex-language-server-extension"}},"instrumentationScope":{"name":"apex-language-server-extension","version":"2026-03-02T01:00.304Z"}}
| Field | Notes |
|---|---|
parentSpanId: "" |
Root span (top of trace tree) |
status.code |
1=OK, 2=ERROR |
spanKind |
OTEL SpanKind enum +1 (1=INTERNAL, 2=SERVER, 3=CLIENT) |
resource.attributes["extension.name"] |
Which extension emitted it |
| Duration (ms) | (endTimeUnixNano - startTimeUnixNano) / 1_000_000 |
Logs (kind: "log")
{"kind":"log","timestamp":"1779463981397000000","severityText":"WARN","severityNumber":30000,"body":"UserIdNotFoundError: Could not determine user ID","traceId":"b4d710...","spanId":"706dfc...","attributes":{"fiberId":"#295"}}
| Field | Notes |
|---|---|
traceId + spanId |
Correlates to parent span active when log was emitted |
severityText |
INFO, WARN, ERROR (filtered by logLevel setting) |
body |
String or array (multiple log args) |
timestamp |
Nanoseconds since epoch |
Only log records at or above the configured logLevel are emitted.
Enable (Desktop)
Settings → search enableFileTraces → check, or set both in the shared salesforcedx-vscode-salesforcedx section:
{
"salesforcedx-vscode-salesforcedx.enableFileTraces": true,
"salesforcedx-vscode-salesforcedx.logLevel": "info"
}
Enable (Web / run:web)
Web POSTs to a local span file server when the workspace is set up for it (often via consumed salesforcedx-vscode-services and .esbuild-web-extra-settings.json). This repo does not define a spans:server script at the root, so do not assume one exists — check the workspace package.json and follow the salesforcedx-vscode-services team docs when wiring run:web + span server.
- Start the span server only if your wireit graph includes it (see team
salesforcedx-vscode-servicesdocs when applicable; the monorepo runs it on port 3003). - Add to
.esbuild-web-extra-settings.jsonat repo root (gitignored when local):{ "salesforcedx-vscode-salesforcedx.enableFileTraces": true } - Run the web target for the extension package you are testing.
Clear
rm ~/.sf/vscode-spans/* or rm -rf ~/.sf/vscode-spans/
Trace Correlation
Logs reference the span that was active when they were emitted via traceId + spanId. To reconstruct an operation:
- Find all spans with a given
traceId - Build the tree using
parentSpanId→ children - Find logs with the same
traceId— they belong to the span matching theirspanId