Repository navigation
feat(stack): persist service logs, ship them to Analytics, and add stack logs history - #6893
Conversation
|
/ai-review |
There was a problem hiding this comment.
Superseded by a newer AI review
🤖 AI Review
Reconciled all 7 Claude and 8 Codex findings into 13 deduplicated entries. Confirmed the code-level issues, including one major shutdown-bound failure. The concurrency and legacy-output findings are narrowed to account for owner lifecycle serialization and the CLI's existing line framing. Verification used surrounding source code, trusted conventions, and isolated UTF-8 and history-selection reproductions.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟠 MAJOR | packages/stack/src/host/LogStore.ts:758 |
shutdown |
codex | The five-second drain timeout does not bound shutdown because persistence batches, including filesystem writes and retention, are uninterruptible. |
| 🟡 MINOR | packages/stack/src/host/LogStore.ts:752 |
correctness |
claude+codex | Late partial lines from ended launches do not flush after two seconds of quiet unless another output batch arrives or the store closes. |
| 🟡 MINOR | packages/stack/src/host/LogStore.ts:860 |
concurrency |
claude | Concurrent calls to the store's remove and close operations can detach the same handle twice, leaving the second caller blocked forever. |
| 🟡 MINOR | packages/stack/src/Owner.ts:653 |
behavior-change |
claude | The legacy logs RPC now buffers unterminated output and normalizes carriage-return progress updates into newline-terminated records, changing raw RPC and package output. |
| 🟡 MINOR | packages/stack/src/host/LogStore.ts:725 |
error-handling |
claude+codex | Failed partial-line flushes can disappear without a lost marker, and previously committed lost markers can be duplicated when a later write in the same append fails. |
| 🟡 MINOR | packages/stack/src/host/LogStore.ts:893 |
performance |
claude | Sequential instance detachment allows shutdown drain time to accumulate across instances instead of sharing one shutdown budget. |
| 🟡 MINOR | packages/stack/src/host/LogStore.ts:425 |
correctness |
codex | The backward history scan can stop before records needed for the timestamp-ordered tail or since result. |
| 🟡 MINOR | packages/stack/src/host/LogStore.ts:351 |
correctness |
codex | Readers silently skip deleted interior generations when an older undeletable segment remains. |
| 🟡 MINOR | packages/stack/src/host/LogRecord.ts:284 |
correctness |
codex | A UTF-8 character split across three chunks loses its first-byte timestamp. |
| 🟡 MINOR | packages/stack/src/host/LogStore.ts:556 |
error-handling |
codex | Windows sharing-violation retries do not recognize segment-listing failures after they have been wrapped in LogStoreError. |
| 🟡 MINOR | packages/stack/src/host/LogStore.integration.test.ts:72 |
test-cleanup |
codex | Integration tests that ignore openStore's returned close operation leave the independently created store scope and its resource finalizers unclosed. |
| ⚪ NIT | packages/stack/src/host/LogStore.ts:522 |
documentation |
claude | The live-tail documentation incorrectly describes its PubSub as unbounded and the recipe buffer as the only place output can be dropped. |
| ⚪ NIT | packages/stack/src/effect.ts:1039 |
input-validation |
claude | The public readStackLogs API accepts invalid tail values without validating that they are non-negative integers. |
Stats
Claude findings: 7 · Codex findings: 8 · Confirmed: 13 · Refuted: 0 · Uncertain: 0
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
Supabase CLI previewnpx --yes https://pkg.pr.new/supabase/cli/supabase@39ba7ff49498cd4373767cc3d88eb099969e4597Preview package for commit |
a47d306 to
19bd0eb
Compare
Service output lived only in a per-recipe in-memory buffer, so the stack kept no log history, lost it when the owner exited, and native mode had nothing to replay. The owner now writes every instance's output to `logs/<service>/<instanceId>/<generation>.log` under the stack's state directory. Output chunks are tagged with their launch, process part, sequence and publish time at the source, so lines are split once, never glued across launches, and upstream loss is recorded as `lost`. Segments rotate at 5 MiB with byte and count retention, and are removed on instance and stack destroy. A single position-based reader serves history, follow and offline reads. It is exposed as a `readLogs` RPC and `readStackLogs`; the existing `logs` RPC keeps its live-only behaviour for `supabase stack logs`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Studio's Logs pages stayed empty because nothing forwarded the stack's service output to Analytics. The owner now ships persisted Auth, REST, Realtime, Storage, Functions and database lines to their Logflare sources, using the legacy Vector remaps ported to TypeScript. It posts to Analytics' own backend only while the composed Analytics instance is running and healthy, so shipping never wakes it or keeps it awake. Each instance keeps a cursor beside its log files: lines written while Analytics sleeps are shipped after it wakes with their original timestamps. Events carry deterministic ids and Logflare de-duplicates on them, so failed posts are retried without duplicates. Auth and target errors pause shipping and keep the cursor; malformed bodies are skipped. The CLI no longer composes Vector. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`supabase stack logs` now prints retained history and exits by default. `-f/--follow` hands over from history to live output per instance without gaps, `--tail` (default 200), `--since <duration|ISO|start>` and a repeatable `--service` select what is shown, and history is read from the log files when the stack is down. Output keeps the `log-entry` contract with `source: "history" | "live"` and adds `log-marker` events. The legacy live-only `logs` RPC is replaced by `readLogs`, which the Promise client exposes as an async iterable. The experimental stack no longer has a Vector service: saved stacks that contain one are migrated on owner start, and leftover Vector files and containers are removed. `analytics.vector_port` stays in the config schema because the legacy `supabase start` still reads it. PostgREST now logs every request, and request lines reach Analytics with their method, path, protocol and status. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The artifacts catalog is also the version table the legacy `supabase start` reads in slim mode, so dropping Vector's entry would silently fall back to the upstream Vector image there. Vector stays in the catalog as an artifact kind that only the legacy start runs; the experimental stack's service kinds, `supabase services` and stack prepare still exclude it. Docker-backed log tests get the same timeout guard as the package's other Docker tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
19bd0eb to
2ba2d89
Compare
- Abort log persistence 5 seconds into close, detaching instances under one deadline; aborted segments are retired and still release their handles. - Flush quiet late partial lines when their grace expires. - Count unwritten records as lost once, and clear lost markers only after they are written. - Read every segment for tails and report interior segment gaps with resumeAt. - Keep the first byte's time for UTF-8 characters split across chunks. - Retry wrapped sharing violations, claim removed instances atomically, and validate the readStackLogs tail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Flush a late partial line only after every chunk published before its grace deadline is processed, comparing publish times. - Report a lost marker when a reader finishes a segment and the next retained generation is not contiguous. - Treat stack logs --since as a value-consuming flag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hold the newline chunk behind a blocked write while the grace flusher wakes past its deadline, so the test fails if the flush skips queued output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/ai-review |
There was a problem hiding this comment.
Superseded by a newer AI review
🤖 AI Review
Both independent reviews were available. Verified all eight distinct findings: seven confirmed and one refuted. The major finding is a reproduced latest-launch filtering bug. Other confirmed findings concern migration contention, cleanup, follow diagnostics, redundant sweeps, and documentation. The reported global-flag scanning regression does not occur on the stack logs execution path.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟠 MAJOR | apps/cli/src/commands/experimental/stack/logs/logs.format.ts:116 |
correctness |
codex | --since start can discard the current launch's logs and retain an older launch when that older launch's first output arrives late. |
| 🟡 MINOR | packages/stack/src/State.ts:686 |
robustness |
claude | Migration acquires the global registry lock even when no Vector instances exist, introducing an unnecessary contention failure into owner startup and orphan reclamation. |
| 🟡 MINOR | packages/stack/src/State.ts:672 |
resource-cleanup |
codex | Vector migration leaves the stack-owned vector.rendered.yaml behind for instances that used a custom pipeline. |
| 🟡 MINOR | apps/cli/src/commands/experimental/stack/logs/logs.handler.ts:179 |
error-handling |
claude | --follow silently skips selected instances missing from the subsequently listed handles; if all are missing, the command completes successfully without explaining why following ended. |
| ⚪ NIT | packages/stack/src/host/LogForwarder.ts:375 |
error-handling |
claude | Destroying a shipped instance while Analytics is serving can produce a misleading 'Log shipping ... paused' warning during normal cleanup. |
| ⚪ NIT | packages/stack/src/Sweep.ts:50 |
code-quality |
claude | Session-stack orphan reclamation performs two container sweeps: one explicitly before migration and another through the namespace destroy path. |
| ⚪ NIT | apps/cli/src/command-internal/colors.ts:81 |
documentation |
codex | The new magenta and blue helpers describe bright colors but select normal ANSI colors. |
Refuted findings (kept for transparency, not posted as review comments)
apps/cli/src/command-internal/db-target-flags.ts:152(correctness): Adding boolean -f to stack logs causes the global explicit-false scanners to skip a following --experimental=false or --yes=false token.
Refuted: The cited helper has the described arity assumption, but it is not invoked on the stack logs execution path. The explicit-false scans run through resolveYes, resolveExperimental, and resolveDebugWithProjectEnv, which this command does not use. Stack registration instead uses resolveExperimentalFeature (stack-backend.ts:92-96), and telemetry correctly overrides f to follow (logs.command.ts:72; command-telemetry.ts:192-200). The claimed command-level regression therefore does not follow from this PR.
Stats
Claude findings: 5 · Codex findings: 3 · Confirmed: 7 · Refuted: 1 · Uncertain: 0
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
- Keep launch ids increasing per instance across owner restarts so stack logs --since start always selects the latest launch. - Migrate saved Vector stacks without taking the registry lock when there is nothing to migrate, and remove the rendered Vector config. - Fail stack logs --follow when the running stack serves none of the selected instances, and warn about skipped ones. - Detach an instance from log shipping, after its cursor write lands, before its logs are removed. - Remove readStackLogs, the end read option and unused platform options; reuse existing helpers and trim redundant tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… one An instance saved before launch ids were persisted resumes after the highest launch id at the end of its newest log segment, so its next launch never reuses an id its logs already hold. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/ai-review |
There was a problem hiding this comment.
Superseded by a newer AI review
🤖 AI Review
Both independent reviews were available. Verified all eight findings against the checked-out code and trusted conventions: one major and seven minor concerns are confirmed. No findings were duplicates. Corrected stale supporting line references and narrowed the sweep finding to migration-specific failures.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟠 MAJOR | packages/stack/src/host/LogForwarder.ts:384 |
error-handling |
codex | A transient log-read failure pauses forwarding indefinitely while the Analytics target remains unchanged. Subsequent records remain unshipped and can expire through retention. |
| 🟡 MINOR | packages/stack/src/host/LogflareEvents.ts:103 |
correctness |
claude | PostgREST messages containing an additional ': ' fail timestamp-prefix parsing because the fallback split is greedy. The shipped event retains the prefix and uses the owner's receive timestamp. |
| 🟡 MINOR | packages/stack/src/host/LogRecord.ts:250 |
correctness |
claude | stack logs --since start can show the previous launch's output after a silent restart or when the new launch marker was dropped during persistence backoff. |
| 🟡 MINOR | apps/cli/src/commands/experimental/stack/logs/logs.handler.ts:200 |
correctness |
codex | --since start --follow applies the launch bound only to history, allowing delayed output from an earlier launch to appear afterward as live output. |
| 🟡 MINOR | apps/cli/src/commands/experimental/stack/start/SIDE_EFFECTS.md:102 |
documentation |
claude | The documentation overstates recovery from API-key rejection: a composition change that leaves the same healthy Analytics instance selected does not resume shipping. |
| 🟡 MINOR | packages/stack/src/Sweep.ts:50 |
error-handling |
claude | Migration-specific failures now prevent the sweeper from reaching destruction of a dead session stack, leaving its remaining resources for a later sweep. |
| 🟡 MINOR | packages/stack/src/host/LogForwarder.ts:232 |
resource-cleanup |
claude | A process crash during a cursor write can leave .state-write-* temporary directories inside an attached instance's log directory, where subsequent owner starts do not reap them. |
| 🟡 MINOR | packages/stack/src/State.ts:711 |
resource-cleanup |
codex | Failed Vector file cleanup is not retried because migration saves the document without Vector instance IDs before deleting their owned files. |
Stats
Claude findings: 5 · Codex findings: 3 · Confirmed: 8 · Refuted: 0 · Uncertain: 0
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
…igration - Retry failed log reads from the saved cursor with capped backoff instead of pausing shipping until Analytics restarts. - Bound stack logs --since start, history and follow, by each instance's saved launch id. - Keep the PostgREST time when a message contains ": ". - Delete Vector files before committing the migration so a failure is retried, keep reclaiming a session stack when migration fails, and reap stale cursor-write directories. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s-files # Conflicts: # apps/cli/src/commands/experimental/stack/logs/logs.handler.ts # apps/cli/src/commands/functions/serve/serve.stack.handler.ts
…rsor Analytics acknowledges a post before its batched insert, and one already stored id makes that insert drop the whole batch. Shipping now records the pending ids before each post, checks which are stored in Analytics' tables, posts only the missing ones, resends after the flush window, and advances the cursor only once every id is stored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jgoux
left a comment
There was a problem hiding this comment.
Two P2 issues in the confirm-before-advance shipping added in the latest commit, plus two small P3 follow-ups. Details inline.
…very - Do not re-post events to the Analytics launch that may still have them queued (its ingest lag exceeds any fixed window); re-post after that launch ends, with a bounded per-event backstop that skips what can never be stored. - Replace NUL and unpaired surrogates that Analytics' jsonb rejects. - Derive Analytics' backend connection once for Analytics and the stored-id check, treat unknown stored state as an error, and drop a failed connection. - Keep a retired target's storage open while its sessions finish, trace the stored-id query, and remove logs before the state document on destroy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cs stores - Count any HTTP status and pre-send failure as a failed post that retries; only timeouts and post-send transport errors leave a body possibly queued. - Re-post a previous owner's possibly-queued events only after a grace that exceeds Analytics' shutdown. - Isolate unstored events by halves and skip one only after Analytics stored a later post on the same launch, so an Analytics that stores nothing keeps every event pending. - Start the backstop when shipping resumes, document the ignored database name, and keep pure helpers untraced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A body Analytics rejects is posted again in halves, like one it leaves unstored, so one refused line no longer drops the rest of its body. Warnings use singular counts and name only the reasons that apply, and functions serve reuses the stack logs marker formatting. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/ai-review |
There was a problem hiding this comment.
Superseded by a newer AI review
🤖 AI Review
Both independent reviews were available. Verified all seven distinct findings against the checked-out code and confirmed them, with qualifications on the standalone-log and CLI-scanner claims. In-memory reproductions demonstrated line/UTF-8 corruption, skipped argv tokens, and cleanup paths escaping the selected stack. No findings were duplicates.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟠 MAJOR | packages/stack/src/State.ts:668 |
data-safety |
codex | A malformed retired Vector instance ID can direct migration cleanup outside the selected stack and delete another stack's files. |
| 🟠 MAJOR | packages/stack/src/host/LogflareStorage.ts:65 |
runtime-config |
codex | The stored-event client discards TLS settings from Analytics' database URL, blocking log shipping when that PostgreSQL connection requires those settings. |
| 🟡 MINOR | packages/stack/src/host/LogForwarder.ts:883 |
correctness |
claude | Standalone database instances in a stack with composed Analytics are shipped to postgres.logs with the same db-default host as the primary database, conflating their logs in Studio. |
| 🟡 MINOR | packages/stack/src/host/LogflareStorage.ts:119 |
error-handling |
claude | A cached source table name survives query failures indefinitely, so replacing the source token/table during an Analytics launch can stall log shipping until the target changes. |
| 🟡 MINOR | packages/stack/src/host/LogStore.ts:959 |
log-framing |
codex | A lifecycle transition can flush partial line and decoder state before queued output chunks are split, corrupting persisted text, CRLF framing, and UTF-8. |
| 🟡 MINOR | packages/stack/src/State.ts:720 |
migration-recovery |
codex | Ordinary owner state writes erase the retired Vector IDs needed to retry cleanup after migration cleanup fails. |
| ⚪ NIT | apps/cli/src/commands/experimental/stack/logs/logs.command.ts:24 |
cli-parsing |
claude | The new boolean -f alias conflicts with the global argv scanner's value-consuming classification, causing that scanner to skip the following token. |
Stats
Claude findings: 3 · Codex findings: 4 · Confirmed: 7 · Refuted: 0 · Uncertain: 0
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
Develop's native port test now uses this branch's recipe signatures, the catalog error helper both sides stopped using is removed, and the stack log event and marker formatting moves to command-internal so functions serve no longer imports another command's internals. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The once-per-launch dropped-output warning now also covers lost markers written after a failed append recovers, and the rejected-body warning says the body is posted again in halves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Vector migration cleanup only follows safe instance ids and finds leftover Vector files by layout, so a failed cleanup is retried after later state writes and never leaves the stack. - The stored-event client connects with Analytics' database URL, keeping its TLS settings, and looks a source's table up again after a failed query. - Only composition members are shipped to Analytics, so standalone databases do not mix into Studio's database logs. - A launch's queued output is split before its partial line is flushed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/ai-review |
There was a problem hiding this comment.
Superseded by a newer AI review
🤖 AI Review
Both independent reviews were available. Verified all four findings against the checked-out code; none overlap. All are confirmed: one major forwarding bug and three minor startup/test-quality concerns. Reproduced the metadata stack overflow on Node 24. Full test suites were not run.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟠 MAJOR | packages/stack/src/host/LogflareEvents.ts:162 |
error-handling |
codex | A valid deeply nested JSON log line can permanently terminate that instance's Analytics forwarding fiber, preventing subsequent log delivery. |
| 🟡 MINOR | packages/stack/src/StackHost.ts:441 |
error-handling |
claude | Owner startup aborts when the legacy Vector migration fails, although the already-loaded state omits Vector and migration failure can be handled as a warning. |
| 🟡 MINOR | packages/stack/src/Owner.logs.integration.test.ts:171 |
test-reliability |
codex | The owner-restart tests can assert finite history before the restarted launch's log record has been persisted. |
| 🟡 MINOR | packages/stack/src/host/LogForwarder.integration.test.ts:413 |
test-quality |
codex | The failed-read recovery test waits through production retry backoff on a real clock instead of controlling retry time. |
Stats
Claude findings: 1 · Codex findings: 3 · Confirmed: 4 · Refuted: 0 · Uncertain: 0
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
- Vector cleanup only touches data directories of instances the stack no longer saves, and skips any whose real path leaves the stack; owner startup logs a failed migration and retries it on the next start. - Deeply nested JSON log lines ship with their raw message instead of stopping that instance's shipping. - A bound Analytics database drops host and TLS parameters meant for the runtime's address; Analytics' own URL keeps libpq's sslmode meaning. - Owner restart tests wait for the new launch, and the failed-read test uses the manual clock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/ai-review |
There was a problem hiding this comment.
🤖 AI Review
Both independent reviews were available. Verified all three findings against the checked-out code: two confirmed minor log-reader issues and one refuted CLI-flag report. No findings overlap. Read-only checks reproduced the filename mismatch and misplaced history gap marker.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟡 MINOR | packages/stack/src/host/LogStore.ts:376 |
correctness |
claude | Retention-gap markers use read-time timestamps, so history sorting can place the retention separator after the retained records instead of at the missing segment's position. |
| 🟡 MINOR | packages/stack/src/host/LogRecord.ts:110 |
correctness |
codex | A noncanonical numeric segment filename such as 1.log, without 0000000001.log, can make offline history reads loop indefinitely. |
Refuted findings (kept for transparency, not posted as review comments)
apps/cli/src/commands/experimental/stack/logs/logs.command.ts:25(cli-flags): The boolean -f alias conflicts with the shared value-consuming short-flag table, causing explicit global flags immediately after it to be silently ignored by stack logs.
Refuted: The helper-level alias conflict exists, but the claimed command behavior does not follow. The stack logs execution path does not call resolveYes, resolveExperimental, or resolveDebugWithProjectEnv, which contain these scanners. Its debug logger uses the parsed DebugFlag directly. Stack registration instead uses resolveExperimentalFeature in command-internal/stack-backend.ts:93–100, whose environment/config resolution is defined in experimental-feature.ts:89–101. Thus the cited scanners do not cause the reported global-flag regression on this command.
Stats
Claude findings: 2 · Codex findings: 1 · Confirmed: 2 · Refuted: 1 · Uncertain: 0
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
A retention gap carries the time of its first retained record, so time sorted history keeps it before that record, and only canonical segment file names count as generations, so a stray `1.log` cannot stall reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Output chunks are numbered per launch across stdout and stderr, and a number is taken and published in one step, so a chunk the shared buffer drops always leaves a gap. A gap is recorded as lost output, since the dropped chunk's stream is unknown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s-files-work # Conflicts: # apps/cli/src/commands/services/services.integration.test.ts
Not pushed yet; held while #6893 is the focus. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eway-logs Brings in the merged log persistence and shipping (#6893). The gateway stream relies on the shared publisher's per-launch ordering instead of its own semaphore. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
In the experimental stack, service output lived only in an in-memory buffer:
supabase stack logshad no history, nothing survived an owner exit, and Studio's Logs pages were always empty because nothing reached Analytics. This PR persists every service's output, ships it to Analytics, and givesstack logsa history-first interface.Persisted logs
lostrecord.<stateRoot>/<stackId>/logs/<service>/<instanceId>/<generation>.log, one record per line (<time> <kind> <launchId> | <text>). Segments are immutable once closed, rotate at 5 MiB, and are retained by bytes (10 MiB) and count (64). Lines over 32 KiB are cut and flaggedtruncated.Studio Logs: shipping to Analytics
cursor.jsonnext to the log files lets lines written while Analytics slept ship after it wakes, with their original timestamps. Retained history is shipped the first time an instance is seen.PGRST_LOG_LEVEL=info), and request lines reach Analytics with method, path, protocol and status.supabase stack logs-f/--followhands over to live output per instance from the last printed record, without gaps or duplicates.--tail N(default 200),--since <duration|ISO|start>, repeatable--service. History is streamed with bounded memory and read from the files when the stack is down;-ffails before any output when the stack is not running.stream-jsonkeeps thelog-entryenvelope withsource: "history" | "live"and record timestamps, and addslog-markerevents.--output-format jsonprints an array.logsRPC is replaced byreadLogs({ id, since?, tail?, follow?, from? }); the Promise client exposes it as an async iterable.streamStackLogsreads a stopped stack. Launch ids keep increasing per instance across owner restarts, so--since startalways means the latest launch.Vector removed from the experimental stack
supabase startstill runs Vector, so its artifact pin stays in the catalog (which legacy slim mode reads) under a separate artifact kind; stack service kinds,supabase servicesand stack prepare exclude it.analytics.vector_portstays in the config schema for the same reason; the experimental stack ignores it.Terminal captures
Recorded from this branch's source on macOS: terminal with vhs, Studio in headless Chrome, both running at the same time against the same stack. A copy of the
usebasejump/basejumpsample with Analytics enabled and a smallhellofunction generates the traffic. Before this change, Studio's Logs pages were empty andstack logsprinted live output only.supabase stack start(Docker, lazy): no Vector member.Docker:
stack logs -f(top) follows REST, Auth, Storage and Functions while requests run (bottom); lazy services wake on the first request, and Studio's PostgREST, Auth and Storage pages show the same lines.Docker, Analytics asleep: requests are written to the log files without waking Analytics; opening Studio wakes it, and the earlier lines arrive with their original timestamps.
Native runtime: the same flow.
stack logshistory:--tail,--since 10m,--since startandstream-json.Stopped stack (native): history is read from the files, and
-ffails before printing.Supersedes #6864.
🤖 Generated with Claude Code