Unified Dev Logs
Air Jam has one canonical local observability stream for development:
- server logs
- host runtime logs
- controller runtime logs
- embedded runtime diagnostics
- local dev-runner tool output such as Vite and other child-process failures
That stream exists so you do not have to debug each surface in isolation.
Canonical File
The canonical file is:
.airjam/logs/dev-latest.ndjsonThis file is:
- local-first
- append-only for the current server run
- reset when the Air Jam server process starts
That means it is the right place to inspect:
- room lifecycle
- host bootstrap and reconnect
- controller join and disconnect flow
- browser/runtime diagnostics that were mirrored back to the server
What Writes Into It
During normal Air Jam development:
- the Air Jam server writes structured server events into the file
- the SDK browser log sink mirrors host and controller browser/runtime logs into the same file
- the standard dev runners mirror local child-process output into the same file as
workspaceevents
If you use the standard Air Jam server and standard SDK session providers in development, this happens automatically.
No extra logging setup should be required for the normal path.
When It Resets
The file resets when the Air Jam server process starts.
That gives you a clean current-session stream by default.
One nuance matters:
If your dev workflow reuses an already-running local server process, the file will not reset until that server actually restarts.
Read It Two Ways
1. Preferred: CLI Querying
Use the published server CLI first.
Examples:
pnpm exec air-jam-server logs --view=signal
pnpm exec air-jam-server logs
pnpm exec air-jam-server logs --follow
pnpm exec air-jam-server logs --trace=host_abc123
pnpm exec air-jam-server logs --source=browser --level=warn
pnpm exec air-jam-server logs --view=signal --room=ROOM1
pnpm exec air-jam-server logs --source=workspace --process=platform --view=signalThe intended Air Jam workflow is:
- start with
pnpm exec air-jam-server logs --view=signal - narrow to the failing trace, room, controller, runtime, or process
- only add custom logging if the stream still does not explain the issue
2. Fallback: Read The File Directly
Direct file reads are also valid.
That is useful when:
- the repo does not yet expose the convenience CLI
- you are using your own tooling
- an LLM or script wants the raw NDJSON stream
Best Filters
The most useful filters are:
traceIdfor one host session storyroomIdfor one multiplayer roomcontrollerIdfor one player/controller patheventfor one lifecycle edgeruntimeKindandruntimeEpochfor embedded bridge/runtime issuesprocessNamevia--processfor one local dev process such asplatform,server, or the active game
In practice, the fastest loop is usually:
- reproduce the issue
- find the relevant
traceId,roomId, orcontrollerId - inspect the rest of the stream through that lens
Which Identifier To Reach For First
Use the narrowest identifier that matches the failure:
- use
traceIdwhen the problem is mainly one host session story: host bootstrap, reconnect, room ownership, launch flow - use
roomIdwhen multiple surfaces are involved in one room and you want the whole multiplayer story - use
controllerIdwhen one player path is failing: join, disconnect, input, action RPC, targeted controller feedback - use
runtimeKindandruntimeEpochwhen debugging embedded bridge/runtime activation problems - use
eventwhen you already know the lifecycle edge you are hunting
If you are unsure, start with roomId or traceId and then narrow further.
Signal View Vs Raw NDJSON
Use --view=signal when:
- you want the fastest first read of the session
- you care about lifecycle edges, accepted/rejected outcomes, and high-signal runtime events
- you want to suppress low-value framework/browser console noise
Read raw NDJSON or use broader CLI filters when:
- you need exact append order
- you need the full event payloads and metadata
- you suspect the hidden plumbing events are part of the problem
- you are doing deeper agent/script analysis over the stream
The practical rule is:
- start with
pnpm exec air-jam-server logs --view=signal - narrow with
--trace,--room,--controller,--runtime,--process, or--source - fall back to raw NDJSON only when the signal view is still insufficient
Recommended Debug Order
When something breaks:
- inspect the canonical dev log stream first
- use SDK diagnostics second
- add temporary custom logs only if the canonical stream still leaves a gap
Do not default to scattered console.log calls across host, controller, and server code.
Air Jam is specifically designed to avoid that debugging style.
Important Exceptions
The automatic unified stream depends on the standard development path.
You should not assume full automatic coverage when:
- running
--web-onlywithout a local Air Jam server - disabling the collector explicitly
- replacing the standard server/runtime path with custom infrastructure
- bypassing the standard dev runner and launching tools outside the Air Jam scripts